// Classe d'effets en Javascript
// (IE, Firefox, Opera)
// Eric Quillévéré 2008

// !!! Pour les affichages déroulants : ne pas oublier overflow:hidden;
// Pour arrêter l'effet en cours : clearTimeout(objet.timeoutEffet);
// Pour déclencher la routine de fin : objet.fonctionApresFin();

// new Effet(objetFenetre.id, {effet:'Progressif', typeAffichage:0,vitesse:40,delaiDemarrage: 100, fonctionFin:function(){} });
// new Effet (objFenetre.id, {effet:'Deplace', destiX:PositionX, destiY:PositionY, vitesse:12, ralentiFin:true, fonctionFin:function(){} });

/*-jsl:import 0-specifique.js */
/*-jsl:import 1-objets.js */
/*jsl:import divers.js */


var Effets = {}; // On crée une variable globale du nom du projet 
Effets.listeInstances = new Array(); // Liste des instances


// --> Utiliser la propriété visible pour savoir si l'objet est visible au demarrage de l'effet (pour faire un focus par exemple).
function Effet(p_nomObjet, listeParametres) 
	{
	if (arguments.length==2)
		new Effets.instance(p_nomObjet, listeParametres) ;
	else
		{
		alert('appel obsolète ' + arguments[1]);
		// Fonction permettant de rester compatible avec l'ancienne version
		var params=Array();
		params['effet']=arguments[1];
		params['delaiDemarrage']=arguments[3];
		params['fonctionFin']=arguments[4];
		if (params['effet']=='Progressif')
			{
			params['typeAffichage']=arguments[2][0];
			params['vitesse']=arguments[2][1];
			params['opt_opaciteMini']=arguments[2][2];
			params['opt_opaciteMaxi']=arguments[2][3];
			}
		else if (params['effet']=='Deplace')
			{
			params['destiX']=arguments[2][0];
			params['destiY']=arguments[2][1];
			params['vitesse']=arguments[2][2];
			params['ralentiFin']=arguments[2][3];
			}
		else if (params['effet']=='Deroulant')
			{
			params['typeAffichage']=arguments[2][0];
			params['vitesse']=arguments[2][1];
			params['limiteH']=arguments[2][2];
			params['limiteL']=arguments[2][3];
			params['padding']=arguments[2][4];
			params['cacherApres']=arguments[2][5];
			params['opt_intervale']=arguments[2][6];
			}
		else if (params['effet']=='DeplaceZoom')
			{
			params['sourceX']=arguments[2][0];
			params['sourceY']=arguments[2][1];
			params['sourceL']=arguments[2][2];
			params['sourceH']=arguments[2][3];
			params['destiX']=arguments[2][4];
			params['destiY']=arguments[2][5];
			params['destiL']=arguments[2][6];
			params['destiH']=arguments[2][7];
			}
		new Effets.instance(p_nomObjet, params) ;
		}
	
	}


Effets.instance = function(p_nomObjet, listeParametres)//, delaiAvantDemarrage, OPT_fonctionApresFin)  
	{  
	/** Instance **/
	this.id = Effets.listeInstances.length; // Numero d'instance actuel (pour setTimeout)
	Effets.listeInstances[this.id]=this; // Affecte l'objet a l'instance
	if (!listeParametres['delaiDemarrage'])
		listeParametres['delaiDemarrage']=0;

	this.nomEffet=listeParametres['effet'];
	this.p=listeParametres;

	// Evalue la durée de l'effet pour éviter de ramer
	this.nbAppels=0;
	
	// Récupère l'objet en paramètre, selon le navigateur
	if (document.getElementById) 
		this.Objet= document.getElementById(p_nomObjet);
	else if (document.all)  
		this.Objet=document.all[p_nomObjet];

	// Recherche si l'objet est visible
	if (this.Objet)
		{
		this.estVisible=objet_estVisible(this.Objet); 

		// Memorise la taille actuelle
		this.largeur=	this.Objet.offsetWidth;		
		this.hauteur=	this.Objet.offsetHeight;		
		this.posGauche= this.Objet.style.left;		
		this.posHaut= 	this.Objet.offsetTop;		
		
		//Permet d'appeler la méthode de fin depuis l'extérieur de l'objet
		this.Objet.fonctionApresFin=listeParametres['fonctionFin'];
		}
	else
		this.estVisible=false; 
	this.Demarrage();  
	};

