// JavaScript Document
(function($) {
	$.fn.yGalerie = function(settings) {
		var gallery 	= this;
		var slideObj 	= $("#yg_slide");
		var captionObj	= $("#yg_caption");
		var thumbsObj	= $("#yg_thumbs");
		var loaderObj	= $("#yg_slide .yloader");
		var slideNavObj = $("#yg_navigation");
		var settings = jQuery.extend({
			thumbsMax: 9,
			thumbWidth: 60,
			thumbHeight: 60,
			thumbsOpacity:0.5,
			thumbsOpacityHover:0.8,
			thumbsOpacityActive:1,
			slideShowDelay: 2000,
			effectTransitionDelay:500
		},settings);
		jQuery.extend(this,{
			slideShowOn 	: false,
			slideShowPid	: undefined,
			slidesCount		: this.find("li").size(),
			slideActive		: 1,
			pagesCount		: function() { return Math.ceil(gallery.slidesCount/settings.thumbsMax); },
			pageActive		: 1,
			slidesDb		: [],
			slidePile		: [],
			slideLoadingPid : undefined,
			
			
			/****************************************************************/
			/* 						 INIT METHODS							*/
			/****************************************************************/
			initGallery : function() {
				if(gallery.slidesCount==0) {
					slideObj.html("Empty Gallery!");
				}
				slideObj.fadeTo("slow",1);
				captionObj.fadeTo("slow",1);
				thumbsObj.fadeTo("slow",1);
				
				// INIT THUMBS :
				gallery.initThumbs();
				gallery.initSlideshow();
				gallery.initSlide();
				gallery.slideActive = 1;
				gallery.updateGallery(1);
			},
			/* INIT THUMBS AND PAGE NAVIGATION 	*/
			initThumbs : function() {
				/* TO CHANGE */
				
				// gallery.width(settings.thumbWidth*gallery.slidesCount+2);
				// thumbsObj.find(".thumbsWrapper").width(settings.thumbsMax*settings.thumbWidth);
				
				var thumbs = thumbsObj.find("li");
				var slidesCounter = 0;
				// SETTING OPACITY OF THUMBS
				thumbs.css("opacity",settings.thumbsOpacity);
				
				// PARSING ALL THUMBS TO GET THE IMAGE DATA
				thumbs.each(function() {
					slidesCounter++;
					if(slidesCounter > settings.thumbsMax) {
						$(this).hide();	
					}
					gallery.slidePile.push(slidesCounter);
					var slideData = {
						src : $(this).find("a").attr("href"),
						alt : $(this).find("a").attr("title"),
						caption : $(this).find(".caption").remove(),
						slide : undefined
					};
					// REGISTERING IMAGE DATA AND SETTING THUMBS LINK HREF
					gallery.slidesDb[''+slidesCounter] = slideData;
					$(this).find("a.thumb").attr("href","#"+slidesCounter);
				});
				
				// HOVER EFFECT FOR THUMBS
				thumbs.hover(
					function(e) {
						//gallery.find("li").not(".active");
						if(!$(this).hasClass("active")) {
							$(this).fadeTo("fast",settings.thumbsOpacityHover);
						}
					},
					function(e) {
						if(!$(this).hasClass("active")) {
							$(this).fadeTo("fast",settings.thumbsOpacity);
						}
					}
				);
			
				// CLICK HANDLER FOR THUMBS
				thumbs.find("a.thumb").click(function(e) {
				 	e.preventDefault();
					gallery.updateSlideshow(false);
					gallery.updateGallery($(this).attr("href"));
					return false;
				});
				
				
				// CLICK HANDLER FOR THUMBS NAVIGATION
				$(".thumbsNav").find("a").click( function(e) {
					e.preventDefault();
					gallery.updateSlideshow(false);
					gallery.updateGallery($(this).attr("href"));
					return false;
				});
				gallery.onKeyDown();
			},
			/* INIT SLIDE SLIDE NAVIGATION AND CAPTION	*/
			initSlide : function() {
				// SLIDE NAV
				slideNavObj.find("a.navSlide").click(function(e) {
						e.preventDefault();
						gallery.updateSlideshow(false);
						gallery.updateGallery($(this).attr("href"));
						return false;
				});		
			},
			/* INIT SLIDESHOW */
			initSlideshow : function() {
				slideNavObj.find("a.navSlideshow").hide();
				slideNavObj.find("a.navSlideshow.play").show();
				slideNavObj.find("a.navSlideshow.play").click(function() {
							$(this).hide();
							gallery.updateSlideshow(true);
							return false;
				});
				slideNavObj.find("a.navSlideshow.pause").click(function() {
							$(this).hide();
							gallery.updateSlideshow(false);
							return false;
				});
			},
			/****************************************************************/
			/* 						 UPDATE METHODS							*/
			/****************************************************************/
			/* MAIN UPDATE METHOD CALLED TO SYNC ON A CLICK EVENT OR SLIDESHOW PLAY */
			updateGallery : function(hash) {
				/* WE SET THE ACTIVE SLIDE */
				hash = gallery.getHash(hash);
				if(!gallery.slidesDb[''+hash]) {
					return gallery;
				} else {
					gallery.slideActive = hash;
				}
				
				if(!gallery.slidesDb[''+hash].slide) {
					gallery.loadSlide(hash);
					return gallery;
				} else {
					gallery.updateSlide(gallery.slideActive); 
					gallery.updateThumbs(gallery.slideActive);
				}
				return gallery;
			},
			/* UPDATE THUMBS AND PAGE NAVIGATION */
			updateThumbs : function(hash) {
				
				// SET ACTIVE THUMB
				oldActive = gallery.find("li.active");
				newActive = gallery.find("li[rel='"+hash+"']");
				oldActive.removeClass("active");
				oldActive.fadeTo(gallery.effectTransitionDelay,settings.thumbsOpacity);
				newActive.fadeTo(gallery.effectTransitionDelay,settings.thumbsOpacityActive);
				newActive.addClass("active");
				
				// NAVIGATION :
				var newPage = gallery.getPage(hash);
				thumbsNavPrevious 	= $(".thumbsNav > a.thumbsPrevious");
				thumbsNavNext		= $(".thumbsNav > a.thumbsNext");
				previousPage		= gallery.previousPage(hash);
				nextPage			= gallery.nextPage(hash);
				previousPageSlide 	= previousPage*settings.thumbsMax - settings.thumbsMax+1;
				nextPageSlide		= nextPage*settings.thumbsMax - settings.thumbsMax+1;
				thumbsNavPrevious.attr("href","#"+previousPageSlide);
				thumbsNavNext.attr("href","#"+nextPageSlide);
				
				if(newPage==1) {
					thumbsNavPrevious.hide();	
				} else {
					thumbsNavPrevious.show();					
				}
				if(newPage==gallery.pagesCount()) {
					thumbsNavNext.hide();	
				} else {
					thumbsNavNext.show();					
				}
				
				if(newPage==gallery.pageActive) {
					return false;
				}
				
				/* CHANGE PAGE ANIMATION */
				
				/* UNCOMMENT FOR SLIDE THUMBS EFFECT */
				/* if(newPage<gallery.pageActive) {
					stepCoef 	= gallery.pageActive-newPage;
					stepOp		= "+=";
				} else {
					stepCoef = newPage-gallery.pageActive;
					stepOp		= "-=";
				}
				stepAnimation = stepCoef*thumbsObj.find(".thumbsWrapper").width();
				gallery.pageActive = newPage;
				gallery.animate({left:stepOp+stepAnimation},400);
				*/
				
				/* UNCOMMENT FOR FADE THUMBS EFFECT */
				thumbsLi	= gallery.find("li");
				gallery.pageActive = newPage;
				var i = 0;
				var thisLi;
				thumbsLi.each(function() {
					i++;
					thisLi = $(this);
					if(gallery.getPage(i)==gallery.pageActive) {
						thisLi.show();
					} else { 
						thisLi.hide();
					}
				});
				gallery.hide().fadeIn(gallery.effectTransitionDelay);
				return this;
			},
			/* UPDATE SLIDE, SLIDE NAVIGATION AND CAPTION */
			updateSlide : function(hash) {
				// SLIDE NAV
				slideNavObj.find("a.navSlide.previous").attr("href",'#'+gallery.previousSlide(hash));
				slideNavObj.find("a.navSlide.next").attr("href",'#'+gallery.nextSlide(hash));
				
				// THE CAPTION
				var caption = gallery.slidesDb[''+gallery.slideActive].caption;
				captionObj.css("opacity",0);
				captionObj.find(".caption_title").html(caption.find(".image-title").html());
				captionObj.find(".caption_description").html(caption.find(".image-desc").html());
				captionObj.find(".caption_download").html(caption.find(".download").html());
				captionObj.fadeTo(gallery.effectTransitionDelay,1);
				$("a.yGalFullScreen").yGalBox();
				
				// THE SLIDE
				oldSlide = slideObj.find(".slideWrapper.current");
				oldSlide.removeClass("current");
				oldSlide.addClass("previous");
				urlFsImage = caption.find("a.yGalFullScreen").attr("href");
				currentSlide = $('<div class="slideWrapper current"><a class="yGalFullScreen" href="'+urlFsImage+'"></a></div>');
				currentSlide.find("a").html(gallery.slidesDb[''+gallery.slideActive].slide);
				currentSlide.css("opacity",0);
				slideObj.append(currentSlide);
				// yGalBox => to draw the FULL SIZE IMAGE
				currentSlide.find("a.yGalFullScreen").yGalBox();
				
				if(gallery.slideTransition) {
					gallery.slideTransition(oldSlide,currentSlide);
				} else {
				// DEFAULT TRANSITION
				//oldSlide.remove();
				oldSlide.fadeTo(400,0,function() { oldSlide.remove(); });
				loaderObj.hide(); currentSlide.fadeTo(500,1);
				//setTimeout(function() {  }, 200);
				}
			},
		
			updateSlideshow : function (status) {
				if(typeof status == "boolean" ) {
					gallery.slideShowOn = status;
				}
				if(gallery.slideShowOn === false) {
					slideNavObj.find("a.navSlideshow.pause").hide();
					slideNavObj.find("a.navSlideshow.play").show();
					clearTimeout(gallery.slideShowPid);
					return false;
				}  
				if(gallery.slideShowOn === true) {
					slideNavObj.find("a.navSlideshow.pause").show();
					slideNavObj.find("a.navSlideshow.play").hide();
					gallery.updateGallery(gallery.nextSlide(gallery.slideActive));
					gallery.slideShowPid = setTimeout(function() { gallery.updateSlideshow(true); },settings.slideShowDelay);
					return true;
				}
				return false;
			},
	
			/****************************************************************/
			/* 						SECONDARY FUNCTION						*/
			/****************************************************************/
			/* LOADING A SLIDE AND ADDING IT TO slidesDb */
			recursiveSlideLoading : function() {
				if(gallery.slidePile.length==0) {
					clearTimeout(gallery.slideLoadingPid);
					return false;
				}
				hash = gallery.slidePile[0];
				gallery.slidePile.shift();
				if(gallery.slidesDb[''+hash].slide) {
					clearTimeout(gallery.slideLoadingPid);
					gallery.slideLoadingPid = setTimeout(function() { gallery.recursiveSlideLoading(); },200);
				} else {
					gallery.loadSlide(hash);
				}
				return gallery;
			},
			loadSlide : function(hash) {
				clearTimeout(gallery.slideLoadingPid);
				if(gallery.slideActive==hash) {
					loaderObj.show();
				}
				slide = new Image();
				slide.onload = function() {
					gallery.slidesDb[''+hash].slide = slide;
					if(gallery.slideActive==hash) {
						gallery.updateGallery(hash);
					}
					gallery.slideLoadingPid = setTimeout(function() { gallery.recursiveSlideLoading(); },200);
				}
				slide.src = gallery.slidesDb[''+hash].src;
				slide.alt = gallery.slidesDb[''+hash].alt;
			},
			nextPage : function(hash) {
				thisPage 	= gallery.getPage(hash);
				nbPages		= gallery.pagesCount();
				if((thisPage+1)>nbPages) {
					return nbPages;
				} else {
					return thisPage+1;
				}
			},
			previousPage : function(hash) {
				thisPage 	= gallery.getPage(hash);
				if((thisPage-1)<=0) {
					return 1;
				} else {
					return thisPage-1;
				}
			},
			nextSlide : function(hash) {
				var nextSlide = eval(hash)+1;
				if(nextSlide>gallery.slidesCount) {
					nextSlide = 1;
				}
				return nextSlide;
			},
			previousSlide : function(hash) {
				var previousSlide = eval(hash)-1;
				if(previousSlide<=0) {
					previousSlide = gallery.slidesCount;
				}
				return previousSlide;
			},
			getPage : function(hash) {
				return Math.ceil(hash/settings.thumbsMax);
			},
			/* GETTING THE HASH CONTAINED IN LINKS with # */
			getHash : function(hash) {
				if(typeof hash == "number") {
					return hash;
				}
				return parseInt(hash.replace(/^.*#/, '').replace(/\?.*$/, ''));
			},
			onKeyDown : function() {
				$(document).keydown(function(e) {
					gallery.find("li").unbind("mouseleave");
					gallery.find("li").unbind("mouseenter");
					nextSlide 		= gallery.nextSlide(gallery.slideActive);
					previousSlide 	= gallery.previousSlide(gallery.slideActive);;
					lastSlide		= gallery.slidesCount;
					firstSlide		= 1;
					switch(e.which) {
						case 32: // space
							gallery.updateSlideshow(false);
							gallery.updateGallery(nextSlide);
							e.preventDefault();
							break;
						case 35: // End
							gallery.updateSlideshow(false);
							gallery.updateGallery(lastSlide);
							e.preventDefault();
							break;
						case 36: // Home
							gallery.updateSlideshow(false);
							gallery.updateGallery(firstSlide);
							e.preventDefault();							
							break;
						case 37: // left arrow
							gallery.updateSlideshow(false);
							gallery.updateGallery(previousSlide);
							e.preventDefault();							
							break;
						case 39: // right arrow
							gallery.updateSlideshow(false);
							gallery.updateGallery(nextSlide);
							e.preventDefault();					
							break;
					}
				});
				return gallery;
			}
		});
		gallery.initGallery();
	}
})(jQuery);
