Ext.namespace('Ext.ux');

Ext.ux.Banner = (function(){

return{
	
		/* ******************* Variables modifiable ************************** */
		
		
		// Le ID du div qui contient la banniere
		divSource       : 'outer_carousal',
		
		// Url pour faire l'appel ajax (relative à la page ou absolu)
		ajaxUrl			: 'banner/ajax/banner_task.php',
		
		
		// Ajax: Valeur envoyer en post (Util pour différencier les commandes)
		ajaxPost		: 'getImages',		
		
		// Ajax: Le nombre d'image a recevoir (Probleme de performance après un certain nombre). -1 = Maximum possible
		ajaxNbImages    : 15,
		
		/* AFFICHAGE DES LOGOS */
		
		
		// Aleatoire ou non (true/false)
		randomize		: true,
		
		
		// Opacité des logos en mouseout (0 à 1)
		initialOpacity	: 1,
		
		
		// Opacité des logos en mouseover (0 à 1)
		endOpacity		: 1,
		
		
		// Marge entre les animations
		marginImg		: 10,
		
		
		// Pourcentage de reduction initial du logo
		resizeScale		: 1,
		
		
		// La durée de l'animation lors de l,agrandissement du logo
		resizeDuration	: .30,
		
		
		/* BANNIÈRE */
		
		
		// Direction de l'animation de départ: RightToLeft (rtl) ou LeftToRight (ltr)
		direction		: 'rtl',
		
		
		// Le nombre de pixel a deplacer a chaque mouvement (un taux trop haut aura un effet de saccade
		speed			: 1,
		
		
		// Le nombre de pixel a deplacer lorsque la souris est a l'extreme-droite/gauche (un taux trop haut aura un effet de saccade
		speedMax		: 6,
		
		
		/* TOOLTIPS */
		
		
		// Affiche le tooltip sur le mouseover de l'image
		showTooltip		: false,
		
		
		// Vitesse d'apparition de la tooltip
		tooltipDuration	: .3,				
	
		
		// Taille de la boite du tooltip (.1 à 1)
		tooltipBoxSize	: .7,
		
		
		// Taille minimum de la tooltip
		tooltipBoxSizeMin: 130,
	
	
		// Grosseur des fonts du tooltips
		tooltipFontSize	: 13,
		
		
	
	
	
		/* **************************************************************
		
			ATTENTION : NE PAS MODIFIER LES ÉLÉMENTS SOUS CETTE SECTION
		
		************************************************************** */
		
		
		images			: [],
		widthContainer	: 0,
		animeInterval	: 0,
		currentSpeed	: 1,
		arrClass		: Array('IMAGI_BANNER_img', 'IMAGI_BANNER_img_clone'),
		originalMargin	: 0,
		viewer			: Ext.get('IMAGI_BANNER_viewer'),
		isAnimated		: false,
		
		/*******************************************************************************
			FUNCTION: getImages
			ROLE	: Effectue l'appel ajax et retourne un tableau d'images
		********************************************************************************/
		getImages : function(){
			
			// URL,  WIDTH, HEIGHT, WEBSITE, TOOLTIP CONTENT
			this.viewer = Ext.get('IMAGI_BANNER_viewer');
			var images = [];
			Ext.Ajax.request({
				url 	: this.ajaxUrl,
				method 	: 'POST',
				params 	: {
					task : this.ajaxPost,
					nbImages : this.ajaxNbImages
				},
				scope 	: this,
				waitMsg : true,
				success:function(response,options){
					var responseData = Ext.decode(response.responseText);
					if(responseData.success == true){
						
						images = responseData.tabImage;
					}
					this.images = images;
					if(!Ext.isEmpty(this.images)){
						this.viewer.setStyle('background', 'none');
					}
					this.createBanner(); // Crée le bandeau et place les images
					this.currentSpeed = this.speed;
					this.launchAnim(); // Démarre l'animation
				}
			});
		},
		
		/*******************************************************************************
			FUNCTION: verifyImages
			ROLE	: Verifie que l'on a assez d'image ou rajoute des images prédéfinie
		********************************************************************************/
		verifyImages : function(){
			if(this.images.length < this.minImages){
				var nbMissingImg = this.minImages - this.images.length;
			}
		},
		
		/*******************************************************************************
			FUNCTION: verifyMargin
			ROLE	: Verifie que l'on a assez d'image pour remplir le viewer
		********************************************************************************/
		verifyMargin : function(){
			var widthContainerTemp = this.widthContainer + (this.marginImg*this.images.length)*2; // On calcul l'espace total occupé par le container
			if(widthContainerTemp <  this.viewer.getWidth(true))
			{
				var over = this.viewer.getWidth(true) - widthContainerTemp;
				var overPerImage = over/this.images.length;
				
				var originalWidth = 0;
				for(var i = 0; i < this.images.length; i++){
					originalWidth += this.images[i][1];
				}
				
				var marginToAdd = overPerImage / 2;
				this.marginImg = this.marginImg+marginToAdd;
			}
		},
		
		/*******************************************************************************
			FUNCTION: restartAnim
			ROLE	: Apres un effet, remet les events comme ils devraient etre
		********************************************************************************/
		restartAnim : function(){
			
			this.hideToolbox();
			for(var i = 0; i < this.arrClass.length; i++)
			{
				Ext.select('.'+this.arrClass[i]).addListener('mouseover', this.enlargeImage, this);
			}
			this.isAnimated = false;
		},
		
		/*******************************************************************************
			FUNCTION: enlargeImage
			ROLE	: Agrandit l'image
		********************************************************************************/
		enlargeImage : function(eventobj, htmlel, o){
			
			var tempEl			= Ext.get(htmlel); // On récupere l'element
			var elNaturalWidth	= tempEl.getAttribute('naturalWidth');
			var elNaturalHeight	= tempEl.getAttribute('naturalHeight');
			var elWidth			= tempEl.getWidth();
			var elHeight		= tempEl.getHeight();
			
			// Garde en memoire la marge pour la remettre au mem niveau lors du mouseout
			this.originalMargin = parseFloat(tempEl.getStyle('margin-left'));

			// Overlap les annimations à venir
			tempEl.syncFx();

			/* --------------- Traitement des events ------------------ */

			// On rajoute un event pour quand la souris quitte
			tempEl.addListener('mouseout', this.resizeImage, this);
			
			// On va enlever tout les event jusqu'à ce que celui la soit fini
			for(var i = 0; i < this.arrClass.length; i++)
			{
				Ext.select('.'+this.arrClass[i]).removeListener('mouseover', this.enlargeImage, this); // On supprime l'event de grossissement
			}
			
			/* --------------- Modification des dimensions de l'image ------------------ */
			
			/* Modifie la grosseur de l'image en changeant le margin pour donner un effet centré */
			var scaledMargin = this.originalMargin-((elNaturalWidth-elWidth)/2); 
			
			tempEl.setOpacity(this.endOpacity);
			
			tempEl.shift({
				width			: elNaturalWidth,
				height			: elNaturalHeight,
				'margin-right'	: scaledMargin-0.10,
				'margin-left'	: scaledMargin-0.10,
				duration		: this.resizeDuration,
				callback		: this.showToolbox,
				scope			: this
			});
		},
		
		/*******************************************************************************
			FUNCTION: resizeImage
			ROLE	: Rend ca taille originale a l'image
		********************************************************************************/
		resizeImage : function(eventobj, htmlel, o){
			
			var tempEl = Ext.get(htmlel);
			var widthTempImg = tempEl.getAttribute('naturalWidth')*(this.resizeScale);
			var heightTempImg = tempEl.getAttribute('naturalHeight')*(this.resizeScale);
			var widthAdded = tempEl.getAttribute('naturalWidth')-widthTempImg;
			
			tempEl.removeListener('mouseout', this.resizeImage, this);
			tempEl.syncFx();
			
			this.isAnimated = true; // Flag bloquant. Empeche le bandeau de se déplacer des que l'on quitte la zone. Attend la fin de l'animation
			
			tempEl.shift({
				width			: widthTempImg,
				height			: heightTempImg,
				'margin-right'	: this.originalMargin,
				'margin-left'	: this.originalMargin,
				duration		: this.resizeDuration,
				callback		: this.restartAnim,
				scope			: this
			});
			
			tempEl.setOpacity(this.initialOpacity, false);
		},
		
		/*******************************************************************************
			FUNCTION: showToolbox
			ROLE	: Affiche la toolbox
		********************************************************************************/
		showToolbox : function(htmlel){
			if(this.showTooltip)
			{
				var el 				= Ext.get(htmlel);
				var tooltipBox		= Ext.get('IMAGI_BANNER_tooltip');
				var elNaturalWidth	= el.getAttribute('naturalWidth');
				var elNaturalHeight = el.getAttribute('naturalHeight');
				var elWidth			= el.getWidth();
				var elHeight		= el.getHeight();
				var parent 			= el.parent('li');	
				var leftParent 		= parent.getX();

				//var scaledMargin	= this.originalMargin-((elNaturalWidth-elWidth)/2); 
				var tpWidth			= elNaturalWidth*this.tooltipBoxSize;
				
				if(tpWidth < this.tooltipBoxSizeMin){tpWidth = this.tooltipBoxSizeMin;}
				
				var diffWidth = 0;
				
				if(elNaturalWidth > tpWidth){
					diffWidth = (elNaturalWidth-tpWidth);
				}
				
				var tpLeft			= leftParent+((diffWidth+(this.originalMargin/2))/2);
				
				tooltipBox.setLeft(tpLeft);
				tooltipBox.setWidth(tpWidth);
				tooltipBox.setStyle({'font-size':this.tooltipFontSize+'px'});
				
				/* Set the text at the begenning in order to get the height with the text inside */
				
				var dh 				= Ext.DomHelper;
				dh.overwrite('IMAGI_BANNER_tooltip_text', this.images[el.getAttribute('posTab')][4]);
				
				tooltipBox.fadeIn({useDisplay:true,duration:this.tooltipDuration});
				
				/* Set the top after the composent is visible */
				var tpTop 	= (parent.getTop()-(elNaturalHeight*.15))-(tooltipBox.getHeight(true)/2);
				tooltipBox.setTop(tpTop);
			}
		},
		
		/*******************************************************************************
			FUNCTION: hideToolbox
			ROLE	: Efface la toolbox
		********************************************************************************/
		hideToolbox : function(eventobj, htmlel, o){
			Ext.get('IMAGI_BANNER_tooltip').fadeOut({useDisplay:true,duration:this.tooltipDuration});
		},
		
		/*******************************************************************************
			FUNCTION: addImagesEvent
			ROLE	: Ajoute les evenements sur les images
		********************************************************************************/
		addImagesEvent : function(){
			var i;
			for(i = 0; i < this.arrClass.length; i++)
			{
				var imgTemp = Ext.select('.'+this.arrClass[i]);
				
				/* Set the image opacity */
				
				imgTemp.setOpacity(this.initialOpacity, false);
				imgTemp.addListener('mouseover', this.enlargeImage, this); // Si on a la souris sur une image, on la grossi
				imgTemp.addListener('mouseover', this.pauseAnim, this); // Si on a la souris sur une image, on arrete le défilement
				imgTemp.addListener('mouseout', this.launchAnim, this); // Lorsqu'on quitte l'image, on recommence le defilement
				
			}
		},
		
		/*******************************************************************************
			FUNCTION: playBanner
			ROLE	: Crée le HTML pour la structure
		********************************************************************************/
		createBanner : function(){
			var i, widthTempImg, heightTempImg, temp, heightContainer;
			
			// On melange les images
			if(this.randomize === true){
				this.images.shuffle();
			}
			
			this.verifyImages(); //On verifie que l'on a un nombre suffisant d'images
			
			// On crée le container
			this.viewer.createChild({
				tag : 'ul',
				id	: 'IMAGI_BANNER_container',
				'class' : 'IMAGI_BANNER_movingDiv'
			});

			// On crée le clone
			this.viewer.createChild({
				tag : 'ul',
				id	: 'IMAGI_BANNER_clone',
				'class' : 'IMAGI_BANNER_movingDiv'
			});
			
			// On ajoute les images au container
			for(i = 0; i < this.images.length; i++){ // On doit verifier la grosseur du containeur avant de verifier la marge
				this.widthContainer += this.images[i][1]*(this.resizeScale);
			}
			
			this.verifyMargin(); // On verifie que les images prennent toute la page
			

			for(i = 0; i < this.images.length; i++){
				
				widthTempImg = this.images[i][1]*(this.resizeScale);
				heightTempImg = this.images[i][2]*(this.resizeScale);
				var li = Ext.get('IMAGI_BANNER_container').createChild({
					tag : 'li'
				});
				
				temp = li.createChild({
					tag : 'div',
					'class' : 'IMAGI_BANNER_wraptocenter'
				});
				
				temp.createChild({
					tag : 'span'
				});
				
				temp = temp.createChild({
					tag : 'a',
					href : this.images[i][3],
					'class' : 'IMAGI_BANNER_wrapper',
					target : '_self'//'_blank'
				});
				
				temp = temp.createChild({
					tag : 'img',
					src : this.images[i][0],
					'class' : 'IMAGI_BANNER_img', // Defini une classe pour récuperer la width plus tard
					style : 'margin-right: '+this.marginImg+'px; margin-left: '+this.marginImg+'px; width: '+widthTempImg+'px; height: '+heightTempImg+'px;',
					'posTab' : i
				});
				
				li.setWidth(widthTempImg+(this.marginImg*2));
				
				var li = Ext.get('IMAGI_BANNER_clone').createChild({
					tag : 'li'
				});
				
				temp = li.createChild({
					tag : 'div',
					'class' : 'IMAGI_BANNER_wraptocenter'
				});
				
				temp.createChild({
					tag : 'span'
				});
				
				temp =temp.createChild({
					tag : 'a',
					href : this.images[i][3],
					'class' : 'IMAGI_BANNER_wrapper',
					target : '_self'//'blank'
				});
				
				temp = temp.createChild({
					tag : 'img',
					src : this.images[i][0],
					'class' : 'IMAGI_BANNER_img_clone',
					style : 'margin-right: '+this.marginImg+'px; margin-left: '+this.marginImg+'px; width: '+widthTempImg+'px; height: '+heightTempImg+'px;',
					'posTab' : i
				});
				
				li.setWidth(widthTempImg+(this.marginImg*2));
			}
			
			heightContainer = this.viewer.getHeight(true);
			Ext.select('.IMAGI_BANNER_wrapper').setHeight(heightContainer);
			
			Ext.get(this.divSource).createChild({
				tag : 'div',
				id	: 'IMAGI_BANNER_controlToLeft',
				'class' : 'IMAGI_BANNER_controler'
			});
			Ext.get(this.divSource).createChild({
				tag : 'div',
				id	: 'IMAGI_BANNER_controlToRight',
				'class' : 'IMAGI_BANNER_controler'
			});
			
			var tooltip = Ext.getBody().createChild({
				tag : 'div',
				id	: 'IMAGI_BANNER_tooltip',
				'class' : 'IMAGI_BANNER_div',
				style : 'left: '+this.viewer.getLeft()+'px; top: '+(this.viewer.getTop())+'px;'
			});
			
			tooltip.createChild({
				tag : 'div',
				id	: 'IMAGI_BANNER_tooltip_text',
				'class' : 'IMAGI_BANNER_div'
			});
			tooltip.createChild({
				tag : 'div',
				id	: 'IMAGI_BANNER_tooltip_bg',
				'class' : 'IMAGI_BANNER_div'
			});
			
			/* Dois rester déclaré ici. les divs n'existe pas avant */
			var controlToRight = Ext.get('IMAGI_BANNER_controlToRight');
			var controlToLeft  = Ext.get('IMAGI_BANNER_controlToLeft');
			
			/* On va gerer les controles sur les bords du div */
			controlToRight.addListener('mouseover', function(){
				for(i = 0; i < this.arrClass.length; i++)
				{
					Ext.select('.'+this.arrClass[i]).removeListener('mouseover', this.pauseAnim, this); // On enleve l'evenement sur les images
				}
				this.pauseAnim(); // On arrete le defilement
				Ext.get('IMAGI_BANNER_tooltip').fadeOut({duration:this.duration, useDisplay:true});
				this.direction = 'ltr'; // On change de direction
				this.currentSpeed = this.speedMax;
				this.animeInterval = setInterval("Ext.ux.Banner.anime()", 10); // On accelere le defilement (3px par millisecondes)
				controlToRight.addClass('IMAGI_BANNER_controler_hover_right');
			}, this);
			controlToLeft.addListener('mouseover', function(){
				for(i = 0; i < this.arrClass.length; i++)
				{
					Ext.select('.'+this.arrClass[i]).removeListener('mouseover', this.pauseAnim, this);
				}
				this.pauseAnim();
				Ext.get('IMAGI_BANNER_tooltip').fadeOut({duration:this.duration, useDisplay:true});
				this.direction = 'rtl';
				this.currentSpeed = this.speedMax;
				this.animeInterval = setInterval("Ext.ux.Banner.anime()", 10);
				controlToLeft.addClass('IMAGI_BANNER_controler_hover_left');
			
			}, this);
			
			controlToRight.addListener('mouseout', function(){
				for(i = 0; i < this.arrClass.length; i++)
				{
					Ext.select('.'+this.arrClass[i]).addListener('mouseover', this.pauseAnim, this);
				}
				this.pauseAnim();
				this.currentSpeed = this.speed; 
				this.animeInterval = setInterval("Ext.ux.Banner.anime()", 10);
				controlToRight.removeClass('IMAGI_BANNER_controler_hover_right');
			}, this);
			
			controlToLeft.addListener('mouseout', function(){
				for(i = 0; i < this.arrClass.length; i++)
				{
					Ext.select('.'+this.arrClass[i]).addListener('mouseover', this.pauseAnim, this);
				}
				this.pauseAnim();
				this.currentSpeed = this.speed; 
				this.animeInterval = setInterval("Ext.ux.Banner.anime()", 10);
				controlToLeft.removeClass('IMAGI_BANNER_controler_hover_left');
			}, this);

			this.widthContainer += 1+(this.marginImg*this.images.length)*2; //*2 A cause de la marge gauche et droit
		
			// On place le clone a sa place initiale
			var cloneName = Ext.get('IMAGI_BANNER_clone');
			
			cloneName.setWidth(this.widthContainer);
			cloneName.setLeft(this.widthContainer); 
			
			Ext.get('IMAGI_BANNER_container').setWidth(this.widthContainer);
			
			this.addImagesEvent(); // On prépare les evenements sur les images
		},
	
		/*******************************************************************************
			FUNCTION: anime
			ROLE	: Permet d'animer la banniere
		********************************************************************************/
		anime : function(){
			
			if(!this.isAnimated)
			{
				
				// On recupere les positions
				var containerName = Ext.get('IMAGI_BANNER_container');
				var cloneName	  = Ext.get('IMAGI_BANNER_clone');
				var leftContainer	= containerName.getLeft(true);
				var rightContainer	= containerName.getRight(true);
				var leftClone		= cloneName.getLeft(true);
				var rightClone		= cloneName.getRight(true);
				var viewerPos		= this.viewer.getPadding('l');
				
				if(this.direction == 'rtl'){
					// Si le container est sorti
					if(rightClone <= viewerPos){
						cloneName.setLeft(leftContainer+cloneName.getWidth(true));
					}
						
					else{
						if(rightContainer <= viewerPos){
							containerName.setLeft(leftClone+containerName.getWidth(true));
						}
						else{
							// On deplace les deux
							containerName.setLeft(leftContainer-this.currentSpeed);
							cloneName.setLeft(leftClone-this.currentSpeed);
						}
					}
				}
				else
				{
					// Si le clone est sorti
					if(leftClone >= this.viewer.getWidth(true)){
						cloneName.setLeft(leftContainer-cloneName.getWidth(true));
					}
					else
					{	
						// Si la gauche du container est sortie
						if(leftContainer >= this.viewer.getWidth(true)){
							containerName.setLeft(leftClone-containerName.getWidth(true));
						}
						else
						{
							// On deplace tout
							containerName.setLeft(leftContainer+this.currentSpeed);
							cloneName.setLeft(leftClone+this.currentSpeed);
						}
					}
				}
			}
		},
		
		/*******************************************************************************
			FUNCTION: pauseAnim
			ROLE	: Verifie si l'animation est en cours et si oui, l'arrete
		********************************************************************************/
		pauseAnim : function(){
			if(this.animeInterval && this.animInterval !== 0){
				clearInterval(this.animeInterval);
			}
		},
		
		/*******************************************************************************
			FUNCTION: launchAnim
			ROLE	: Fait rouler l'animation
		********************************************************************************/
		launchAnim : function(){
			this.pauseAnim();
			this.animeInterval = setInterval("Ext.ux.Banner.anime()", 10);
		},

		init: function(){
			
			// Crée le viewer
			Ext.get(this.divSource).createChild({
			    tag : 'div',
				id : 'IMAGI_BANNER_viewer'
			});
			this.images = this.getImages(); // Recupere les images
		}
	};
	
})();

Ext.onReady(Ext.ux.Banner.init, Ext.ux.Banner);

// Prototype pour mélanger un tableau
Array.prototype.shuffle = function (){ 
        for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i, 10), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp){}
};



