/*====================================================================

	startAt			: define witch slide is displayed for start (0 by default)
	auto			: define if the slide is automatic or manual (true or false by default)
	order			: define slides order (only if auto true)
	prevNext		: define if we add prev and next buttons (true by defaults or false)
	prevLabel		: define the displayed text in the prev button
	nextLabel		: define the displayed text in the next button
	navigation		: define navigation method (arrows by default, navbar, both or none)
	navLink			: define if navigation links are html links or img, possible value
						- link (default)
						- image url
	transition		: define transition animation between images, possible value :
						- fade by default
						- slideY	(horizontally) (default)
						- slideX	(vertically)
	delay			: define delay between 2 slides
	transitionSpeed	: define animation speed, possible values :
						- slow (default)
						- fast
						- value in milliseconds (1000 = 1 sec)
	fancybox		: open image in fancybox on click (true by default or false)

======================================================================*/

//navigation: arrows, navbar, both, none

(function($) {
    $.fn.jboSlideShow = function(options) {
        
        //Parametres par defaut
        var defaults = {
			startAt: 0,
			auto: false, 
			navigation: "arrows", 
			order: "normal", 
			delay: "5000", 
			prevLabel: "Previous", 
			nextLabel: "Next", 
			navIn: "link", 
			navOut: "link", 
			pauseLabel: "Pause", 
			transition: "slide", 
			transitionSpeed: "slow", 
			fancybox: true
		};
		var opts = $.extend(defaults, options);
		
		//On parcours tout les noeuds
		$(this).each(function() {
			
			var $t = $(this);
			var slideShowIndex = $t.index();
			var slideWidth = $t.width();
			var nbSlides = $("li", $t).length;
			var maxSlide = nbSlides*slideWidth
			var lightBoxClass = (opts.lightbox == true) ? 'lightbox' : '';
			
			var anim; //Pour le setTimeout
			
			// Ajout d'une class a la liste a animer pour pouvoir mieux l'identifier et la distinguer par rapport a la liste de navigation
			$('ul', $t).addClass('toSlide');
			
			$('ul.toSlide li:eq(0) img').show();
			
			// Masque le contenu eventuel a afficher dans la fancybox
			$('.fancyContent').wrap('<div style="display: none;"></div>');
			
			/////////////////////////////////////
			// Gestion de la fancybox fancybox //
			/////////////////////////////////////
			
			if(opts.fancybox == true)
				{
					$("ul.toSlide li", $t).each(function() {
						
						var fancyLink = $("img", this).attr("src");
						var fancyCaption = $("img", this).attr("alt");

						if( $("a", this).length == 0 )
							{
								$(this).children().wrap('<a href="'+fancyLink+'" title="'+fancyCaption+'" rel="fancy_group_'+slideShowIndex+'"></a>');
							}
						
						if( $("a", this).attr("class") != "no-fancy" )
							{
								var fancyLink = $("a", this).attr("href");
								$("a", this).attr("rel", "fancy_group_"+slideShowIndex);
								$("a", this).attr("title", fancyCaption);
							}
						
						// Check des differents contenus possibles pour la fancybox
						// Image, inline, Iframe, ...
						
						if( $("a", this).attr("class") != "no-fancy" )
							{
								var linkType = checkFancyUrl(fancyLink);
								switch(linkType)
									{
										case "image": $("a", this).addClass("fancyImage"); break;
										case "iframe": $("a", this).addClass("fancyIframe"); break;
										case "swf": $("a", this).addClass("fancySwf"); break;
										case "inline": $("a", this).addClass("fancyInline"); break;
									}
							}
					});
					
					// Cas d'une image
					$('ul.toSlide li a.fancyImage', $t).fancybox({
						'autoScale' : true,			// Pour eviter un bug avec certains navigateurs)
						'autoDimensions' : false,	// Pour eviter un bug avec certains navigateurs)
						'type': 'image'
					});
					
					// Cas d'une iFrame
					$('ul.toSlide li a.fancyIframe', $t).fancybox({
						'type': 'iframe', 
						'width': '100%', 
						'height': '100%'
					});
					
					// Cas d'une animation swf
					$('ul.toSlide li a.fancySwf', $t).fancybox({
						'autoScale' : true,			// Pour eviter un bug avec certains navigateurs)
						'autoDimensions' : false,	// Pour eviter un bug avec certains navigateurs)
						'type': 'swf'
					});
					
					// Cas d'un contenu en ligne
					$('ul.toSlide li a.fancyInline', $t).fancybox({
						'autoScale' : true,			// Pour eviter un bug avec certains navigateurs)
						'autoDimensions' : false,	// Pour eviter un bug avec certains navigateurs)
						'type': 'inline', 
						'hideOnContentClick': false
					});
				}
			
			//Selection du mode de transition
			var firstSlide = (opts.startAt >= nbSlides) ? nbSlides-1 : opts.startAt;
			
			switch(opts.transition)
				{
					//Si le mode de transition est fade (mode par defaut)
					//On masque tout les slides et on affiche seulement le premier ou celui passe en paramettre (startAt)
					case 'fade':
						$('li', $t).hide();
						$('li:eq('+firstSlide+')', $t).show().addClass('currentSlide');
					break;
					
					//Si le mode de transition est slide
					case 'slide':
						//On place la liste a sa position initiale par rapport au premier slide a afficher
						$('ul', $t).css('left', '-'+firstSlide*slideWidth+'px').show()
						$('li:eq('+firstSlide+')', $t).addClass('currentSlide');
						//On mets tout les slides l'un a cote de l'autre
						for(var i=0; i<nbSlides; i++) { $('li:eq('+i+')', $t).css("left", i*slideWidth); }
					break;
					
					default:
						$('li', $t).hide();
						$('li:eq('+firstSlide+')', $t).show().addClass('currentSlide');
					break;
				}

			////////////////
			// Navigation //
			////////////////
			
			// Ajout des boutons prev et next selon le paramettre (ops.navigation)
			if( (opts.navigation == "arrows" || opts.navigation == "both") && nbSlides > 1 && opts.auto == false )
				{
					prevLabel = opts.prevLabel;
					nextLabel = opts.nextLabel;
					
					$t.append('<a class="prev">'+prevLabel+'</a>');
					$t.append('<a class="next">'+nextLabel+'</a>');

					$('a.next', $t).show();
					if(firstSlide == 0 && nbSlides > 1) { $('.prev', $t).hide(); }
					if(opts.startAt == (nbSlides-1) && nbSlides > 1) { $('.next', $t).hide(); }
				}
			
			// Ajout de la barre de navigation selon le paramettre (opts.navigation)
			if( (opts.navigation == "navbar" || opts.navigation == "both" || opts.auto != false && opts.navigation != "none") && nbSlides > 1 )
				{
					var navigation = "";
					for(var i=0; i<nbSlides; i++) {
						var classe = (i == firstSlide) ? ' class="active"' : '';
						var img = (i == firstSlide) ? opts.navIn : opts.navOut;
						navLink = (opts.navOut == "link") ? (i+1) : img;
						navigation += '<li'+classe+'><a href="">'+navLink+'</a></li>';
					}
					$t.append('<div class="navbar"><ul>'+navigation+'</ul></div>');
					
					$('.navbar ul li', $t).each(function(e) {
						var $t = $(this);
						$('a img', $t).attr("alt", (e+1)).attr("title", (e+1));
					});
					
					//$(".navbar ul li a img", $t).attr("width", $(".navbar ul li a img", $t).width()).attr("height", $(".navbar ul li a img", $t).height());
				}
				
			// Add pause button
			if(opts.auto == true && nbSlides > 1)
				{
					$t.append('<div class="pause">'+opts.pauseLabel+'</div>');
				}
			
			$( '.navbar li:eq('+opts.startAt+')', $t ).addClass('active');
			
			////////////////////////////
			// Navigation automatique //
			////////////////////////////
			
			if(opts.auto == true)
				{
					var slideIndex = $('ul.toSlide li.currentSlide', $t).index();
					if(opts.transition == "fade") { animation("fadeSlide", slideIndex); }
					if(opts.transition == "slide") { animation("slideSlide", slideIndex); }
				}
			
			///////////////////////////
			// Navigation au clavier //
			///////////////////////////
			/*
			$(document).keyup(function(e) {
				var code = (e.keyCode ? e.keyCode : e.which);
				if(code == 37) { $(".prev", $t).click(); }
				if(code == 39) { $(".next", $t).click(); }
			});
			*/
			
			//////////////////////////////////////////////////////////////
			// Gestion des click sur les lien de la barre de navigation //
			//////////////////////////////////////////////////////////////
			
			$('.navbar ul li', $t).click(function() {
				
				if(opts.auto == false)
					{
						var slideIndex = $(this).index();
						var currentSlideIndex = $('li.currentSlide', $t).index();
										
						//On masque/affiche le bouton .next
						if(slideIndex+1 != nbSlides) { displayNavButtons('.next', 'show'); }
						else { displayNavButtons('.next', 'hide'); }
						
						//On masque/affiche le bouton .prev
						if(slideIndex-1 >= 0) { displayNavButtons('.prev', 'show'); }
						else { displayNavButtons('.prev', 'hide'); }
						
						if( slideIndex != currentSlideIndex )
							{
								switch(opts.transition)
									{
										case 'fade': animation("fadeSlide", slideIndex); break;
										case 'slide': animation("slideSlide", slideIndex); break;
									}
							}
					}
				return false;
			});
			
			/* Prev next buttons
			-------------------------------------------------------------------------------------------------*/
			
			/////////////////////////////////////////
			//Gestion des click sur le boutons next//
			/////////////////////////////////////////
			
			//var maxSlide = nbSlides*slideWidth;
			
			$('.next', $t).click(function() {
				//On affiche le bouton .prev
				displayNavButtons('.prev', 'show');
				
				//Prevent double click
				if ($('ul.toSlide', $t).is(":animated")) { return; }
				
				var changeIndex = $('li.currentSlide', $t).index()+1;
				switch(opts.transition)
					{
						case "fade": animation("fadeSlide", changeIndex); break;
						case "slide": animation("slideSlide", changeIndex); break;
					}
				return false;
			});
			
			/////////////////////////////////////////
			//Gestion des click sur le boutons prev//
			/////////////////////////////////////////
			
			$('.prev', $t).click(function() {
				//On affiche le bouton .next
				displayNavButtons('.next', 'show');
				
				//Prevent double click
				if ( $('ul.toSlide', $t).is(":animated") || $('ul.toSlide li', $t).is(":animated") ) { return; }
				
				var changeIndex = $('li.currentSlide', $t).index()-1;
				switch(opts.transition)
					{
						case "fade": animation("fadeSlide", changeIndex); break;
						case "slide": animation("slideSlide", changeIndex); break;
					}
				return false;
			});
			
			//////////////////////////////
			// Fonctions de transitions //
			//////////////////////////////
			
			/* Fonction fade
			=======================================================================================================================*/
			function fadeSlide(slideIndex)
				{
					if(nbSlides > 1)
						{
							if(slideIndex+1 >= nbSlides) { displayNavButtons('.next', 'hide'); }
							if(slideIndex-1 < 0) { displayNavButtons('.prev', 'hide'); }
							if(slideIndex < nbSlides)
								{
									if(opts.auto == true)
										{
											anim = setInterval (function () {
												var slideIndex = $("li.currentSlide", $t).index();
												var nextSlide = slideIndex;
												switch(opts.order)
													{
														case "normal": nextSlide = (nextSlide+1 < nbSlides) ? nextSlide+1 : 0; break;
														case "random": nextSlide = getRandom(nbSlides); slideIndex = nextSlide; break;
														default: nextSlide = (nextSlide+1 < nbSlides) ? nextSlide+1 : 0; break;
													}
				    							$("li.currentSlide", $t).fadeTo(opts.transitionSpeed, 0, function() { $(this).hide(); }); 
				    							$("li:eq("+nextSlide+")", $t).fadeTo(opts.transitionSpeed, 1.0);
						    					updateCurrentSlide(nextSlide);
				   								updateNavigation(nextSlide);
											}, opts.delay);
										}
										
									else
										{
											$("li.currentSlide", $t).fadeTo(opts.transitionSpeed, 0,function() { $(this).hide(); });
											$("li:eq("+slideIndex+")", $t).fadeTo(opts.transitionSpeed, 1.0);
											updateCurrentSlide(slideIndex);
											updateNavigation(slideIndex);
										}
								}
						}
				}
			
			/* Fonction slide
			=======================================================================================================================*/
			
			function slideSlide(slideIndex)
				{
					if(opts.auto == true)
						{
							anim = setInterval (function () {
								var maxSlide = 0-(nbSlides*slideWidth);
								slideIndex = (slideIndex+1 < nbSlides) ? slideIndex+1 : 0;
								var currentSlide = $('li.currentSlide', $t).index();
								
    							switch(opts.order)
									{
										case "normal":
										newPos = ( (slideIndex*slideWidth) > maxSlide) ? 0-(slideIndex*slideWidth) : 0;
										nextSlide = (slideIndex < nbSlides) ? slideIndex : 0;
										break;
										
										case "random": 
										nextSlide = getRandom(nbSlides); slideIndex = nextSlide;	
										var newSlidePos = $('ul.toSlide li:eq('+nextSlide+')', $t).position();
										var newPos = "-"+(nextSlide*slideWidth);
										break;
										
										default:
										newPos = ( (slideIndex*slideWidth) > maxSlide) ? 0-(slideIndex*slideWidth) : 0;
										nextSlide = (slideIndex < nbSlides) ? slideIndex : 0;
										break;
									}
    							
    							$('ul.toSlide', $t).animate({
    								left: newPos+'px'
    							}, opts.transitionSpeed);
    							
    							updateCurrentSlide(nextSlide);
								updateNavigation(nextSlide);
								
							}, opts.delay);
						}
					else
						{
							var maxSlide = 0-maxSlide;
							var currentSlide = $('li.currentSlide', $t).index();
							var newPos = ( (slideIndex*slideWidth) > maxSlide) ? 0-(slideIndex*slideWidth) : 0;
							if(slideIndex+1 >= nbSlides) { displayNavButtons('.next', 'hide'); }
							if(slideIndex-1 < 0) { displayNavButtons('.prev', 'hide'); }
							if(slideIndex >= 0)
								{
									var currentSlide = $('li.currentSlide', $t).index();
									if(newPos) { newSlide = newPos }
									else { newSlide = '-'+slideIndex*slideWidth; }
									updateCurrentSlide(slideIndex);
									updateNavigation(slideIndex);
									$('ul.toSlide', $t).animate({
										left: newSlide+'px'
									}, opts.transitionSpeed);
								}
						}
				}
			
			////////////////////////	
			// Fonctions diverses //
			////////////////////////
			
			function animation(transition, slideIndex)
				{
					switch(transition)
						{
							case "fadeSlide":
							fadeSlide(slideIndex);
							break;
							
							case "slideSlide":
							slideSlide(slideIndex);
							break;
						}
				}
			
			function displayNavButtons(button, display)
				{
					(display == "show") ? $(button, $t).fadeTo("slow", 1.0) : $(button, $t).fadeTo("slow", 0, function() { $(this).hide(); });
				}
			
			function updateCurrentSlide(slideIndex)
				{
					$('li.prevSlide', $t).removeClass('prevSlide');
					$('li.currentSlide', $t).removeClass('currentSlide').addClass('prevSlide');
					$('li:eq('+slideIndex+')', $t).addClass('currentSlide');
				}
			
			function updateNavigation(changeIndex)
				{
					var imgInactive = $('.navbar li:eq('+changeIndex+') a img', $t).attr("src");
					var imgActive = $('.navbar li.active a img', $t).attr("src");
					if(opts.navOut != "link")
						{
							$('.navbar li a img', $t).attr("src", imgInactive);
							$('.navbar li', $t).removeClass('active');
							$('.navbar li:eq('+changeIndex+') a img', $t).attr("src", imgActive);
							$('.navbar li:eq('+changeIndex+')', $t).addClass('active');
						}
				}
			
			function getRandom(numMax)
				{
					var num = Math.round( Math.random()*(numMax-1) );
					var currentSlide = $("li.currentSlide", $t).index();
					var prevSlide = $("li.prevSlide").index();
					if(nbSlides > 2) { while(num == currentSlide || num == prevSlide) { num = Math.round( Math.random()*(numMax-1) ); } }
					else { while(num == currentSlide) { num = Math.round( Math.random()*(numMax-1) ); } }
					return num;
				}
			
			function checkFancyUrl(url)
				{
					var imagePattern	= new RegExp(/^([a-zA-Z0-9\-\_\/]+)\.(jpeg|jpg|png|gif)$/);
					var iframePattern	= new RegExp(/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/);
					var swfPattern		= new RegExp(/.swf$/);
					var inlinePattern	= new RegExp(/^\#([a-zA-Z0-9-_]+)$/);
					
					// For fancybox content type
					if( url.match(imagePattern) ) { return "image"; }
					if( url.match(iframePattern) ) { return "iframe"; }
					if( url.match(swfPattern) ) { return "swf"; }
					if( url.match(inlinePattern) ) { return "inline"; }
				}
				
			//////////////////////////////////////////
			// Systeme play/pause pour le mode auto //
			//////////////////////////////////////////
			
			if(opts.auto == true)
				{
					$t.mouseover(function()
						{
							$(".pause", $t).stop().fadeTo("fast", 1.0);
							clearInterval(anim);
						});
					$t.mouseout(function() {
						$(".pause", $t).stop().fadeTo("slow", 0);
						changeIndex = $("li.currentSlide", $t).index();
						
						currentPos = $('ul.toSlide', $t).position();
						newPos = ( (currentPos.left-slideWidth) > maxSlide) ? currentPos.left-slideWidth : 0;
						switch(opts.transition)
							{
								case "fade": animation("fadeSlide", changeIndex); break;
								case "slide": animation("slideSlide", changeIndex); break;
							}
					});
				}
			
        });//EOF each
		
        return $(this);  
    }; //EOF plugin
})(jQuery);




















