// -----------------------------------------------------------------------------------


//


//	Lightbox Slideshow v1.1


//	by Justin Barkhuff - http://www.justinbarkhuff.com/lab/lightbox_slideshow/


//  Updated: 2007-08-15


//


//	Largely based on Lightbox v2.02


//	by Lokesh Dhakar - http://huddletogether.com/projects/lightbox2/


//	3/31/06


//


//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/


//


//	The code inserts html at the bottom of the page that looks similar to this:


//


//	<div id="overlay"></div>


//	<div id="lightbox">


//		<div id="outerImageContainer">


//			<div id="imageContainer">


//				<img id="lightboxImage" />


//				<div id="hoverNav">


//					<a href="javascript:void(0);" id="prevLinkImg">&laquo; prev</a>


//					<a href="javascript:void(0);" id="nextLinkImg">next &raquo;</a>


//				</div>


//				<div id="loading">


//					<a href="javascript:void(0);" id="loadingLink">loading</a>


//				</div>


//			</div>


//		</div>


//		<div id="imageDataContainer">


//			<div id="imageData">


//				<div id="imageDetails">


//					<span id="caption"></span>


//					<span id="numberDisplay"></span>


//					<span id="detailsNav">


//						<a id="prevLinkDetails" href="javascript:void(0);">&laquo; prev</a>


//						<a id="nextLinkDetails" href="javascript:void(0);">next &raquo;</a>


//						<a id="slideShowControl" href="javascript:void(0);">stop slideshow</a>


//					</span>


//				</div>


//				<div id="close">


//					<a id="closeLink" href="javascript:void(0);">close</a>


//				</div>


//			</div>


//		</div>


//	</div>


//


// -----------------------------------------------------------------------------------





//


//	Lightbox Object


//





