/*
	JaS is developed by Robert Nyman, http://www.robertnyman.com
	For more information, please see http://www.robertnyman.com/jas

	EDIT:
		2009-03-11 : Vincent (http://www.vlamoureux.com/)
			Updated for reusability
		2009-03-12 : Vincent (http://www.vlamoureux.com/)
			Added some properties : carouselMode, useThumbnailImages and ueAltTextOnThumbnails. See optional options below for details...
				
*/



/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/*

Usage
	new JaS_CreateGallery( options:Object );
	

Mandatory options
	imagePath:String
	images:Array
	fadeContainerId:String
	imageContainerId:String
	imageTextContainerId:String
	previousLinkId:String
	nextLinkId:String
	thumbnailContainerId:String
	imageCounterId:String
	
Optional options
	useImageText:Boolean            [default=true]
	useThumbnails:Boolean           [default=true]
	useKeyboardShortcuts:Boolean    [default=true]
	useFadingIn:Boolean             [default=true]
	useFadeWhenNotSlideshow:Boolean [default=true]
	fadeIncrement:Number            [default=.14]
	imageIndex:uint                 [default=0]
	useImageCounter:Boolean			[default=true]
	carouselMode:Boolean            [default=false] : If set to true, loops the navigation
	useThumbnailImages:Boolean      [default=false] : If set to true, uses small images for thumbnails with &rsquo;_th&rsquo; as suffix (&rsquo;mypicture.jpg&rsquo; needs thumbnail image &rsquo;mypicture_th.jpg&rsquo;). *** Known actually as problem if set to true since the large image isn&rsquo;t cached.
	ueAltTextOnThumbnails:Boolean   [default=true]  : If set to false, removes &rsquo;alt&rsquo; and &rsquo;title&rsquo; attributes on thumbnails.
	useImageCounter:Boolean			[default=true]

*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

function JaS_CreateGallery( options ) {
		this.options = options;
		this.imageCounterId = "image-counter";
		
		// Default options
		if (this.options.useImageText == null) this.options.useImageText = true;
		if (this.options.useImageCounter == null) this.options.useImageCounter = true;
		if (this.options.useThumbnails == false) this.options.useThumbnails = true;
		if (this.options.useImageCounter == null) this.options.useImageCounter = true;
		if (this.options.useKeyboardShortcuts == null) this.options.useKeyboardShortcuts = true;
		if (this.options.useFadingIn == null) this.options.useFadingIn = true;
		if (this.options.useFadeWhenNotSlideshow == null) this.options.useFadeWhenNotSlideshow = true;
		if (this.options.fadeIncrement == 0) this.options.fadeIncrement = 0.18;
		if (this.options.imageIndex == null) this.options.imageIndex = 0;
		if (this.options.carouselMode == null) this.options.carouselMode = true;
		if (this.options.useThumbnailImages == null) this.options.useThumbnailImages = false;
		if (this.options.ueAltTextOnThumbnails == null) this.options.ueAltTextOnThumbnails = false;
		
		// Methods
		this.init                        = JaS_Init;
		this.previousLinkClick           = JaS_PreviousLinkClick;
		this.nextLinkClick               = JaS_NextLinkClick;
		this.documentKeyDown             = JaS_DocumentKeyDown;
		this.setImage                    = JaS_SetImage;
		this.displayImageCount           = JaS_DisplayImageCount;
		this.nextImage                   = JaS_NextImage;
		this.previousImage               = JaS_PreviousImage;
		this.setImageText                = JaS_SetImageText;
		this.fadeIn                      = JaS_FadeIn;
		this.fadeOut                     = JaS_FadeOut;
		this.fadeOutDone                 = JaS_FadeOutDone;
		this.fade                        = JaS_Fade;
		this.setFade                     = JaS_SetFade;
		this.setFadeParams               = JaS_SetFadeParams;
		this.createThumbnails            = JaS_CreateThumbnails;
		this.thumbnailClick              = JaS_ThumbnailClick;
		this.markCurrentThumbnail        = JaS_MarkCurrentThumbnail;
		this.applyKeyboardNavigation     = JaS_ApplyKeyboardNavigation;
		this.preventDefaultEventBehavior = JaS_PreventDefaultEventBehavior;
		
		
		// Starts program
		this.init();
}
	


function JaS_Init(){
	if($){
		var refObject = this;
		
		this.fadeContainer = $(this.options.fadeContainerId);
		this.imageContainer = $(this.options.imageContainerId);
		this.slideshowIsSupported = this.fadeContainer && this.imageContainer;
		if(this.slideshowIsSupported){
			this.allImages = this.options.images;
			this.currentImages = this.options.images;
			if(this.options.useImageText){
				this.imageTextContainer = $(this.options.imageTextContainerId);
				if( !this.imageTextContainer){
					this.options.useImageText = false;
				}
			}
			this.hasOpacitySupport = typeof this.fadeContainer.style.filter != "undefined" || typeof this.fadeContainer.style.opacity != "undefined";
			this.useMSFilter = typeof this.fadeContainer.style.filter != "undefined";	
			this.previousLink = $(this.options.previousLinkId);
			this.previousLink.onclick = function (e) { refObject.previousLinkClick(e) };
			this.nextLink = $(this.options.nextLinkId);
			this.nextLink.onclick = function (e) { refObject.nextLinkClick(e) };
			this.imageCounter = $(this.imageCounterId);
	
			if(this.options.useKeyboardShortcuts){
				document.onkeydown = function(e) { refObject.documentKeyDown(e, refObject) };
			}
			
			this.thumbnailContainer = $(this.options.thumbnailContainerId);
			if(this.options.useThumbnails && this.thumbnailContainer){
				this.createThumbnails();
			}
						
			this.isInitialLoad = true;
			this.setImage();
			this.isInitialLoad = false;
		}
	}
}



function JaS_PreviousLinkClick(oEvent){
	var oEvent = (typeof oEvent != "undefined")? oEvent : event;
	this.preventDefaultEventBehavior(oEvent);
	this.previousImage();
}



function JaS_NextLinkClick(oEvent){
	var oEvent = (typeof oEvent != "undefined")? oEvent : event;
	this.preventDefaultEventBehavior(oEvent);
	this.nextImage();
}



function JaS_DocumentKeyDown(oEvent, refObject){
	var oEvent = (typeof oEvent != "undefined")? oEvent : event;
	refObject.applyKeyboardNavigation(oEvent, refObject);
}



function JaS_SetImage(){
	if(this.currentImages.length > 0){
		this.imageSource = this.currentImages[this.options.imageIndex][0];
		this.imageText = this.currentImages[this.options.imageIndex][1];
		if(this.useFadingOut || this.options.useFadeWhenNotSlideshow && (this.useFadeAtInitialLoad || !this.isInitialLoad)){
			this.fadeOut();
		}
		else{
			this.setImageText();
			this.displayImageCount();
		}
		if(this.options.useThumbnails){
			this.markCurrentThumbnail();
		}
	}
}



function JaS_DisplayImageCount(){
	if(this.imageCounter){
		this.imageCounter.innerHTML = (((this.currentImages.length > 0)? this.options.imageIndex : -1) + 1) + " / " + this.currentImages.length;
	}
}



function JaS_NextImage(){
	if(this.options.imageIndex < (this.currentImages.length - 1)){
		++this.options.imageIndex;
		this.setImage();
	} else if ( this.options.carouselMode ) {
		this.options.imageIndex = 0;
		this.setImage();
	}
}



function JaS_PreviousImage(){
	if(this.options.imageIndex > 0){
		--this.options.imageIndex;
		this.setImage();
	} else if ( this.options.carouselMode ) {
		this.options.imageIndex = (this.currentImages.length - 1);
		this.setImage();
	}
}



function JaS_SetImageText(){
	this.imageTextContainer.setAttribute("alt", this.imageText);
	if(this.options.useImageText && typeof this.imageText == "string"){
		this.imageTextContainer.innerHTML = this.imageText;
	}
}



function JaS_FadeIn(){
	this.setFadeParams(true, 0, 1);
	this.functionAfterFade = null;
	this.fade();
	if(this.slideshowIsPlaying){
		this.functionAfterFade = "this.startSlideshow()";
	}
}



function JaS_FadeOut(){
	this.setFadeParams(false, 1, 0);
	this.functionAfterFade = "this.fadeOutDone()";
	this.fade();
}



function JaS_FadeOutDone(){
	this.displayImageCount();
	this.imageContainer.setAttribute("src", (this.options.imagePath + this.imageSource));
	this.setImageText();
	if(this.options.useFadingIn){
		this.fadeIn();
	}
	else{
		this.fadeLevel = 1;
		this.setFade();
	}
}



function JaS_Fade(){
	if((this.fadingIn && this.fadeLevel < this.fadeEndLevel) || !this.fadingIn && this.fadeLevel > this.fadeEndLevel){
		this.fadeLevel = (this.fadingIn)? this.fadeLevel + this.options.fadeIncrement : this.fadeLevel - this.options.fadeIncrement;
		// This line is b/c of a floating point bug in JavaScript
		this.fadeLevel = Math.round(this.fadeLevel * 10) / 10;
		this.setFade();
		var refObject = this;
		this.fadeTimer = setTimeout(function(){ refObject.fade() }, this.fadeInterval);
	}
	else{
		clearTimeout(this.fadeTimer);
		if(this.functionAfterFade){
			eval(this.functionAfterFade);
		}
	}
}



function JaS_SetFade(){
	if(this.useMSFilter){
		this.fadeContainer.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + (this.fadeLevel * 100) + ")";
	}
	else{
		this.fadeContainer.style.opacity = this.fadeLevel;
	}
}



function JaS_SetFadeParams(bFadingIn, intStartLevel, intEndLevel){
	this.fadingIn = bFadingIn;
	this.fadeLevel = intStartLevel;
	this.fadeEndLevel = intEndLevel;
}



function JaS_CreateThumbnails(){
	this.thumbnailContainer.innerHTML = "";
	this.thumbnailCollection = [];
	var oThumbnailsList = document.createElement("ul");
	var oListItem;
	var oThumbnail;
	var oCurrentImage;
	var refObject = this;
	for(var i=0; i<this.currentImages.length; i++){
		oCurrentImage = this.currentImages[i];
		oListItem = document.createElement("li");
		oThumbnail = document.createElement("img");
		oThumbnail.setAttribute("id", ("jas-thumbnail-" + i));
		var thumbnailSource = !this.options.useThumbnailImages? this.options.imagePath + oCurrentImage[0] : this.options.imagePath + oCurrentImage[0].substring(0, oCurrentImage[0].lastIndexOf(".")) + "_th" + oCurrentImage[0].substring(oCurrentImage[0].lastIndexOf("."));
		oThumbnail.setAttribute("src", thumbnailSource);
		
		if ( this.options.ueAltTextOnThumbnails ) {
			oThumbnail.setAttribute("alt", oCurrentImage[1]);
			oThumbnail.setAttribute("title", oCurrentImage[1]);
		} else
			oThumbnail.setAttribute("alt", "");
		
		oThumbnail.onclick = function() { refObject.thumbnailClick(this); };
		this.thumbnailCollection.push(oThumbnail);
		oListItem.appendChild(oThumbnail);
		oThumbnailsList.appendChild(oListItem);			
	}
	this.thumbnailContainer.appendChild(oThumbnailsList);
	if(this.thumbnailCollection.length > 0){
		this.markCurrentThumbnail();
	}
}



function JaS_ThumbnailClick(me){
	this.options.imageIndex = parseInt(me.getAttribute("id").replace(/\D*(\d+)$/, "$1"), 10);
	this.setImage();
}



function JaS_MarkCurrentThumbnail(){
	if(this.currentThumbnailSelected){
		this.currentThumbnailSelected.className = "";
		// Sometimes, in IE, the image loses its reference to its parent
		if(this.currentThumbnailSelected.parentNode){
			this.currentThumbnailSelected.parentNode.className = "";
		}
	}
	this.currentThumbnailSelected = this.thumbnailCollection[this.options.imageIndex];
	this.currentThumbnailSelected.className = "selected";
	this.currentThumbnailSelected.parentNode.className = "selected-parent";
}



function JaS_ApplyKeyboardNavigation(oEvent, refObject){
	var intKeyCode = oEvent.keyCode;
	if( !oEvent.altKey){
		switch(intKeyCode){
			case 37:
			case 38:
				refObject.previousImage();
				refObject.preventDefaultEventBehavior(oEvent);
				break;
			case 39:
			case 40:
				refObject.nextImage();
				refObject.preventDefaultEventBehavior(oEvent);
				break;
		}
	}
}



function JaS_PreventDefaultEventBehavior(oEvent){
	if(oEvent){
		oEvent.returnValue = false;
		if(oEvent.preventDefault){
			oEvent.preventDefault();
		}
	}
}



// Utilities
function $(strId){
	return document.getElementById(strId);
}