// Methodes publiques de maClasse  
Effets.instance.prototype = 
	{  
	//Initialisation, methode apellée a l'instanciation de l'objet 
	Demarrage: function()  
		{  
		if (this.p['delaiDemarrage']===0)
			this.Effet_BranchementFonction(); 
		else
			// Demarrage retarde
			setTimeout('Effets.listeInstances['+ this.id + '].Effet_BranchementFonction();', this.p['delaiDemarrage']);
		},
		
	Effet_Fin:function()
		{
		// Fin de l'effet : appelle une fonction si demandé
		if (this.p['fonctionFin'])
			{
			if (this.Objet) this.Objet.fonctionApresFin=null;
			this.p['fonctionFin']();
			this.p['fonctionFin']=null;
			}
		} ,

	Effet_BranchementFonction:function()
		{
		if (this.Objet)
			{
			switch(this.nomEffet)
				{
				case 'Progressif':
					this.Effet_AffichageProgressif();break;
					
				case 'Deroulant':
					this.Effet_AffichageDeroulant();break;					
					
 				case 'DeplaceZoom':
					this.Effet_AffichageDeplaceZoom ();break;				
					
				case 'Deplace':
					this.Effet_Deplace();break;		

				case 'Opacite':
					this.Effet_AffichageOpacite (this.p[0]);break;						
					
				default:
					alert('Nom d\'effet inconnu : ' + this.nomEffet);break;
				}
			}
		},


	// Affiche un objet en le déroulant

	// typeAffichage :
	//	0 :  du haut vers le bas
	//	1 : du bas vers le haut
	// vitesse : delai entre deux evolutions de la taille
	// padding : taille du padding (border+padding haut/bas)
	Effet_AffichageDeroulant:function()
		{
		// Paramètres affichage deroulant
		if (!this.p['opt_intervalle']) this.p['opt_intervalle']=40;
		if (!this.p['limiteL']) this.p['limiteL']=0;

		this.intervalle=this.p['opt_intervalle']; // Intervalle de rappel
		this.AfficheElement();
		this.Effet_AffichageDeroulant_Appels (); 
		},	

			
	Effet_AffichageDeroulant_Appels:function()
		{
		this.GereTemps();
		var hauteurActu=this.Objet.offsetHeight;
		var largeurActu=this.Objet.offsetWidth;
		var finAppel=false;
		
		if (this.p['typeAffichage']===0)
			{
			if (hauteurActu<this.p['limiteH']) hauteurActu+=this.p['vitesse'];
			if (largeurActu<this.p['limiteL']) largeurActu+=this.p['vitesse'];
			
			if (hauteurActu>this.p['limiteH'])	hauteurActu=this.p['limiteH'];
			if (largeurActu>this.p['limiteL']) largeurActu=this.p['limiteL'];
			
			}
			
		else if (this.p['typeAffichage']==1)
			{
			if (hauteurActu>this.p['limiteH']) hauteurActu-=this.p['vitesse'];
			if (largeurActu>this.p['limiteL']) largeurActu-=this.p['vitesse'];
			
			if (hauteurActu<this.p['limiteH'])	hauteurActu=this.p['limiteH'];
			if (largeurActu<this.p['limiteL']) largeurActu=this.p['limiteL'];
			}

		if 	((this.p['limiteH']===0 || (this.p['limiteH']!==0 && hauteurActu==this.p['limiteH'])) &&
			(this.p['limiteL']===0 || (this.p['limiteL']!==0 && largeurActu==this.p['limiteL'])))
			finAppel=true;

		
		if (this.Objet)
			{
			this.Objet.style.height=(hauteurActu-this.p['padding']) + 'px';
			if (this.p['limiteL']!==0) this.Objet.style.width=(largeurActu-this.p['padding']) + 'px';
			}

		if (this.Objet && !finAppel)
			{
			// Permet d'appeler la présente routine après n millisec
			this.Objet.timeoutEffet=setTimeout('Effets.listeInstances['+ this.id + '].Effet_AffichageDeroulant_Appels();', this.intervalle);
			}
		else
			{
			if (this.p['cacherApres']) 
				this.Objet.style.display='none';
			this.Effet_Fin();
			}
		},
			
	// Affiche un objet en le déroulant

	// typeAffichage :
	//	0 :  du haut vers le bas
	//	1 : du bas vers le haut
	// vitesse : delai entre deux evolutions de la taille
	// 	
	Effet_AffichageDeplaceZoom:function()
		{
		// Paramètres affichage déroulant
		this.Objet.style.position = 'absolute';
		//this.Objet.style.zIndex=100;
		this.intervalle=50;
		this.nbEtapes=10;
		this.agrandX=(this.p['destiL']-this.p['sourceL'])/this.nbEtapes;
		this.agrandY=(this.p['destiH']-this.p['sourceH'])/this.nbEtapes;
		this.deplX=(this.p['destiX']-this.p['sourceX'])/this.nbEtapes;
		this.deplY=(this.p['destiY']-this.p['sourceY'])/this.nbEtapes;

		this.Effet_AffichageDeplaceZoom_Appels(); 
		},	

			
	Effet_AffichageDeplaceZoom_Appels:function()
		{
		// Fixe la position et la taille d'origine
		this.Objet.style.left=this.p['sourceX'] + 'px';
		this.Objet.style.top=this.p['sourceY'] + 'px';
		this.Objet.style.height=this.p['sourceH'] + 'px';
		this.Objet.style.width=this.p['sourceL'] + 'px';
		
		this.nbEtapes--;
		if (this.GereTemps()) this.nbEtapes=-1;
		if (this.nbEtapes>=0)
			{
			this.p['sourceL']+=this.agrandX;
			this.p['sourceH']+=this.agrandY;
			this.p['sourceX']+=this.deplX;
			this.p['sourceY']+=this.deplY;
			
			// Permet d'appeler la présente routine après n millisec
			setTimeout('Effets.listeInstances['+ this.id + '].Effet_AffichageDeplaceZoom_Appels();', this.intervalle);
			}
		else
			{
			this.Objet.style.left=this.p['destiX'] + 'px';
			this.Objet.style.top=this.p['destiY'] + 'px';
			this.Objet.style.height=this.p['destiH'] + 'px';
			this.Objet.style.width=this.p['destiL'] + 'px';			
			this.Effet_Fin();
			}
		},			


	// Affiche/cache un objet progressivement

	// typeAffichage :
	//	0 : masquer progressivement
	//	1 : afficher progressivement
	// 	2 : inverser (affiche progressivement si objet cache ou cache progressivement si objet visible)
	// vitesse : delai entre deux evolutions de l'opacite
	// [int] valeurMini : valeur a atteindre au minimum 
	// [int] valeurMaxi : valeur a atteindre au maximum 
	Effet_AffichageProgressif:function()
		{
		// Paramètres : typeAffichage, vitesse, opaciteMini, opaciteMaxi
		if (!this.p['opt_opaciteMini']) this.p['opt_opaciteMini']=0;
		if (!this.p['opt_opaciteMaxi']) this.p['opt_opaciteMaxi']=100;
		
		// Paramètres affichage progressif
		this.intervalle=100;
		this.OpaciteActu=0; // Opacite actuelle
		this.OpaciteIncrement=0; // Increment/decrement de l'opacite
		this.demandeAffichage=true; // Demande-t-on l'affichage ou le masquage ?
		var continuer=true;

		switch (this.p['typeAffichage'])
			{
			case 0:
				// Si déjà caché, ne sert a rien de faire un effet
				if (!this.estVisible)
					continuer=false;
				else
					this.demandeAffichage=false;
				break;					
				
			case 1:
				this.demandeAffichage=true;
				break;
			
			case 2: // Inverser
				if (!this.estVisible)
					{
					//this.Effet_Opacite_Fixe (30); // Opacite au demarrage
					objet_FixeOpacite(this.Objet, 30);
					this.demandeAffichage=true;
					}
				else 
					this.demandeAffichage=false;
				break;
				
			default: break;
			}

		if (continuer)
			{
			
			this.AfficheElement();
			this.valeurMini=this.p['opt_opaciteMini']; // Valeur mini
			this.valeurMaxi=this.p['opt_opaciteMaxi']; // Valeur maxi
			
			this.estVisible=this.demandeAffichage;
			
			if (!this.demandeAffichage)
				{
				this.OpaciteActu=100; 
				this.OpaciteIncrement=-this.p['vitesse'];
				}
			else
				{
				this.OpaciteActu=0;
				this.OpaciteIncrement=this.p['vitesse'];
				}
			
			// Corrige un bug de transparence sur IE si pas de hauteur definie
			//if (ie)
				//this.Objet.style.height='auto';
				//this.Objet.style.setAttribute('cssText','zoom:1');

			this.Effet_AffichageProgressif_Appels (); 
			}
		},
			
			
	Effet_AffichageProgressif_Appels:function()
		{
		if (this.Objet)
			{
			
			if (this.Objet.style.visibility!='hidden' )
				{
				if (this.GereTemps())
					this.Effet_AffichageProgressif_Fin(this.demandeAffichage);
				else
					{
					if (this.Effet_Opacite_Modif(this.OpaciteIncrement, this.valeurMini, this.valeurMaxi))
						// Permet d'appeler la présente routine après n millisec
						setTimeout('Effets.listeInstances['+ this.id + '].Effet_AffichageProgressif_Appels();', this.intervalle);
					else
						this.Effet_AffichageProgressif_Fin(this.demandeAffichage);
					}
				}
			}
		else
			this.Effet_AffichageProgressif_Fin(this.demandeAffichage);
		}	,	
			
	Effet_AffichageProgressif_Fin:function(afficherObjet) 
		{
		if (this.Objet)
			{
			if (!afficherObjet)
				{
				// Cache définivement
				this.Objet.style.display = "none"; // invisible;
				this.Objet.style.visibility='hidden';
				}
			else
				// Affiche definitivement
				//this.Effet_Opacite_Fixe (this.valeurMaxi);
				objet_FixeOpacite(this.Objet, this.vakeurMaxi);
			this.Effet_Fin();				
			}
			
		},			
			

	// Opacité
	Effet_AffichageOpacite:function(valOpacite)
		{
		if (this.Objet)
			//this.Effet_Opacite_Fixe (valOpacite);
			objet_FixeOpacite(this.Objet, valOpacite);

		this.Effet_Fin();		
		}	, 		
			
			
	// Enlève l'opcacité de la bulle en plusieurs etapes
	Effet_Opacite_Modif:function(Increment, valeurMini, valeurMaxi)
		{
		if (ie5 || ie6 || ie7 || ffox || opera )
			{
			var autreIncrementPossible=true;
			this.OpaciteActu+=Increment;
			
			if(this.OpaciteActu<valeurMini) // 0
				{
				this.OpaciteActu=valeurMini;
				autreIncrementPossible=false;
				}
			else if (this.OpaciteActu>valeurMaxi) // 100
				{
				this.OpaciteActu=valeurMaxi;
				autreIncrementPossible=false;
				}

			if (this.Objet)	
				{
				//this.Effet_Opacite_Fixe (this.OpaciteActu);
				objet_FixeOpacite(this.Objet, this.OpaciteActu);
				return autreIncrementPossible;
				}
			else
				return false; // Objet non trouvé
			}
		else
			return false; // Navigateur non géré
		}   ,
		
		
		
	// Déplace un objet

	// posX : posX destination
	// posY : posY destination
	// vitesse : délai entre deux deplacements
	// 	
	Effet_Deplace:function()
		{
		this.intervalle=10;
		// Détermine le sens du déplacement
		var posXActu=this.Objet.offsetLeft;
		var posYActu=this.Objet.offsetTop;		

		if (this.p['destiX']===null) this.gereX=false; else this.gereX=true;
		if (this.p['destiY']===null) this.gereY=false; else this.gereY=true;

		if (posXActu<this.p['destiX']  && this.gereX) this.sensX=1; else this.sensX=-1;
		if (posYActu<this.p['destiY']  && this.gereY) this.sensY=1; else this.sensY=-1;
		this.Effet_Deplace_Appels (); 
		//alert(posXActu + '/' + posYActu + ' vers ' + this.p['destiX'] + '/' + this.p['destiY']);
		},
		
		
	Effet_Deplace_Appels:function()
		{
		var posXActu=this.Objet.offsetLeft;
		var posYActu=this.Objet.offsetTop;


		if (this.GereTemps())
			{
			posXActu=this.p['destiX'];
			posYActu=this.p['destiY'];
			}
		else
			{
			if (this.p['estVariable'])
				{
				var distance=Math.max(Math.abs(posXActu-this.p['destiX']), Math.abs(posYActu-this.p['destiY']));
				//if (!confirm(distance +' et ('+ Math.pow(this.p['vitesse']-1,2) + '/' +  Math.pow(this.p['vitesse'],2) + '), dept:'+ this.p['vitesse'])) return;
				
				var ContinueCalcul=true;
				var LimiteDeptUn=12; // Limite pour le déplacement de 1 pixel
				while (ContinueCalcul && this.p['vitesse']>1)
					{
					if ((distance>Math.pow(this.p['vitesse']-1,2)+LimiteDeptUn) && (distance<Math.pow(this.p['vitesse'],2)+LimiteDeptUn) ||
						distance<Math.pow(this.p['vitesse']-1,2)+LimiteDeptUn) 
						this.p['vitesse']--;
					else
						ContinueCalcul=false;
					}
				}
			
			if (this.gereX) posXActu=posXActu+ (this.p['vitesse']*this.sensX);
			if (this.gereY) posYActu=posYActu+ (this.p['vitesse']*this.sensY);
			}
			
		var finAppelX=false;
		var finAppelY=false;
		
	
		if (this.gereX)
			{
			if ((posXActu>=this.p['destiX'] && this.sensX==1) || (posXActu<=this.p['destiX'] && this.sensX==-1))
				{
				posXActu=this.p['destiX'];
				finAppelX=true;
				}
			}
		else
			finAppelX=true;

			
		if (this.gereY)
			{
			if ((posYActu>=this.p['destiY'] && this.sensY==1) || (posYActu<=this.p['destiY'] && this.sensY==-1))
				{
				posYActu=this.p['destiY'];
				finAppelY=true;
				}
			}
		else
			finAppelY=true;

				
				
		if (this.Objet)
			{
			if (this.gereX) this.Objet.style.left=posXActu + 'px';
			if (this.gereY) this.Objet.style.top =posYActu+ 'px';
			}
			
		if (this.Objet && ((!finAppelX || !finAppelY)))
			{
			// Permet d'appeler la routine après n millisec
			//if (confirm('rappel deplace, effet id ' + this.id + ' - Objet ' + this.Objet.id))
			setTimeout('Effets.listeInstances['+ this.id + '].Effet_Deplace_Appels();', this.intervalle);
			}
		else
			this.Effet_Fin();
		}		,	
			
	AfficheElement:function()	
		{
		this.Objet.style.visibility='visible';
		if (this.Objet.style.display==='none' || this.Objet.style.display==='')
			this.Objet.style.display = 'block'; // visible		
		},
		
	// Gestion pour éviter de ramer
	// Renvoie vrai si doit accélérer
	GereTemps:function()
		{
		//return false;
		this.nbAppels++;
		var dateHeure=new Date();
		if (this.nbAppels==1)
			{
			this.debutEffet=dateHeure.getTime();
			//this.effetTxt=this.nomEffet+'\nDelai : '+this.p['delaiDemarrage']+'\n';
			return false;
			}
		else
			{
			var dureeAppels=dateHeure.getTime()-this.debutEffet;
			var moyAppels=dureeAppels/(this.nbAppels-1);
			//this.effetTxt+= ((this.nbAppels-1) + '. ' +this.intervalle + ' / '+ dureeAppels + ' moy : ' + moyAppels) + '\n';
			if (moyAppels>10*this.intervalle)
				return true;
			else
				return false;
			}
		}
	}; 