var Lightbox = {	


	activeImage : null,


	badObjects : ['select','object','embed'],


	container : null,


	enableSlideshow : null,


	groupName : null,


	imageArray : [],


	options : null,


	overlayDuration : null,


	overlayOpacity : null,


	playSlides : null,


	refTags : ['a','area'],


	relAttribute : null,


	resizeDuration : null,


	slideShowTimer : null,


	startImage : null,


	


	//


	// initialize()


	// Constructor sets class properties and configuration options and


	// inserts html at the bottom of the page which is used to display the shadow 


	// overlay and the image container.


	//


	initialize: function(options) {


		if (!document.getElementsByTagName){ return; }


		


		this.options = $H({


			animate : true, // resizing animations


			autoPlay : true, // should slideshow start automatically


			borderSize : 10, // if you adjust the padding in the CSS, you will need to update this variable


			containerID : document, // lightbox container object


			enableSlideshow : true, // enable slideshow feature


			googleAnalytics : false, // track individual image views using Google Analytics
			
			imgWidth : 200,
			
			imgHeigth : 200,


			imageDataLocation : 'south', // location of image caption information


			initImage : '', // ID of image link to automatically launch when upon script initialization


			loop : true, // whether to continuously loop slideshow images


			overlayDuration : .2, // time to fade in shadow overlay


			overlayOpacity : .8, // transparency of shadow overlay


			prefix : '', // ID prefix for all dynamically created html elements


			relAttribute : 'lightbox', // specifies the rel attribute value that triggers lightbox


			resizeSpeed : 7, // controls the speed of the image resizing (1=slowest and 10=fastest)


			showGroupName : false, // show group name of images in image details


			slideTime : 4, // time to display images during slideshow


			strings : { // allows for localization


				closeLink : 'close',


				loadingMsg : 'loading',


				nextLink : 'next &raquo;',


				prevLink : '&laquo; prev',


				startSlideshow : 'start slideshow',


				stopSlideshow : 'stop slideshow',


				numDisplayPrefix : 'Image',


				numDisplaySeparator : 'of'


			}


        }).merge(options);


		


		if(this.options.animate){


			this.overlayDuration = Math.max(this.options.overlayDuration,0);


			this.options.resizeSpeed = Math.max(Math.min(this.options.resizeSpeed,10),1);


			this.resizeDuration = (11 - this.options.resizeSpeed) * 0.15;


		}else{


			this.overlayDuration = 0;


			this.resizeDuration = 0;


		}


		


		this.enableSlideshow = this.options.enableSlideshow;


		this.overlayOpacity = Math.max(Math.min(this.options.overlayOpacity,1),0);


		this.playSlides = this.options.autoPlay;


		this.container = $(this.options.containerID);


		this.relAttribute = this.options.relAttribute;


		this.updateImageList();


		


		var objBody = this.container != document ? this.container : document.getElementsByTagName('body').item(0);


		


		var objOverlay = document.createElement('div');


		objOverlay.setAttribute('id',this.getID('overlay'));


		objOverlay.style.display = 'none';


		objBody.appendChild(objOverlay);


		Event.observe(objOverlay,'click',this.end.bindAsEventListener(this));


		


		var objLightbox = document.createElement('div');


		objLightbox.setAttribute('id',this.getID('lightbox'));


		objLightbox.style.display = 'none';


		objBody.appendChild(objLightbox);


		


		var objImageDataContainer = document.createElement('div');


		objImageDataContainer.setAttribute('id',this.getID('imageDataContainer'));


		objImageDataContainer.className = this.getID('clearfix');





		var objImageData = document.createElement('div');


		objImageData.setAttribute('id',this.getID('imageData'));


		objImageDataContainer.appendChild(objImageData);


	


		var objImageDetails = document.createElement('div');


		objImageDetails.setAttribute('id',this.getID('imageDetails'));


		objImageData.appendChild(objImageDetails);


	


		var objCaption = document.createElement('span');


		objCaption.setAttribute('id',this.getID('caption'));


		objImageDetails.appendChild(objCaption);


	


		var objNumberDisplay = document.createElement('span');


		objNumberDisplay.setAttribute('id',this.getID('numberDisplay'));


		objImageDetails.appendChild(objNumberDisplay);





		var objDetailsNav = document.createElement('span');


		objDetailsNav.setAttribute('id',this.getID('detailsNav'));


		objImageDetails.appendChild(objDetailsNav);





		var objPrevLink = document.createElement('a');


		objPrevLink.setAttribute('id',this.getID('prevLinkDetails'));


		objPrevLink.setAttribute('href','javascript:void(0);');


		objPrevLink.innerHTML = this.options.strings.prevLink;


		objDetailsNav.appendChild(objPrevLink);


		Event.observe(objPrevLink,'click',this.showPrev.bindAsEventListener(this));


		


		var objNextLink = document.createElement('a');


		objNextLink.setAttribute('id',this.getID('nextLinkDetails'));


		objNextLink.setAttribute('href','javascript:void(0);');


		objNextLink.innerHTML = this.options.strings.nextLink;


		objDetailsNav.appendChild(objNextLink);


		Event.observe(objNextLink,'click',this.showNext.bindAsEventListener(this));





		var objSlideShowControl = document.createElement('a');


		objSlideShowControl.setAttribute('id',this.getID('slideShowControl'));


		objSlideShowControl.setAttribute('href','javascript:void(0);');


		objDetailsNav.appendChild(objSlideShowControl);


		Event.observe(objSlideShowControl,'click',this.toggleSlideShow.bindAsEventListener(this));





		var objClose = document.createElement('div');


		objClose.setAttribute('id',this.getID('close'));


		objImageData.appendChild(objClose);


	


		var objCloseLink = document.createElement('a');


		objCloseLink.setAttribute('id',this.getID('closeLink'));


		objCloseLink.setAttribute('href','javascript:void(0);');


		objCloseLink.innerHTML = this.options.strings.closeLink;


		objClose.appendChild(objCloseLink);	


		Event.observe(objCloseLink,'click',this.end.bindAsEventListener(this));





		if(this.options.imageDataLocation == 'north'){


			objLightbox.appendChild(objImageDataContainer);


		}


	


		var objOuterImageContainer = document.createElement('div');


		objOuterImageContainer.setAttribute('id',this.getID('outerImageContainer'));


		objLightbox.appendChild(objOuterImageContainer);





		var objImageContainer = document.createElement('div');


		objImageContainer.setAttribute('id',this.getID('imageContainer'));


		objOuterImageContainer.appendChild(objImageContainer);


	


		var objLightboxImage = document.createElement('img');


		objLightboxImage.setAttribute('id',this.getID('lightboxImage'));


		objImageContainer.appendChild(objLightboxImage);


	


		var objHoverNav = document.createElement('div');


		objHoverNav.setAttribute('id',this.getID('hoverNav'));


		objImageContainer.appendChild(objHoverNav);


	


		var objPrevLinkImg = document.createElement('a');


		objPrevLinkImg.setAttribute('id',this.getID('prevLinkImg'));


		objPrevLinkImg.setAttribute('href','javascript:void(0);');


		objHoverNav.appendChild(objPrevLinkImg);


		Event.observe(objPrevLinkImg,'click',this.showPrev.bindAsEventListener(this));


		


		var objNextLinkImg = document.createElement('a');


		objNextLinkImg.setAttribute('id',this.getID('nextLinkImg'));


		objNextLinkImg.setAttribute('href','javascript:void(0);');


		objHoverNav.appendChild(objNextLinkImg);


		Event.observe(objNextLinkImg,'click',this.showNext.bindAsEventListener(this));


	


		var objLoading = document.createElement('div');


		objLoading.setAttribute('id',this.getID('loading'));


		objImageContainer.appendChild(objLoading);


	


		var objLoadingLink = document.createElement('a');


		objLoadingLink.setAttribute('id',this.getID('loadingLink'));


		objLoadingLink.setAttribute('href','javascript:void(0);');


		objLoadingLink.innerHTML = this.options.strings.loadingMsg;


		objLoading.appendChild(objLoadingLink);


		Event.observe(objLoadingLink,'click',this.end.bindAsEventListener(this));


		


		if(this.options.imageDataLocation != 'north'){


			objLightbox.appendChild(objImageDataContainer);


		}


		


		if(this.options.initImage != ''){


			this.start($(this.options.initImage));


		}


	},


	


	//


	//	updateImageList()


	//	Loops through specific tags within 'container' looking for 


	// 'lightbox' references and applies onclick events to them.


	//


	updateImageList: function(){


		var el, els, rel;


		for(var i=0; i < this.refTags.length; i++){


			els = this.container.getElementsByTagName(this.refTags[i]);


			for(var j=0; j < els.length; j++){


				el = els[j];


				rel = String(el.getAttribute('rel'));


				if (el.getAttribute('href') && (rel.toLowerCase().match(this.relAttribute))){


					el.onclick = function(){Lightbox.start(this); return false;}


				}


			}


		}


	},


		


	//


	//	start()


	//	Display overlay and lightbox. If image is part of a set, add siblings to imageArray.


	//


	start: function(imageLink) {	





		this.hideBadObjects();





		// stretch overlay to fill page and fade in


		var pageSize = this.getPageSize();


		$(this.getID('overlay')).setStyle({height:pageSize.pageHeight+'px'});


		new Effect.Appear(this.getID('overlay'), { duration: this.overlayDuration, from: 0, to: this.overlayOpacity });





		this.imageArray = [];


		this.groupName = null;


		


		var rel = imageLink.getAttribute('rel');


		var imageTitle = '';


		


		// if image is NOT part of a group..


		if(rel == this.relAttribute){


			// add single image to imageArray


			imageTitle = imageLink.getAttribute('title') ? imageLink.getAttribute('title') : '';


			this.imageArray.push({'link':imageLink.getAttribute('href'), 'title':imageTitle});			


			this.startImage = 0;


		} else {


			// if image is part of a group..


			var els = this.container.getElementsByTagName(imageLink.tagName);


			// loop through anchors, find other images in group, and add them to imageArray


			for (var i=0; i<els.length; i++){


				var el = els[i];


				if (el.getAttribute('href') && (el.getAttribute('rel') == rel)){


					imageTitle = el.getAttribute('title') ? el.getAttribute('title') : '';


					this.imageArray.push({'link':el.getAttribute('href'),'title':imageTitle});


					if(el == imageLink){


						this.startImage = this.imageArray.length-1;


					}


				}


			}


			// get group name


			this.groupName = rel.substring(this.relAttribute.length+1,rel.length-1);


		}





		// calculate top offset for the lightbox and display 


		var pageScroll = this.getPageScroll();


		var lightboxTop = pageScroll.y + (pageSize.winHeight / 15);





		$(this.getID('lightbox')).setStyle({top:lightboxTop+'px'}).show();


		this.changeImage(this.startImage);


	},





	//


	//	changeImage()


	//	Hide most elements and preload image in preparation for resizing image container.


	//


	changeImage: function(imageNum){	


		this.activeImage = imageNum;





		this.disableKeyboardNav();


		this.pauseSlideShow();





		// hide elements during transition


		$(this.getID('loading')).show();


		$(this.getID('lightboxImage')).hide();


		$(this.getID('hoverNav')).hide();


		$(this.getID('imageDataContainer')).hide();


		$(this.getID('numberDisplay')).hide();


		$(this.getID('detailsNav')).hide();


		


		var imgPreloader = new Image();


		


		// once image is preloaded, resize image container


		imgPreloader.onload=function(){


			$(Lightbox.getID('lightboxImage')).src = imgPreloader.src;


			Lightbox.resizeImageContainer(imgPreloader.width,imgPreloader.height);


		}


		imgPreloader.src = this.imageArray[this.activeImage].link;


		


		if(this.options.googleAnalytics){


			urchinTracker(this.imageArray[this.activeImage].link);


		}


	},





	//


	//	resizeImageContainer()


	//


	resizeImageContainer: function(imgWidth,imgHeight) {


		// get current height and width


		var cDims = $(this.getID('outerImageContainer')).getDimensions();





		// scalars based on change from old to new


		var xScale = ((imgWidth  + (this.options.borderSize * 2)) / cDims.width) * 100;


		var yScale = ((imgHeight  + (this.options.borderSize * 2)) / cDims.height) * 100;





		// calculate size difference between new and old image, and resize if necessary


		var wDiff = (cDims.width - this.options.borderSize * 2) - imgWidth;


		var hDiff = (cDims.height - this.options.borderSize * 2) - imgHeight;





		if(!( hDiff == 0)){ new Effect.Scale(this.getID('outerImageContainer'), yScale, {scaleX: false, duration: this.resizeDuration, queue: 'front'}); }


		if(!( wDiff == 0)){ new Effect.Scale(this.getID('outerImageContainer'), xScale, {scaleY: false, delay: this.resizeDuration, duration: this.resizeDuration}); }





		// if new and old image are same size and no scaling transition is necessary, 


		// do a quick pause to prevent image flicker.


		if((hDiff == 0) && (wDiff == 0)){


			if(navigator.appVersion.indexOf('MSIE')!=-1){ this.pause(250); } else { this.pause(100);} 


		}





		$(this.getID('prevLinkImg')).setStyle({height:imgHeight+'px'});


		$(this.getID('nextLinkImg')).setStyle({height:imgHeight+'px'});


		$(this.getID('imageDataContainer')).setStyle({width:(imgWidth+(this.options.borderSize * 2))+'px'});





		this.showImage();


	},


	


	//


	//	showImage()


	//	Display image and begin preloading neighbors.


	//


	showImage: function(){


		$(this.getID('loading')).hide();


		new Effect.Appear(this.getID('lightboxImage'), { duration: 0.5, queue: 'end', afterFinish: function(){	Lightbox.updateDetails(); } });


		this.preloadNeighborImages();


	},





	//


	//	updateDetails()


	//	Display caption, image number, and bottom nav.


	//


	updateDetails: function() {


		$(this.getID('caption')).show();


		$(this.getID('caption')).update(this.imageArray[this.activeImage].title);


		


		// if image is part of set display 'Image x of y' 


		if(this.imageArray.length > 1){


			var num_display = this.options.strings.numDisplayPrefix + ' ' + eval(this.activeImage + 1) + ' ' + this.options.strings.numDisplaySeparator + ' ' + this.imageArray.length;


			if(this.options.showGroupName && this.groupName != ''){


				num_display += ' '+this.options.strings.numDisplaySeparator+' '+this.groupName;


			}


			$(this.getID('numberDisplay')).update(num_display).show();


			if(!this.enableSlideshow){


				$(this.getID('slideShowControl')).hide();


			}


			$(this.getID('detailsNav')).show();


		}


		


		new Effect.Parallel(


			[ new Effect.SlideDown( this.getID('imageDataContainer'), { sync: true }), 


			  new Effect.Appear(this.getID('imageDataContainer'), { sync: true }) ], 


			{ duration:.65, afterFinish: function() { Lightbox.updateNav();} } 


		);


	},


	


	//


	//	updateNav()


	//	Display appropriate previous and next hover navigation.


	//


	updateNav: function() {


		if(this.imageArray.length > 1){


			$(this.getID('hoverNav')).show();


			if(this.enableSlideshow){


				if(this.playSlides){


					this.startSlideShow();


				} else {


					this.stopSlideShow();


				}


			}


		}


		this.enableKeyboardNav();


	},


	//


	//	startSlideShow()


	//	Starts the slide show


	//


	startSlideShow: function(){


		this.playSlides = true;


		this.slideShowTimer = new PeriodicalExecuter(function(pe){ Lightbox.showNext(); pe.stop(); },this.options.slideTime);


		$(this.getID('slideShowControl')).update(this.options.strings.stopSlideshow);


	},


	


	//


	//	stopSlideShow()


	//	Stops the slide show


	//


	stopSlideShow: function(){


		this.playSlides = false;


		if(this.slideShowTimer){


			this.slideShowTimer.stop();


		}


		$(this.getID('slideShowControl')).update(this.options.strings.startSlideshow);


	},





	//


	//	stopSlideShow()


	//	Stops the slide show


	//


	toggleSlideShow: function(){


		if(this.playSlides){


			this.stopSlideShow();


		}else{


			this.startSlideShow();


		}


	},





	//


	//	pauseSlideShow()


	//	Pauses the slide show (doesn't change the value of this.playSlides)


	//


	pauseSlideShow: function(){


		if(this.slideShowTimer){


			this.slideShowTimer.stop();


		}


	},


	


	//


	//	showNext()


	//	Display the next image in a group


	//


	showNext : function(){


		if(this.imageArray.length > 1){


			if(!this.options.loop && ((this.activeImage == this.imageArray.length - 1 && this.startImage == 0) || (this.activeImage+1 == this.startImage))){


				return this.end();


			}


			if(this.activeImage == this.imageArray.length - 1){


				this.changeImage(0);


			}else{


				this.changeImage(this.activeImage+1);


			}


		}


	},





	//


	//	showPrev()


	//	Display the next image in a group


	//


	showPrev : function(){


		if(this.imageArray.length > 1){


			if(this.activeImage == 0){


				this.changeImage(this.imageArray.length - 1);


			}else{


				this.changeImage(this.activeImage-1);


			}


		}


	},


	


	//


	//	showFirst()


	//	Display the first image in a group


	//


	showFirst : function(){


		if(this.imageArray.length > 1){


			this.changeImage(0);


		}


	},





	//


	//	showFirst()


	//	Display the first image in a group


	//


	showLast : function(){


		if(this.imageArray.length > 1){


			this.changeImage(this.imageArray.length - 1);


		}


	},





	//


	//	enableKeyboardNav()


	//


	enableKeyboardNav: function() {


		document.onkeydown = this.keyboardAction; 


	},





	//


	//	disableKeyboardNav()


	//


	disableKeyboardNav: function() {


		document.onkeydown = '';


	},





	//


	//	keyboardAction()


	//


	keyboardAction: function(e) {


		if (e == null) { // ie


			keycode = event.keyCode;


		} else { // mozilla


			keycode = e.which;


		}





		key = String.fromCharCode(keycode).toLowerCase();


		


		if(key == 'x' || key == 'o' || key == 'c'){ // close lightbox


		//	Lightbox.end();


		} else if(key == 'p' || key == '%'){ // display previous image


			Lightbox.showPrev();


		} else if(key == 'n' || key =='\''){ // display next image


			Lightbox.showNext();


		} else if(key == 'f'){ // display first image


			Lightbox.showFirst();


		} else if(key == 'l'){ // display last image


			Lightbox.showLast();


		} else if(key == 's'){ // toggle slideshow


			if(Lightbox.imageArray.length > 0 && Lightbox.options.enableSlideshow){


				Lightbox.toggleSlideShow();


			}


		}


	},





	//


	//	preloadNeighborImages()


	//	Preload previous and next images.


	//


	preloadNeighborImages: function(){


		var nextImageID = this.imageArray.length - 1 == this.activeImage ? 0 : this.activeImage + 1;


		nextImage = new Image();


		nextImage.src = this.imageArray[nextImageID].link





		var prevImageID = this.activeImage == 0 ? this.imageArray.length - 1 : this.activeImage - 1;


		prevImage = new Image();


		prevImage.src = this.imageArray[prevImageID].link;


	},





	//


	//	end()


	//


	end: function() {


		this.disableKeyboardNav();


		this.pauseSlideShow();


		$(this.getID('lightbox')).hide();


		new Effect.Fade(this.getID('overlay'), { duration:this.overlayDuration });


		this.showBadObjects();


	},


	


	//


	//	showBadObjects()


	//


	showBadObjects: function (){


		var els;


		var tags = Lightbox.badObjects;


		for(var i=0; i<tags.length; i++){


			els = document.getElementsByTagName(tags[i]);


			for(var j=0; j<els.length; j++){


				$(els[j]).setStyle({visibility:'visible'});


			}


		}


	},


	


	//


	//	hideBadObjects()


	//


	hideBadObjects: function (){


		var els;


		var tags = Lightbox.badObjects;


		for(var i=0; i<tags.length; i++){


			els = document.getElementsByTagName(tags[i]);


			for(var j=0; j<els.length; j++){


				$(els[j]).setStyle({visibility:'hidden'});


			}


		}


	},


		


	//


	// pause(numberMillis)


	// Pauses code execution for specified time. Uses busy code, not good.


	// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602


	//


	pause: function(numberMillis) {


		var now = new Date();


		var exitTime = now.getTime() + numberMillis;


		while(true){


			now = new Date();


			if (now.getTime() > exitTime)


				return;


		}


	},





	//


	// getPageScroll()


	// Returns array with x,y page scroll values.


	// Core code from - quirksmode.org


	//


	getPageScroll: function(){


		var x,y;


		if (self.pageYOffset) {


			x = self.pageXOffset;


			y = self.pageYOffset;


		} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict


			x = document.documentElement.scrollLeft;


			y = document.documentElement.scrollTop;


		} else if (document.body) {// all other Explorers


			x = document.body.scrollLeft;


			y = document.body.scrollTop;


		}


		return {x:x,y:y};


	},





	//


	// getPageSize()


	// Returns array with page width, height and window width, height


	// Core code from - quirksmode.org


	// Edit for Firefox by pHaez


	//


	getPageSize: function(){


		var scrollX,scrollY,windowX,windowY,pageX,pageY;


		if (window.innerHeight && window.scrollMaxY) {	


			scrollX = document.body.scrollWidth;


			scrollY = window.innerHeight + window.scrollMaxY;


		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac


			scrollX = document.body.scrollWidth;


			scrollY = document.body.scrollHeight;


		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari


			scrollX = document.body.offsetWidth;


			scrollY = document.body.offsetHeight;


		}


		


		if (self.innerHeight) {	// all except Explorer


			windowX = self.innerWidth;


			windowY = self.innerHeight;


		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode


			windowX = document.documentElement.clientWidth;


			windowY = document.documentElement.clientHeight;


		} else if (document.body) { // other Explorers


			windowX = document.body.clientWidth;


			windowY = document.body.clientHeight;


		}	


		


		pageY = (scrollY < windowY) ? windowY : scrollY; // for small pages with total height less then height of the viewport


		pageX = (scrollX < windowX) ? windowX : scrollX; // for small pages with total width less then width of the viewport


	


		return {pageWidth:pageX,pageHeight:pageY,winWidth:windowX,winHeight:windowY};


	},





	//


	// getID()


	// Returns formatted Lightbox element ID


	//


	getID: function(id){


		return this.options.prefix+id;


	}


}





// -----------------------------------------------------------------------------------





Event.observe(window,'load',function(){ Lightbox.initialize(); });
