var Slide = new Class({

	Implements: [Options,Events],
	
	//Définition des variables de class
	options: {
		slide: [],
		slides: [],
		listSlides: [],
		nbSlides: [],
		slideSize: [],
		slideOn: 1,
		slideToGo: [],//Le slide à afficher
		orientation: 'horizontal',//Orientation du défilemement
		propertyCSS: 'margin-left',//Propriété à modifier
		propertySize: 'width',
		btnNext: [],
		btnPrev: [],
		btns: null,//Boutons d'affichage de slide individuellement
		autoSlide: 0,//Animation automatique
		timer: 5000,
		directionAuto: 1,//Sens de déplacement automatique
		periodical: [],
		boucle: 1,
		type: 'slide'
	},

	/**
	 * Function initialize 
	 * 
	 * @description : initialisation de l'objet 
	 * @param : mySlide -> conteneur des slides,btnPrev -> bouton précédent,btnNext -> bouton suivant,btns -> boutons individuels,orientation -> vertical / horizontal
	 *          auto -> defilement automatique,timer -> temps entre chaque slide,boucle -> tourne en boucle ou non
	 * @access : public
	 * @return : void
	 * @date : 2010-03-31
	 * @author : François Guémard <f.guemard@hegyd.com>
	 */
	initialize: function(mySlide,options){

		this.setOptions(options);

		this.options.slide        = mySlide;
		this.options.slides       = mySlide.getChildren('div');
		this.options.listSlides   = this.options.slides.get('id');
		this.options.nbSlides     = this.options.listSlides.length;

		//Si il n'y a qu'1 slide ou moins arrêt du slide
		if (this.options.nbSlides <= 1) return false;
		
		//Initialisation du sens de défilement si différent du default
		if (this.options.orientation == 'vertical') {
			this.options.propertyCSS  = 'margin-top';
			this.options.propertySize = 'height';
		}
		
		this.options.slideSize    = parseInt(this.options.slides[0].getStyle(this.options.propertySize));
		
		this.options.slide.setStyle(this.options.propertySize,this.options.nbSlides*this.options.slideSize);

		//Affectation de l'object courant à la variable objectSlide
		var objectSlide = this;

		//Configuration du bouton précédent
		if (objectSlide.options.btnPrev != null) {
			objectSlide.options.btnPrev.setStyle('cursor','pointer');
			objectSlide.options.btnPrev.addEvent('click', function(e){
				objectSlide.animate({'objectSlide' : objectSlide,'direction' : -1,'action' : 1});
			});
		}
		
		//Configuration du bouton suivant
		if (objectSlide.options.btnNext != null) {
			objectSlide.options.btnNext.setStyle('cursor','pointer');
			objectSlide.options.btnNext.addEvent('click', function(e){
				objectSlide.animate({'objectSlide' : objectSlide,'direction' : 1,'action' : 1});
			});
		}

		//Configuration des boutons individuels
		if (objectSlide.options.btns != null) {
			objectSlide.options.btns.getChildren('a').addEvent('click', function(e){
            	if(e != undefined) new Event(e).stop();
				
				var slide = this.get('href');
	
				objectSlide.goToSlide(slide);
			});
		}

		//Si le nombre slides est inférieur à 3, ne tourne pas en boucle
		if (objectSlide.options.nbSlides < 3 && objectSlide.options.boucle == 1) objectSlide.options.boucle = 0;

		//Initialisation des blocs pour tourner en boucle
		if (objectSlide.options.type == 'slide' && objectSlide.options.boucle == 1) {
			objectSlide.options.slides[objectSlide.options.nbSlides-1].dispose();
			objectSlide.options.slide.grab(objectSlide.options.slides[objectSlide.options.nbSlides-1],'top');
			objectSlide.options.slide.setStyle(objectSlide.options.propertyCSS,-objectSlide.options.slideSize);
			objectSlide.options.slideOn = 2;
			
			objectSlide.options.slides     = objectSlide.options.slide.getChildren('div');
			objectSlide.options.listSlides = objectSlide.options.slides.get('id');
		}

		//Initialisation des blocs pour le fade
		if (objectSlide.options.type == 'fade') {
			objectSlide.options.slide.setStyle(objectSlide.options.propertySize,objectSlide.options.slideSize);
			objectSlide.options.slide.setStyle(objectSlide.options.propertyCSS,0);
			objectSlide.options.slides.setStyle('position','absolute');
			
			objectSlide.options.slides[objectSlide.options.nbSlides-1].dispose();
			objectSlide.options.slide.grab(objectSlide.options.slides[objectSlide.options.nbSlides-1],'top');
			
			objectSlide.options.slideOn    = 2;
			objectSlide.options.slides     = objectSlide.options.slide.getChildren('div');
			objectSlide.options.listSlides = objectSlide.options.slides.get('id');
			
			for (var i = 0;i < objectSlide.options.nbSlides;i++) {
				if (i != (objectSlide.options.slideOn-1)) {
					objectSlide.options.slides[i].setStyle('opacity','0');
					objectSlide.options.slides[i].setStyle('visibility','hidden');
				}
			}
		}

		//Lancement de l'animation automatique
		if (this.options.autoSlide) {

			objectSlide.options.periodical = objectSlide.animate.periodical(objectSlide.options.timer,null,{'objectSlide' : objectSlide,'direction' : this.options.directionAuto});
	
		}

	},

	/**
	 * Function animate
	 * 
	 * @description : Lance l'animation paramétrée dans la direction souhaitée, si il y a animation automatique, relance le timer à 0
	 * @param :  direction = 1 -> suivant, direction = -1 -> précédent
	 * @access : public
	 * @return : void
	 * @date : 2010-04-01
	 * @author : François Guémard <f.guemard@hegyd.com>
	 */
	animate: function(params){

		objectSlide = params['objectSlide'];
		direction   = params['direction'];
		action      = params['action'];
		
		if (objectSlide.options.autoSlide && action) {
			$clear(objectSlide.options.periodical);
			if (action == 1) objectSlide.options.directionAuto = direction;//Si clique bouton suivant / précédent changement de directionAuto
			objectSlide.options.periodical = objectSlide.animate.periodical(objectSlide.options.timer,null,{'direction': objectSlide.options.directionAuto,'objectSlide': objectSlide});
		}

		if (objectSlide.options.type == 'fade') objectSlide.fade(direction);
		else objectSlide.slide(objectSlide.options.directionAuto);

	},

	/**
	 * Function slide 
	 * 
	 * @description : Slide dans la direction souhaitée 
	 * @param :  direction = 1 -> suivant, direction = -1 -> précédent
	 * @access : public
	 * @return : void
	 * @date : 2010-04-01
	 * @author : François Guémard <f.guemard@hegyd.com>
	 */
	slide: function(direction,slideToGo){
		var objectSlide   = this;
		var slide         = objectSlide.options.slide;
		var slideMargin   = -((objectSlide.options.slideOn-1)*objectSlide.options.slideSize);
		var marginToSlide = slideMargin;
		var myTween       = new Fx.Tween(slide);
		//var myTween       = new Fx.Tween(slide,{onComplete : function() {console.log(objectSlide.options.propertyCSS+' = '+objectSlide.options.slide.getStyle(objectSlide.options.propertyCSS))}});

		if (objectSlide.options.btns != null) objectSlide.options.btns.getChildren('a[href$='+objectSlide.options.listSlides[objectSlide.options.slideOn-1]+']').removeClass('activ');

		if (direction == 1) {
			if (objectSlide.options.slideOn < objectSlide.options.nbSlides) {
				objectSlide.options.slideToGo = objectSlide.options.slideOn+1;
		
				var toMove        = objectSlide.options.slideToGo - objectSlide.options.slideOn;
				var marginToSlide = slideMargin-(toMove*objectSlide.options.slideSize);
			} else if (objectSlide.options.slideOn == objectSlide.options.nbSlides) {//Boucle utilisée si le slide ne tourne pas en boucle et arrive à la fin
				objectSlide.options.slideToGo = 1;	
			
				var toMove        = objectSlide.options.slideToGo-1;
				var marginToSlide = toMove*objectSlide.options.slideSize;
			}
			
		} else if (direction == -1) {
			if (objectSlide.options.slideOn > 1) {
				objectSlide.options.slideToGo = objectSlide.options.slideOn-1;
			
				var toMove        = objectSlide.options.slideOn - objectSlide.options.slideToGo;
				var marginToSlide = slideMargin+(toMove*objectSlide.options.slideSize);
			} else if (direction == -1 && objectSlide.options.slideOn == 1) {//Boucle utilisée si le slide ne tourne pas en boucle et arrive au début
			 	objectSlide.options.slideToGo = objectSlide.options.nbSlides;
			
				var toMove        = objectSlide.options.slideToGo-1;
				var marginToSlide = -toMove*objectSlide.options.slideSize;
			}
			
		}
	
		//Le slide à afficher devient le slide visible
		objectSlide.options.slideOn = objectSlide.options.slideToGo;

		//Permettre le comportement de tourner en boucle sans arrêt
		if (objectSlide.options.boucle == 1) {
			marginToSlide = -objectSlide.options.slideSize;
			
			if (direction == 1 && objectSlide.options.slideToGo >= 3) {
				objectSlide.options.slides[0].dispose();
				objectSlide.options.slide.grab(objectSlide.options.slides[0]);
				objectSlide.options.slide.setStyle(objectSlide.options.propertyCSS,'0');
				objectSlide.options.slideOn--;//Permet de tourner en boucle en faisant rester le slideOn au même niveau
				slideMargin = 0;
			} else if (direction == -1 && objectSlide.options.slideToGo <= 1) {
				objectSlide.options.slides[objectSlide.options.nbSlides-1].dispose();
				objectSlide.options.slide.grab(objectSlide.options.slides[objectSlide.options.nbSlides-1],'top');
				objectSlide.options.slide.setStyle(objectSlide.options.propertyCSS,-(objectSlide.options.slideSize*2));
				objectSlide.options.slideOn++;//Permet de tourner en boucle en faisant rester le slideOn au même niveau
				slideMargin = -(objectSlide.options.slideSize*2);
			}
		
			objectSlide.options.slides     = objectSlide.options.slide.getChildren('div');
			objectSlide.options.listSlides = objectSlide.options.slides.get('id');
		}

		//Exécution du slide (propriété à modifier,position de départ,position d'arrivée
		//console.log('slideMargin = '+slideMargin+' - marginToSlide = '+marginToSlide);
		myTween.start(objectSlide.options.propertyCSS,slideMargin,marginToSlide);

		if (objectSlide.options.btns != null) objectSlide.options.btns.getChildren('a[href$='+objectSlide.options.listSlides[objectSlide.options.slideOn-1]+']').addClass('activ');
		
	},

	/**
	 * Function fade 
	 * 
	 * @description : Masque le slide actuel et affiche celui souhaité 
	 * @param :  direction = 1 -> suivant, direction = -1 -> précédent
	 * @access : public
	 * @return : void
	 * @date : 2010-04-01
	 * @author : François Guémard <f.guemard@hegyd.com>
	 */
	fade: function(direction,slideToGo){
	
		var objectSlide = this;
		var slideInTab  = objectSlide.options.slideOn-1;
		
		if (objectSlide.options.btns != null) objectSlide.options.btns.getChildren('a[href$='+objectSlide.options.listSlides[slideInTab]+']').removeClass('activ');
	
		if (objectSlide.options.slideOn == objectSlide.options.nbSlides) objectSlide.options.slideOn = 0;
		
		$(objectSlide.options.listSlides[slideInTab]).fade('out');
	
		if (direction == 1) {
			objectSlide.options.slides[0].dispose();
			objectSlide.options.slide.grab(objectSlide.options.slides[0],'bottom');
		} else if (direction == -1) {
			objectSlide.options.slides[objectSlide.options.nbSlides-1].dispose();
			objectSlide.options.slide.grab(objectSlide.options.slides[objectSlide.options.nbSlides-1],'top');
		}
		
		objectSlide.options.slides     = objectSlide.options.slide.getChildren('div');
		objectSlide.options.listSlides = objectSlide.options.slides.get('id');
	
		$(objectSlide.options.listSlides[slideInTab]).fade('in');
		
		if (objectSlide.options.btns != null) objectSlide.options.btns.getChildren('a[href$='+objectSlide.options.listSlides[slideInTab]+']').addClass('activ');
	
	},

	/**
	 * Function goToSlide 
	 * 
	 * @description : Lance la fonction slide pour afficher le slide passé en paramètre
	 * @param :  slide à afficher
	 * @access : public
	 * @return : void
	 * @date : 2010-04-01
	 * @author : François Guémard <f.guemard@hegyd.com>
	 */
	goToSlide: function(slide){

		var objectSlide = this;
		var slideOn     = objectSlide.options.listSlides[objectSlide.options.slideOn-1];
		var slideToGo   = slide;
		var direction   = 1;

		for (var i = 0;i < objectSlide.options.listSlides.length;i++) {
			if (slideOn == objectSlide.options.listSlides[i]) var posSlideOn = i;
			if (slideToGo == '#'+objectSlide.options.listSlides[i]) var posSlideToGo = i;
		}

		if (posSlideOn > posSlideToGo) direction = -1;

		while ('#'+slideOn != slideToGo) {
			
			objectSlide.animate({'objectSlide' : objectSlide,'direction' : direction,'action' : 2});

			slideOn = objectSlide.options.listSlides[objectSlide.options.slideOn-1];

		}

	}

});
