/**
 * Le gestionnaire de slideshow tout simple
 */
petzl.views.ClassicSlideshow = function (pSelector, pOptions)
{
	// ------- PRIVATE PROPERTIES --------
	// Redéclarer cet élément
	var that = this;
	
	// Cibler le sélécteur
	var element 			= $(pSelector);
	
	// Le container
	var slidesContainer;

	// Cibler les slides
	var slides 				= element.find(".slide");
	
	// Les dimensions
	var sizes;

	// L'index en cours
	var currentIndex		= 0;

	// L'interval
	var interval 			= -1;

	// Les options
	var options = $.extend({
		// Démarrage automatique du slideshow à l'initialisation
		autoStart: true,

		// Première slide à afficher (0 pour aucune)
		index: 1,
		
		// Si le slideshow est vertical
		opacityAnimation: false,
		parallaxAnimation: false,
		vertical: false,
		
		// Le selecteur du container
		containerSelector: ".slidesContainer",

		// Durée d'une slide (ms)
		duration: 4000,

		// Durée de l'animation (ms)
		transitionDuration: 600,

		selectStrict : false,
		
		// Le easing
		easing: 'easeInOutCubic'
	}, pOptions);

	// ------- PUBLIC PROPERTIES --------
	// Le handler externe de changement
	this.onChange;
	
	
	// ---------- CONSTRUCTOR -----------
	function init ()
	{
		// L'index de départ
		currentIndex = options.index;
		
		// Cibler le selecteur
		slidesContainer = element.find(options.containerSelector);
		
		// Récupérer les dimensions du slideshow
		sizes = [element.width(), element.height];
		
		// Placer le slideshow en relatif pour le container en absolu
		/*
		element.css({
			position: "relative"
		});
		*/
	   
		// Appliquer a toutes les slides
		slides.css({
			height: sizes[1]
		});
		
		// Initialiser le container
		if (options.vertical)
		{
			// Taille du container
			slidesContainer.css({
				width: sizes[0],
				height: 50000
			});
		}
		else if (options.opacityAnimation)
		{
			// Taille du container
			slidesContainer.css({
				height: sizes[1]
			});
			
			// Les slides en position absolute
			slides.css({
				position : 'absolute',
				'float': '',
				top: 0,
				left: 0,
				opacity:0
			});
			
			slides.first().css({
				position : 'relative',
				opacity:1
				
			});
		}
		else
		{
			// Taille du container
			slidesContainer.css({
				position: "absolute",
				width: 50000,
				height: sizes[1]
			});
			
			// Forcer le float sur les slides
			slides.css({
				"float": "left"
			});
		}
		
		// Démarrer automatiquement
		// Et si on a des slides
		if (options.autoStart && slides.length > 1)
		{
			// Démarrer
			that.start();
		}
		
		// Si on a un index
		if (currentIndex != 0)
		{
			// Séléctionner l'index
			that.select(currentIndex);
		}
	}

	// -------- PRIVATE METHODS ---------
	// Dispatcher le changement
	function dispatchChange ()
	{
		if (that.onChange != null)
			that.onChange(currentIndex);
	}

	// -------- PUBLIC METHODS ---------
	
	this.initSizes = function ()
	{
		// Récupérer les dimensions du slideshow
		sizes = [element.width(), element.height];
	   
		// Appliquer a toutes les slides
		slides.css({
			width: sizes[0],
			height: sizes[1]
		});
		
		if (!options.vertical && !options.opacityAnimation)
		{
			// Taille du container
			slidesContainer.css({
				left : (currentIndex-1)*sizes[0]*-1
			});
		}
	};


	$(window).resize(function(){
		that.initSizes();

	});
	
	
	
	// Démarrer le slideshow
	this.start = function ()
	{
		// Arrêter
		that.stop();

		// Démarrer
		interval = setInterval(that.next, options.duration);
	};
	
	// Arrêter le slideshow
	this.stop = function ()
	{

		// Vérifier si c'est démarré
		if (interval != -1)
		{
			// On arrête
			clearInterval(interval);
			interval = -1;
		}
	};
	
	// Redémarrer le slideshow
	this.restart = function ()
	{

		// Vérifier si c'est démarré
		if (interval != -1)
		{
			that.start();
		}
	};

	// Passer à la slide précédente
	this.prev = function ()
	{
		if(!options.selectStrict){
			that.select((currentIndex <= 1 ? slides.length+1 : currentIndex) - 1, dispatchChange);
		}
		else if(options.selectStrict && currentIndex > 1){
			that.select(currentIndex - 1, dispatchChange);
		}
	};

	// Passer à la slide suivante
	this.next = function ()
	{
		
		if(!options.selectStrict){
			that.select(currentIndex >= slides.length ? 1 : currentIndex + 1, dispatchChange);
		} 
		else if(options.selectStrict && currentIndex <= slides.length){
			that.select(currentIndex + 1, dispatchChange);
		} 
	};
	
	// Séléctionner une slide en particulier
	this.select = function (pIndex, pThen)
	{
		
		// Séléctionner la slide suivante
		// Limiter au maximum et au minimum
		var oldIndex = currentIndex;
		currentIndex = Math.max(0, Math.min(pIndex, slides.length));
		
		// Animer le container
		if (options.opacityAnimation)
		{
			if(options.transitionDuration == 0)
			{
				$(slides[currentIndex - 1]).appendTo(slidesContainer).stop().css({
					opacity:1
				});
			}
			else
			{
				slides.css({zIndex:1});
				$(slides[currentIndex - 1]).appendTo(slidesContainer).stop().css({
					opacity: 0,
					zIndex:2
				}).animate({
					opacity: 1
				}, {
					duration: options.transitionDuration,
					easing: options.easing,
					complete : function(){
						slides.not(slides.eq(currentIndex - 1)).css({opacity : 0});
					}
				});
			}
		}
		else if(options.parallaxAnimation == 1)
		{
			slides.eq(currentIndex - 1).css({ display : 'block', opacity:0});
			var isLast = false;
			if(oldIndex == slides.length && currentIndex == 1)
			{
				isLast = true;
			}
			if(currentIndex > oldIndex)
			{
				var toLeft = sizes[0] * -1;
			}
			else
			{
				slidesContainer.css({ left : sizes[0] * -1 });
				var toLeft = 0;
			}
			
			// slide courant
			slides.eq(currentIndex - 1).stop().animate({
				opacity:1
			}, {
				duration : options.transitionDuration,
				easing: options.easing
			});
			
			// ajouter le parallax au slide courant
			slides.eq(currentIndex - 1).find('.hr, .title, .subtitle, p').each(function(i){
				var mltply = (toLeft == 0) ? -1 : 1;
				$(this).css({marginLeft: mltply*(i+1)*50}).stop().delay((i+1)*50).stop().animate({
					marginLeft : 0
				}, {
					duration : options.transitionDuration*1.5,
					easing: options.easing
				});
			});
			
			// les autres slides
			slides.not(slides.eq(currentIndex - 1)).stop().animate({
				opacity:0
			}, {
				duration : options.transitionDuration,
				easing: options.easing
			});
			
			// ajouter le parallax aux dernier slide
			if(oldIndex != currentIndex)
			{
				var elementSlidesNotCurrent = slides.eq(oldIndex - 1).find('.hr, .title, .subtitle, p');
				var iReverse = elementSlidesNotCurrent.length-1;
				elementSlidesNotCurrent.each(function(i){
					var mltply = (toLeft == 0) ? -1 : 1;
					$(this).stop().delay((i+1)*50).stop().animate({
						marginLeft : mltply*(iReverse+1)*70
					}, {
						duration : options.transitionDuration*2,
						easing: options.easing
					});
					iReverse--;
				});
			}
			
			
			// Slidewhow horizontal
			slidesContainer.stop().animate({
				left: toLeft
			}, {
				duration: options.transitionDuration,
				easing: options.easing,
				complete : function(){
					slides.not(slides.eq(currentIndex - 1)).css({display : 'none'});
					slidesContainer.css({left : 0});
				}
			});
		}
		else
		{
			// Slidewhow horizontal
			slidesContainer.stop().animate({
				left: - (currentIndex - 1)* sizes[0]
			}, {
				duration: options.transitionDuration,
				easing: options.easing
			});
		}
		
		// La suite
		if (pThen != null)
			pThen();
	};
	
	this.selectDirect = function(pIndex, pThen){
		var currentDuration = options.transitionDuration;
		options.transitionDuration = 0;
		that.select(pIndex, pThen);
		options.transitionDuration = currentDuration;
	};
	
	// Initialiser
	init();
};