// -----------------------------------------------------------------------------------
//
//    VisualLightBox for Prototype v 1.9.16p
//    http://visuallightbox.com/
//    VisualLightBox is a free wizard program that helps you easily generate LightBox photo
//    galleries, in a few clicks without writing a single line of code. For Windows and Mac!
//    Last updated: 16:38 30.08.2010
//
//
//	The code inserts html at the bottom of the page that looks similar to this:
//
//	<div id="overlay"></div>
//	<div id="lightbox">
//		<table id="outerImageContainer">
//			<tr><td class="tl"></td><td class="tc"></td><td class="tr"></td></tr>
//			<tr><td class="ml"></td>
//			<td id="lightboxFrameBody">
//				<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 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);"></a>
//								<a id="slideShowControl" href="javascript:void(0);"></a>
//								<a id="nextLinkDetails" href="javascript:void(0);"></a>
//							</span>
//						</div>
//						<div id="close">
//							<a id="closeLink" href="javascript:void(0);">close</a>
//						</div>
//					</div>
//				</div>
//			</td>
//			<td class="mr"></td></tr>
//			<tr><td class="bl"></td><td class="bc"></td><td class="br"></td></tr>
//		</table>
//	</div>
//
// -----------------------------------------------------------------------------------

//
//	Lightbox Object
//

