﻿/*global $ , document, setInterval, clearInterval */

/**
	-------------------------------------------------------------------------------------------------------
	Carrousel
	
	p_list = liste (ul) des éléments
	p_btNext = bouton pour passer l'élément suivant
	p_btPrev = bouton pour passer l'élément précédent
	p_maskObject = Element définissant le contour de la zone d'affichage (overflow:hidden)
	p_moveDuration = durée du mouvement (en ms)
	p_direction = 'H' = horizontal, 'V' = vertical 
	p_autoRollDelay = delay entre 2 roll automatique (si null ou 0, pas de roll auto) en seconde
 */
 var Carrousel = function (p_list, p_btNext, p_btPrev, p_maskObject, p_moveDuration, p_direction, p_autoRollDelay) {
 
	if($(p_list) && $(p_btNext) && $(p_btPrev) && $(p_list + ' > li').size() > 0) {
		
		// Element affiché
		this.currentItem = 0;
		// Elément à afficher
		this.followingItem = 0;
		// Bouton suivant
		this.btPrev = $(p_btPrev);
		// Bouton précédent
		this.btNext = $(p_btNext);
		// UL
		this.list = $(p_list);
		// Liste des LI
		this.listItem = $(p_list + ' > li');
		// Nombre de LI
		this.nbItem = this.listItem.size();
		// Sens du carrousel
		this.vertical = (p_direction == 'V' ? true : false);
		// Objet avec l'overfow:hidden
		this.mask = $(p_maskObject);
		// Position des contours de l'objet
		this.topDisplay = this.mask.position().top;
		this.bottomDisplay = this.topDisplay + this.mask.height();
		this.leftDisplay = this.mask.position().left;
		this.rightDisplay = this.leftDisplay + this.mask.width();
		
		// 'Y' à partir duquel l'objet est entièrement caché
		this.topHidden = (this.topDisplay  - this.mask.height());
		// 'X' à partir duquel l'objet est entièrement caché
		this.leftHidden = (this.leftDisplay  - this.mask.width());
		// Durée du mouvement
		this.moveDuration = p_moveDuration;
		// Indique si un mouvement est en cours
		this.isMoving = false;
		// Déroulement automatique
		if (p_autoRollDelay) {
			this.autoRollDelay = parseInt(p_autoRollDelay, 0) * 1000;
			this.autoRoll = (this.autoRollDelay > 0);
		}
		else {
			this.autoRoll = false;
		}
		// Id de l'interval
		this.autoRollIntervalId = -1;
	
		// retourne l'index de suivant
		this.getNextItem = function () {
			return (this.currentItem + 1 < this.nbItem ? this.currentItem + 1 : 0);
		};
		
		// retourne l'index de précédent
		this.getPrevItem = function () {
			return (this.currentItem - 1 >= 0 ? this.currentItem - 1 : this.nbItem - 1);
		};
		
		// Déplace les éléments
		this.moveItem = function (p_followingItem, p_direction){
			if (!this.isMoving) {
				
				// Contient la ref vers le carrousel
				var mainObj = this;
				
				// Coordonées de départ et d'arrivée des éléments
				var currItemStartPos = 0;
				var currItemToGo = {};
				var followItemStartPos = 0;
				var followItemToGo = {};

				if (p_direction === 'top') {
					currItemStartPos = this.topDisplay;
					followItemToGo = {top: this.topDisplay};

					if (p_followingItem === 'next') {
						currItemToGo = {top: this.bottomDisplay};
						followItemStartPos = this.topHidden;
					}
					else {
						currItemToGo = {top: this.topHidden};
						followItemStartPos = this.bottomDisplay;
					}
				}
				else {
					currItemStartPos = this.leftDisplay;
					followItemToGo = {left: this.leftDisplay};

					if (p_followingItem === 'next') {
						currItemToGo = {left: this.leftHidden};
						followItemStartPos = this.rightDisplay;
					}
					else {
						currItemToGo = {left: this.rightDisplay}
						followItemStartPos = this.leftHidden;
					}
				}
				
				
				// On stoppe le roll auto pour pouvoir faire repartir le compte à rebour au début.
				if(this.autoRollIntervalId !== -1) {
					clearInterval (this.autoRollIntervalId);
				}
				
				this.isMoving = true;
				
				this.followingItem = (p_followingItem === 'next' ? this.getNextItem() : this.getPrevItem());
				
				$(this.listItem.get(this.currentItem)).css(p_direction, currItemStartPos).animate(currItemToGo, this.moveDuration, "linear", function (){
					mainObj.currentItem = mainObj.followingItem; 
					mainObj.isMoving = false;
					// On relance le le mode auto
					if (mainObj.autoRollDelay > 0) {
						mainObj.autoRollIntervalId = setInterval(mainObj.autoNextItem, mainObj.autoRollDelay);
					}
				});
				$(this.listItem.get(this.followingItem)).css(p_direction, followItemStartPos).animate(followItemToGo, this.moveDuration, "linear");
			}
		};
		
		// Affiche l'élément suivant
		this.moveToNextItemV = function (p_evt) {
			p_evt.preventDefault();
			// on récupère l'objet Carrousel
			var parent = p_evt.data.parentObject;
			parent.moveItem ('next', 'top');
		};
		
		 // Affiche l'élément précédent
		 this.moveToPreviousItemV = function (p_evt) {
			p_evt.preventDefault();
			var parent = p_evt.data.parentObject;
			parent.moveItem ('prev', 'top');
		 };
		 
		// Affiche l'élément suivant
		this.moveToNextItemH = function (p_evt) {
			p_evt.preventDefault();
			// on récupère l'objet Carrousel
			var parent = p_evt.data.parentObject;
			parent.moveItem ('next', 'left');
		};
		
		 // Affiche l'élément précédent
		 this.moveToPreviousItemH = function (p_evt) {
			p_evt.preventDefault();
			var parent = p_evt.data.parentObject;
			parent.moveItem ('prev', 'left');
		 };
			 
		 // Affiche l'élément suivant (utilisé pour le mode auto uniquement
		 this.autoNextItem = function () {
			$(p_btNext).trigger('click');
		 };
		 
		 // Initialisation
		 this.init = function () {
		 
			 // On lie les boutons au fonctions
			 if (this.vertical) {
				 this.btPrev.bind ('click', {parentObject : this}, this.moveToPreviousItemV);
				 this.btNext.bind ('click', {parentObject : this}, this.moveToNextItemV);
	
				// on initialise la position des éléments (li)
				for (var iFor = 0; iFor < this.nbItem; iFor++) {
					if (iFor === 0) {
						$(this.listItem.get(iFor)).css("top", this.topDisplay);
						this.currentItem = 0;
					}
					else {
						$(this.listItem.get(iFor)).css("top", this.bottomDisplay);
					}
				}
			 }
			 else {
				 this.btPrev.bind ('click', {parentObject : this}, this.moveToPreviousItemH);
				 this.btNext.bind ('click', {parentObject : this}, this.moveToNextItemH);
	
				// on initialise la position des éléments (li)
				for (var iFor = 0; iFor < this.nbItem; iFor++) {
					if (iFor === 0) {
						$(this.listItem.get(iFor)).css("left", this.leftDisplay);
						this.currentItem = 0;
					}
					else {
						$(this.listItem.get(iFor)).css("left", this.rightDisplay);
					}
				}
			 }
			
			// On lance le déroulement automatique (si voulu)
			if (this.autoRoll) {
				this.autoRollIntervalId = setInterval(this.autoNextItem, this.autoRollDelay);
			}
		 }
		 
		 
		 // Initialisation de l'objet
		 this.init();
	}

};