function VisualLightbox(options){
		var activeImage = null,
			badObjects = ['select','object','embed'],
			groupName = null,
			imageArray = [],
			slideShowTimer = null,
			startImage = null,
			descriptionHeight= 50,
			imgPreloader,
			resizeEffects,
			showTimer;
		
		//
		// 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.
		//
		if (!document.getElementsByTagName){ return; }
		
		options = $H({
			animate : true, // resizing animations
			autoPlay : true, // should slideshow start automatically
			borderSize : 39, // 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
			descSliding: true, // sliding description panel
			imageDataLocation : 'south', // location of image caption information
			closeLocation : '', // location of close button: default in imageData object
			initImage : '', // ID of image link to automatically launch when upon script initialization
			loop : true, // whether to continuously loop slideshow images
			overlayDuration : 0.2, // time to fade in shadow overlay
			overlayOpacity : .7, // transparency of shadow overlay
			prefix : '', // ID prefix for all dynamically created html elements
			classNames : 'vlightbox', // 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 : '',
				loadingMsg : 'loading',
				nextLink : '',
				prevLink : '',
				startSlideshow : '',
				stopSlideshow : '',
				numDisplayPrefix : '',
				numDisplaySeparator : '/'
			},
			enableRightClick: false,// disable right click on images
			featBrowser: true,     // set it to true or false to choose to auto-adjust the maximum size to the browser
			breathingSize: 20,     // control the minimum space around the image box
			startZoom: false,      // do zoom from clicked image while starting
			floating: true         // create floating menu
		}).merge(options);
		
		if(options.animate){
			var overlayDuration = Math.max(options.overlayDuration,0);
			options.resizeSpeed = Math.max(Math.min(options.resizeSpeed,10),1);
			var resizeDuration = (11 - options.resizeSpeed) * 0.15;
		}else{
			var overlayDuration = 0;
			var resizeDuration = 0;
		}
		
		var enableSlideshow = options.enableSlideshow;
		options.overlayOpacity = Math.max(Math.min(options.overlayOpacity,1),0);
		var playSlides = options.autoPlay;
		var container = $(options.containerID);
		var classNames = options.classNames;
		updateImageList();
		
		var objBody = container != document ? container : document.getElementsByTagName('body').item(0);
		
		// create additional contaner in begin of document for because
		new Insertion.Top($(objBody), '<div></div>');
		objBody = objBody.childNodes[0];
		
		function connectEvent(obj,name,func){
			Event.observe(obj,name,func.bindAsEventListener(this));
		};
		
		// create structure
		//------------------
		var objOverlay = document.createElement('div');
		objOverlay.setAttribute('id',getID('overlay'));
		objOverlay.style.display = 'none';
		objBody.appendChild(objOverlay);
		connectEvent(objOverlay,'click',end)
		
		var objLightbox = document.createElement('div');
		objLightbox.setAttribute('id',getID('lightbox'));
		objLightbox.style.display = 'none';
		objBody.appendChild(objLightbox);
		connectEvent(objLightbox,'click',end)
		
		var objImageDataContainer = document.createElement('div');
		objImageDataContainer.setAttribute('id',getID('imageDataContainer'));
		objImageDataContainer.className = getID('clearfix');

		var objOuterImageContainer = document.createElement('table');
		objOuterImageContainer.setAttribute('id',getID('outerImageContainer'));
		objOuterImageContainer.cellSpacing = 0;
		objLightbox.appendChild(objOuterImageContainer);
		
		// create content cells
		var objOICTop = objOuterImageContainer.insertRow(-1);
		var objOICTL =  objOICTop.insertCell(-1);
		objOICTL.className = 'tl';
		var objOICTC =  objOICTop.insertCell(-1);
		objOICTC.className = 'tc';
		var objOICTR =  objOICTop.insertCell(-1);
		objOICTR.className = 'tr';
		var objOICMiddle = objOuterImageContainer.insertRow(-1);
		var objOICML =  objOICMiddle.insertCell(-1);
		objOICML.className = 'ml';
		
		// middle center 
		var objLightboxFrameBody =  objOICMiddle.insertCell(-1);
		objLightboxFrameBody.setAttribute('id',getID('lightboxFrameBody'));
		objLightboxFrameBody.innerHTML= String.fromCharCode(160) //+ '&nbsp;';?
		
		var objOICMR =  objOICMiddle.insertCell(-1);
		objOICMR.className = 'mr';
		var objOICBottom = objOuterImageContainer.insertRow(-1);
		var objOICBL =  objOICBottom.insertCell(-1);
		objOICBL.className = 'bl';
		var objOICBC =  objOICBottom.insertCell(-1);
		objOICBC.className = 'bc';
		var objOICBR =  objOICBottom.insertCell(-1);
		objOICBR.className = 'br';
		

		if(options.imageDataLocation == 'north'){
			objLightboxFrameBody.appendChild(objImageDataContainer);
		}
		
		var objImageData = document.createElement('div');
		objImageData.setAttribute('id',getID('imageData'));
		objImageDataContainer.appendChild(objImageData);
	
		var objImageDetails = document.createElement('div');
		objImageDetails.setAttribute('id',getID('imageDetails'));
		objImageData.appendChild(objImageDetails);
	
		var objCaption = document.createElement('div');
		objCaption.setAttribute('id',getID('caption'));
		objImageDetails.appendChild(objCaption);
	
		var objNumberDisplay = document.createElement('span');
		objNumberDisplay.setAttribute('id',getID('numberDisplay'));
		objImageDetails.appendChild(objNumberDisplay);

		var objDetailsNav = document.createElement('span');
		objDetailsNav.setAttribute('id',getID('detailsNav'));
		objImageDetails.appendChild(objDetailsNav);

		var objPrevLink = document.createElement('a');
		objPrevLink.setAttribute('id',getID('prevLinkDetails'));
		objPrevLink.setAttribute('href','javascript:void(0);');
		objPrevLink.innerHTML = options.strings.prevLink;
		objDetailsNav.appendChild(objPrevLink);
		connectEvent(objPrevLink,'click',showPrev);
		

		var objSlideShowControl = document.createElement('a');
		objSlideShowControl.setAttribute('id',getID('slideShowControl'));
		objSlideShowControl.setAttribute('href','javascript:void(0);');
		objDetailsNav.appendChild(objSlideShowControl);
		connectEvent(objSlideShowControl,'click',toggleSlideShow);


		var objCloseLink = document.createElement('a');
		objCloseLink.setAttribute('id',getID('closeLink'));
		objCloseLink.setAttribute('href','javascript:void(0);');
		objCloseLink.innerHTML = options.strings.closeLink;
		if (options.closeLocation == 'nav')
			objDetailsNav.appendChild(objCloseLink)
		else{
			var objClose = document.createElement('div');
			objClose.setAttribute('id',getID('close'));
			if (options.closeLocation=='top')
				objOICTR.appendChild(objClose)
			else
				objImageData.appendChild(objClose);
			objClose.appendChild(objCloseLink);
		}
		connectEvent(objCloseLink,'click',end);
		
		
		var objNextLink = document.createElement('a');
		objNextLink.setAttribute('id',getID('nextLinkDetails'));
		objNextLink.setAttribute('href','javascript:void(0);');
		objNextLink.innerHTML = options.strings.nextLink;
		objDetailsNav.appendChild(objNextLink);
		connectEvent(objNextLink,'click',showNext);
		
		var objImageContainer = document.createElement('div');
		objImageContainer.setAttribute('id',getID('imageContainer'));
		objLightboxFrameBody.appendChild(objImageContainer);
	
		var objLightboxImage = document.createElement('img');
		objLightboxImage.setAttribute('id',getID('lightboxImage'));
		objImageContainer.appendChild(objLightboxImage);
		
		if (!options.enableRightClick){
			var objHoverNav = document.createElement('div');
			objHoverNav.setAttribute('id',getID('hoverNav'));
			objHoverNav.style.background="white";
			objHoverNav.style.opacity = 0;
			objHoverNav.style.filter = "alpha(opacity=0)";
			objImageContainer.appendChild(objHoverNav);
			connectEvent(objHoverNav,'mousemove',hoverNav);
			connectEvent(objHoverNav,'mouseout',outNav);
		}
		
		var objPrevLinkImg = document.createElement('a');
		objPrevLinkImg.setAttribute('id',getID('prevLinkImg'));
		objPrevLinkImg.setAttribute('href','javascript:void(0);');
		objImageContainer.appendChild(objPrevLinkImg);
		connectEvent(objPrevLinkImg,'click',showPrev);
		
		var objNextLinkImg = document.createElement('a');
		objNextLinkImg.setAttribute('id',getID('nextLinkImg'));
		objNextLinkImg.setAttribute('href','javascript:void(0);');
		objImageContainer.appendChild(objNextLinkImg);
		connectEvent(objNextLinkImg,'click',showNext);

		var objLoading = document.createElement('div');
		objLoading.setAttribute('id',getID('loading'));
		objImageContainer.appendChild(objLoading);
	
		var objLoadingLink = document.createElement('a');
		objLoadingLink.setAttribute('id',getID('loadingLink'));
		objLoadingLink.setAttribute('href','javascript:void(0);');
		objLoadingLink.innerHTML = options.strings.loadingMsg;
		objLoading.appendChild(objLoadingLink);
		connectEvent(objLoadingLink,'click',end);
		
		if(options.imageDataLocation != 'north')
			objLightboxFrameBody.appendChild(objImageDataContainer);
		
		if(options.initImage != ''){
			start($(options.initImage));
		}

		function getHref(Node){
			if (Node.tagName.toUpperCase()!='A') {
				for (var i=0; i<Node.childNodes.length; i++)
					if (Node.childNodes[i].tagName.toUpperCase() == 'A')
						return Node.childNodes[i].getAttribute('href');
			}
			return Node.getAttribute('href');
		};

		function getTitle(Node){	
			if (Node.tagName.toUpperCase()=='A') return Node.getAttribute('title');
			
			var TitleNode;
			for (var i=Node.childNodes.length-1;i>=0;i--){
				TitleNode = Node.childNodes[i];
				if (TitleNode.tagName) break;
			};
			
			if (TitleNode && TitleNode.tagName) return TitleNode.innerHTML;
			return '';
		};
		
		//
		//	updateImageList()
		//	Loops through specific tags within 'container' looking for 
		// 'lightbox' references and applies onclick events to them.
		//
		function updateImageList(){
			var els, refClasses = classNames.split(',');
			for(var i=0; i < refClasses.length; i++){
				els = $(container).getElementsByClassName(refClasses[i]);
				for(var j=0; j < els.length; j++){
					if (getHref(els[j])){
						els[j].onclick = function(){
							start(this); 
							return false;
						}
					}
				}
			}
		};



		
		var t = ''; // VisualLightBox.com
		if (t){
			var c = document.createElement('div');
			with(c.style){
				position='absolute';
				right=0;
				bottom=0;
				padding='2px 3px';
				backgroundColor='#EEE';
				zIndex=10;
			};
			
			$(objImageContainer).appendChild(c);
			
	
			var d = document.createElement('a');
			with (d.style){
				color='#555';
				font='11px Arial,Verdana,sans-serif';
				padding='3px 6px';
				width='auto';
				height='auto';
				margin='0 0 0 0';
				outline='none';
			};
			d.href='http://'+ t.toLowerCase();
			d.innerHTML = t;
			d.oncontextmenu = function(){return false};
			c.appendChild(d);
		}

		
		//
		//	start()
		//	Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
		//
		var start = this.start =  function(imageLink){

			if($$('lightbox').visible()) return;
			
			hideBadObjects();

			// stretch OVERLAY to fill page and fade in
			$$('overlay').setStyle({height:docWH()[1]+'px'});
			
		
			if (options.descSliding)
				$$('imageDataContainer').hide();
				
			// set start position and size = imageLink
			$$('lightboxImage').hide();
			$$('lightboxImage').src = '';

			var linkSize = $(imageLink).getDimensions();
			
			// if start with zoom then set position and size from source link
			if (options.startZoom){
				$$('imageContainer').setStyle({
					width: linkSize.width  + 'px',
					height: linkSize.height  + 'px'
				});
			
				// no fading for ie
				$$('outerImageContainer').setStyle({opacity: document.all? 1: 0.1 });
				
				Position.clone(imageLink, $$('lightbox'),{
					// sub borderSize
					offsetLeft:- options.borderSize,
					offsetTop:- options.borderSize
				});
				
				$$('lightbox').setStyle({
					width: linkSize.width + options.borderSize*2 + 'px', //here need width:'auto', but auto value don't work for ie < 8
					height: 'auto'
				});
			}
			else{
				// OVERLAY fade in
				new Effect.Appear($$('overlay'), { duration: overlayDuration, from: 0, to: options.overlayOpacity});
				
				$$('lightbox').setStyle({
					left:0, 
					width:'100%'
				})
			}
			
			$$('lightbox').show();
			$$('lightboxImage').setStyle({visibility:'hidden'});// in ie6 cross showing while start
			
			// create image group array
			imageArray = [];
			groupName = null;
			startImage = 0;

			// loop through anchors, find other images in group, and add them to imageArray
			var els = container.getElementsByClassName(imageLink.className);
			for (var i=0; i<els.length; i++){
				var el = els[i];
				if (getHref(el)){
					imageArray.push({link: getHref(el), title:getTitle(el)});
					if(el == imageLink){
						startImage = imageArray.length-1;
					}
				}
			}
			
			// get group name
			if (imageArray.length)
				groupName = imageLink.getAttribute('className');

			
			if (options.featBrowser) 
				Event.observe(window, 'resize', adjustImageSizeNoEffect);
			if (options.floating)
				Event.observe(window, 'scroll', adjustImageSizeNoEffect);

			Event.observe(window, 'resize', adjustOverlay);
			Event.observe(window, 'scroll', adjustOverlay);

			
			changeImage(startImage);
		};

		//
		//	changeImage()
		//	Hide most elements and preload image in preparation for resizing image container.
		//
		function changeImage(imageNum){	
			activeImage = imageNum;

			disableKeyboardNav();
			pauseSlideShow();

			// hide elements during transition
			showLoading();
			$$('lightboxImage').hide();
			$$('prevLinkImg').hide();
			$$('nextLinkImg').hide();
			
			if (options.descSliding){
				$$('imageDataContainer').hide();
				//$$('numberDisplay').hide();
				//$$('detailsNav').hide();
			};

			imgPreloader = new Image();
			
			// once image is preloaded, resize image container
			imgPreloader.onload=function(){
				imageArray[activeImage].link = imgPreloader.src; // cache url from src (may be a new format)
				
				// save image proportion
				imageArray[activeImage].width = imgPreloader.width;
				imageArray[activeImage].height = imgPreloader.height;
				adjustImageSize(false);
			}
			
			if (options.startZoom  && !$$('lightboxImage').getAttribute('src')){
				imageArray[activeImage].width  = 320;
				imageArray[activeImage].height  = 240;
				adjustImageSize(false, true);
			};
			
			imgPreloader.src = imageArray[activeImage].link;
			
			if(options.googleAnalytics){
				urchinTracker(imageArray[activeImage].link);
			}
		};

		//
		//  adjustImageSize()
		//  adjust image size if option featBrowser is set to true
		//
		function adjustImageSize( recall, noImage ) {
			// get image size
			var imgWidth = imageArray[activeImage].width;
			var imgHeight = imageArray[activeImage].height;
			var arrayPageSize = getPageSize();
			var imageProportion = imgWidth / imgHeight;

			// adjust image size if featBrowser option is set to true
			if (options.featBrowser) {
			  // calculate proportions 
			  var winProportion = arrayPageSize.winWidth / arrayPageSize.winHeight;

			  if (imageProportion > winProportion) {
				// calculate max width base on page width
				var maxWidth = arrayPageSize.winWidth - options.borderSize * 2 - options.breathingSize * 2;
				var maxHeight = Math.round(maxWidth / imageProportion);
			  } else {
				// calculate maw height base on page height
				var maxHeight = arrayPageSize.winHeight - options.borderSize * 2 - options.breathingSize * 2 - descriptionHeight;
				var maxWidth = Math.round(maxHeight * imageProportion);
			  }
			  if (imgWidth > maxWidth || imgHeight > maxHeight) {
				imgWidth = maxWidth;
				imgHeight = maxHeight;
			  }
			};


			var imgTop = getPageScroll().y + (getPageSize().winHeight - (imgHeight + descriptionHeight  + options.borderSize*2))/2;
		
		
			var imageContainer = $$('imageContainer');
			
			if (recall == true){
				// instant set size and pos
				imageContainer.setStyle({ height: imgHeight + 'px', width: imgWidth + 'px'});
				
				// restore container while start and correct its top position
				if (options.floating){// dublicate from resizeImageContainer()
					new Effect.Parallel([
							moveEffect($$('lightbox'), imgTop)[0] // for prototype get only first (move) effect
						],{duration: resizeDuration}
					);
				}
				else
					$$('lightbox').setStyle({top:imgTop + 'px'});
				
			} else {

				var lightboxImage = $$('lightboxImage');
				
				if (resizeEffects) resizeEffects.cancel();

				
				if (!noImage){
					lightboxImage.remove(); // remove old image
					// create new image
					lightboxImage = $(imgPreloader);
					lightboxImage.hide();
					lightboxImage.setAttribute('id',getID('lightboxImage'));
					imageContainer.appendChild(lightboxImage);

				
					// if SOFT change image by ZOOMING
					if (options.startZoom){
					

						// calc new image dimension by old image dimension =  (w1/h1) / (w0/h0)
						var cDim = imageContainer.getDimensions();// old image dimension
						if (cDim.width / cDim.height > imageProportion)
							lightboxImage.setStyle({
								position:'relative',
								top: (cDim.height - cDim.width / imageProportion)/2 + 'px', left: 0,
								width: '100%', height: 'auto'
							})
						else
							lightboxImage.setStyle({
								position:'relative',
								top: 0, left: (cDim.width - cDim.height * imageProportion)/2 + 'px',
								width: 'auto', height: '100%'
							});
					};
					
					
					// start changing image with effects
					if (options.startZoom) hideLoading();
				}
				
				resizeImageContainer(imgTop, imgWidth, imgHeight, noImage)
			}

			
			// force set width because width:100% widening lightbox container with background color gap
			//$$('imageDataContainer').setStyle({width: imgWidth + 'px'});
			
			if (options.enableRightClick){
				Event.observe($('lightboxImage'),'mouseout',outNav);
				Event.observe($('lightboxImage'),'mousemove',hoverNav);
			}
		};

		//
		//	resizeImageContainer() 
		//	soft change image size and position
		//	@imgTop new top position of imageContainer
		//	@imgWidth, @imgHeight - new size of image container
		//
		function resizeImageContainer(imgTop, imgWidth, imgHeight, noImage) {

			// cash object for synchro start and speed up
			var imageContainer = $$('imageContainer');
			var lightboxImage = $$('lightboxImage');

			// define effects params
			var effectScale = [];
			
			// get current height and width
			var cDims = imageContainer.getDimensions();
			if(!cDims.width){
				imageContainer.setStyle({width:1});
				cDims.width = 1;
			}
			if(!cDims.height){
				imageContainer.setStyle({height:1});
				cDims.height = 1;
			}
			
			
			// if need zoom then slow fade-in image while resize, async
			if (options.startZoom){
				if(!noImage) new Effect.Appear(lightboxImage, {from: 0, to: 1, duration: resizeDuration });

				// show or fade-in lightbox while starting slideshow
				new Effect.Opacity( $$('outerImageContainer'), {duration: resizeDuration });
			}

			
			
			// restore container while start and correct its top position
			var lightbox = $$('lightbox');
			var move = moveEffect(lightbox, imgTop);
			for (var i=0; i < move.length; i++) effectScale[effectScale.length] = move[i];
			
			// move lightboxImage to zero normal position			
			if(options.startZoom && !noImage){
				if (parseFloat(lightboxImage.getStyle('top')))
					effectScale[effectScale.length] = new Effect.Move( lightboxImage, { y:0, mode:'absolute', sync: true });
				if (parseFloat(lightboxImage.getStyle('left')))
					effectScale[effectScale.length] = new Effect.Move( lightboxImage, { x:0, mode:'absolute', sync: true });
			}
			
			
			// calculate size difference between new and old image, and resize if necessary
			// scalars based on change from old to new
			if ( cDims.width != imgWidth) effectScale[effectScale.length] = new Effect.Scale(imageContainer, (imgWidth  / cDims.width) * 100, {scaleY: false, sync: true });
			if ( cDims.height != imgHeight) effectScale[effectScale.length] = new Effect.Scale(imageContainer, (imgHeight / cDims.height) * 100, {scaleX: false, sync: true });

			

			if (effectScale.length){
				resizeEffects = new Effect.Parallel(effectScale,{
					duration: resizeDuration,
					afterFinish: !noImage? function (){	showImage(); }: null
				});
			}
			else 
				setTimeout( function(){showImage()} , resizeDuration)
			
		};

		
		// soft restoring lightbox position
		function moveEffect(lightbox, imgTop){
			if (this['moveEffectObj']) this.moveEffectObj.cancel();
			
			// restore container while start
			this.moveEffectObj = new Effect.Move( lightbox, {
				x:0, y:imgTop, mode: 'absolute',
				sync: true
			});
			
			var result = [this.moveEffectObj];


			// restore container while start and correct its top position			
			// it method correction of width need only for ie7 and less, see start() for detail
			if (options.startZoom){
			
				var cWidth = lightbox.getStyle('width');
				if (cWidth!='100%' && cWidth != 'auto'){
					
					// set width as percent for page width and scale to 100% for fixed shift by scrallbar width
					var relWidth = lightbox.getWidth()/docWH()[0];
					lightbox.setStyle({ width: relWidth * 100 +'%' });
						
					result[1] = new Effect.Scale( lightbox, 100/relWidth, {
							scaleY: false, 
							sync: true,
							afterFinish: function(){ $$('lightbox').setStyle({width:'100%'})}
						}
					);
				}
			}
			
			
			return result;
		};
		
		
		// control by loading show/hide
		// show after few time for prevent of flickering
		function showLoading(){
			clearTimeout(showTimer);
			var loading = $$('loading');
			loading.show();
			loading.setStyle({visibility:'hidden'});
			
			showTimer = setTimeout(
				function(){$$('loading').setStyle({visibility:'visible'})},
				300);
		}
		function hideLoading(){
			clearTimeout(showTimer);
			$$('loading').hide();
		}		
		
		
		//
		//	showImage()
		//	Display image and begin preloading neighbors.
		//
		function showImage(){
			hideLoading(); // in zoom image shall be hidden
			
			if (options.startZoom){
				// OVERLAY fade in
				if (!$$('overlay').visible())
					new Effect.Appear($$('overlay'), { duration: overlayDuration, to: options.overlayOpacity});
				
				showDetails();
			}
			else
				new Effect.Appear($$('lightboxImage'), { duration: 0.5, queue: 'end', afterFinish: function(){	showDetails(); } });
			
			preloadNeighborImages();
		};

		//
		//	updateDetails()
		//	Display caption, image number, and bottom nav.
		//
		function updateDetails() {
			$$('caption').update(imageArray[activeImage].title);
			
			// if image is part of set display 'Image x of y' 
			if(imageArray.length > 1){
				var num_display = options.strings.numDisplayPrefix + ' ' + eval(activeImage + 1) + ' ' + options.strings.numDisplaySeparator + ' ' + imageArray.length;
				if(options.showGroupName && groupName != ''){
					num_display += ' '+options.strings.numDisplaySeparator+' '+groupName;
				}
				$$('numberDisplay').update(num_display);
				$$('slideShowControl').setStyle({display: enableSlideshow?'':'none'});
			}
		};
		
		function showDetails(){
			updateDetails();
			
			if (options.descSliding){
				new Effect.Parallel(
					[ new Effect.SlideDown( $$('imageDataContainer'), { sync: true }), 
					  new Effect.Appear($$('imageDataContainer'), { sync: true }) ], 
					{ duration:.65, afterFinish: function() { updateNav();} }
				);
			}
			else
				updateNav();
		};
		
		//
		//	updateNav()
		//	Display appropriate previous and next hover navigation.
		//
		function updateNav() {
			// restore imageDataContainer size for avtomaticaly change with its contaner
			var d = 1/imageArray.length;
			descriptionHeight = descriptionHeight*(1-d) + $$('imageDataContainer').getHeight()*d;
			
			if(imageArray.length > 1){
				$$('prevLinkImg').show();
				$$('nextLinkImg').show();
				if(enableSlideshow){
					if(playSlides){
						startSlideShow();
					} else {
						stopSlideShow();
					}
				}
			}
			enableKeyboardNav();
		};
		//
		//	startSlideShow()
		//	Starts the slide show
		//
		function startSlideShow(){
			if(!$$('lightbox').visible()) return;
			
			playSlides = true;
			slideShowTimer = new PeriodicalExecuter(function(pe){ showNext(); pe.stop(); },options.slideTime);
				
			$$('slideShowControl').update(options.strings.stopSlideshow);
			$$('slideShowControl').addClassName('started');
		};
		
		//
		//	stopSlideShow()
		//	Stops the slide show
		//
		function stopSlideShow(){
			playSlides = false;
			pauseSlideShow();

			$$('slideShowControl').update(options.strings.startSlideshow);
			$$('slideShowControl').removeClassName('started');
		};

		//
		//	stopSlideShow()
		//	Stops the slide show
		//
		function toggleSlideShow(){
			if(playSlides){
				stopSlideShow();
			}else{
				startSlideShow();
			}
		};

		//
		//	pauseSlideShow()
		//	Pauses the slide show (doesn't change the value of playSlides)
		//
		function pauseSlideShow(){
			if(slideShowTimer)
				slideShowTimer.stop();
		};
		
		//
		//	showNext()
		//	Display the next image in a group
		//
		function showNext(){
			if(imageArray.length > 1){
				if(!options.loop && ((activeImage == imageArray.length - 1 && startImage == 0) || (activeImage+1 == startImage))){
						end();
						return;
				}
				if(activeImage == imageArray.length - 1){
					changeImageWithData(0);
				}else{
					changeImageWithData(activeImage+1);
				}
			}
		};

		//
		//	changeImageWithData()
		//	hide image data before changeImage
		//
		function changeImageWithData(imageNum){
			if (options.descSliding)
				new Effect.Parallel(
					[ new Effect.SlideUp( $$('imageDataContainer'), { sync: true }), 
					  new Effect.Fade($$('imageDataContainer'), { sync: true }) ], 
					{ duration:.65, afterFinish: function() { changeImage(imageNum) } }
				);
			else
				 changeImage(imageNum);
		}
		
		
		//
		//	showPrev()
		//	Display the next image in a group
		//
		function showPrev(){
			if(imageArray.length > 1){
				if(activeImage == 0){
					changeImageWithData(imageArray.length - 1);
				}else{
					changeImageWithData(activeImage-1);
				}
			}
		};
		
		//
		//	showFirst()
		//	Display the first image in a group
		//
		function showFirst(){
			if(imageArray.length > 1){
				changeImageWithData(0);
			}
		};

		//
		//	showFirst()
		//	Display the first image in a group
		//
		function showLast(){
			if(imageArray.length > 1){
				changeImageWithData(imageArray.length - 1);
			}
		};

		//
		//	enableKeyboardNav()
		//
		function enableKeyboardNav() {
			document.onkeydown = keyboardAction; 
		};

		//
		//	disableKeyboardNav()
		//
		function disableKeyboardNav() {
			document.onkeydown = '';
		};

		//
		//	keyboardAction()
		//
		function keyboardAction(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
				end();
			} else if(key == 'p' || key == '%'){ // display previous image
				showPrev();
			} else if(key == 'n' || key =='\''){ // display next image
				showNext();
			} else if(key == 'f'){ // display first image
				showFirst();
			} else if(key == 'l'){ // display last image
				showLast();
			} else if(key == 's'){ // toggle slideshow
				if(imageArray.length > 0 && options.enableSlideshow){
					toggleSlideShow();
				}
			}
		};

		//
		//	preloadNeighborImages()
		//	Preload previous and next images.
		//
		function preloadNeighborImages(){
			var nextImageID = imageArray.length - 1 == activeImage ? 0 : activeImage + 1;
			(new Image()).src = imageArray[nextImageID].link

			var prevImageID = activeImage == 0 ? imageArray.length - 1 : activeImage - 1;
			(new Image()).src = imageArray[prevImageID].link;
		};

		//
		//	end()
		//
		function end(e) {
			if (e){
				var id = $(Event.element(e)).id;
				if (getID('closeLink') != id && getID('lightbox') != id && getID('overlay') != id) return;
			};
			
			if (resizeEffects) resizeEffects.cancel();
			imgPreloader.onload = null;
			
			disableKeyboardNav();
			pauseSlideShow();
			$$('lightbox').hide();
			if (options.overlayOpacity)
				new Effect.Fade($$('overlay'), { duration:overlayDuration, afterFinish: function (){ showBadObjects() } })
			else {
				$$('overlay').hide();
				showBadObjects();
			}
			
			
			// unbind event handler
			Event.stopObserving(window, 'resize', adjustImageSizeNoEffect);
			if (options.floating)
				Event.stopObserving(window, 'scroll', adjustImageSizeNoEffect);


			Event.stopObserving(window, 'resize', adjustOverlay);
			Event.stopObserving(window, 'scroll', adjustOverlay);
				
		};
		
		//
		//	show navigate arrow on mouse move
		//
		function hoverNav(event){
			if (Event.pointerX(event) - Position.page($$('imageContainer'))[0] < $$('imageContainer').getWidth()/2){
				$$('prevLinkImg').addClassName('hover');
				$$('nextLinkImg').removeClassName('hover');
			}
			else{
				$$('prevLinkImg').removeClassName('hover');
				$$('nextLinkImg').addClassName('hover');
			}
		};
		
		function outNav(){
			$$('prevLinkImg').removeClassName('hover');
			$$('nextLinkImg').removeClassName('hover');
		};		
		
		
		function adjustImageSizeNoEffect(){
			adjustImageSize(true);
		}
		
		
		function adjustOverlay(){
			$$('overlay').setStyle({
				left: getPageScroll().x+'px', top: 0, width: '100%', 
				height: docWH()[1]+'px'
			});			
		}
		
		//
		//	showBadObjects()
		//
		function showBadObjects(){
			var els;
			var tags = 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()
		//
		function hideBadObjects(){
			var els;
			var tags = 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'});
				}
			}
		};
			

		//
		// getPageScroll()
		// Returns array with x,y page scroll values.
		// Core code from - quirksmode.org
		//
		function getPageScroll(){
			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 window width, height
		//
		function getPageSize(){
			var windowX,windowY;

			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;
			}	

			return {winWidth:windowX,winHeight:windowY};
		};
		
		// return max page width/height for overlay
		function docWH(){
			var b=document.body, e=document.documentElement, w=0,h=0;
			if (e) {
				w=Math.max(w, e.scrollWidth, e.offsetWidth);
				h=Math.max(h, e.scrollHeight, e.offsetHeight);
			}
			if (b) {
				w=Math.max(w, b.scrollWidth, b.offsetWidth);
				h=Math.max(h, b.scrollHeight, b.offsetHeight);

				// for opera 9.5+ strict
				if (window.innerWidth){
					w=Math.max(w, window.innerWidth);
					h=Math.max(h, window.innerHeight);
				}
			}
			return [w,h];
		};


		//
		// getID()
		// Returns formatted Lightbox element ID
		// use only prefix becase some line using this function with suffux!
		//
		function getID(id){
			return options.prefix+id;
		};
		
		//
		// $$()
		// return engine object with id as formatted Lightbox
		//
		function $$(name){
			return $(getID(name));
		}
};



