//#16.00.04.00 WDAnim.js
//VersionVI: 30A160057k
// Le seul support technique disponible pour cette librairie est
// accessible a travers le service "Assistance Directe".

function WDAnim(pfSetProp,nValDebut,nValFin,nType,nCourbe,nDuree,sAliasChamp)
{
	if(pfSetProp!==undefined)
	{
		// Notifie le champ du debut de l'animation
		if(sAliasChamp&&(typeof WDChamp!="undefined"))
		{
			this.m_sAliasChamp=sAliasChamp;
			AppelMethodeChampPtr(this.m_sAliasChamp,WDChamp.prototype.AnimationDebut,[this]);
		}

		this.m_pfSetProp=pfSetProp;
		this.m_nValDebut=nValDebut;
		this.m_nValDelta=nValFin-nValDebut;
		this.m_nDebut=(new Date()).getTime();
		// Centieme de secondes => millisecondes
		this.m_nType=nType;
		switch (nCourbe)
		{
		case this.ms_nCourbeLineaire:
			this.dCourbe = this.dCourbeLineaire;
			break;
		case this.ms_nCourbeAccelere:
			this.dCourbe = this.dCourbeAccelere;
			break;
		default:
		case this.ms_nCourbeDecelere:
			this.dCourbe = this.dCourbeDecelere;
			break;
		}
		this.m_nDuree=nDuree*10;
		this.m_bFini=false;
		var oThis=this;
		this.m_pfCallBack=function() { oThis.vMaj(false); }
		// Premiere animation
		// Note cette fonction est surchargable dans les classes derivees (!!!)
		// Donc il faut bien faire attention d'appeller le constructeur en dernier dans les constructeurs derives
		this.vMaj(true);
	}
};

WDAnim.prototype.ms_nCourbeLineaire=0;
WDAnim.prototype.ms_nCourbeAccelere=1;
WDAnim.prototype.ms_nCourbeDecelere=2;
WDAnim.prototype.ms_nPeriodeMs=25;

// bForceNonFini : indique qu'il faut continuer l'animation (pour les animations avec des sous animations)
WDAnim.prototype.vMaj=function vMaj(bForceNonFini)
{
	// Calcule l'avancement
	var nTemps=(new Date()).getTime()-this.m_nDebut;
	var dAvancement=Math.min(1,nTemps/this.m_nDuree);
	this._Maj(dAvancement);

	// Si on n'est pas arrive a la fin
	if((nTemps<this.m_nDuree)||bForceNonFini)
	{
		// Toutes les 25ms ou le temps restant
		var nTimer=Math.min(this.ms_nPeriodeMs,this.m_nDuree-nTemps);
		this.m_nTimeout=setTimeout(this.m_pfCallBack,nTimer);
	}
	else
	{
		// Indique que l'animation est finie
		this.vFin();
	}
};

// Effectue le dessin
WDAnim.prototype._Maj = function _Maj (dAvancement)
{
	// Calcule la valeur et l'affiche
	if(this.m_pfSetProp)
	{
		var nVal = this.m_nValDebut + this.dCourbe(dAvancement) * this.m_nValDelta;
		this.m_pfSetProp(nVal);
	}
};

// Annule l'animation
// Ne met PAS dans l'etat final
WDAnim.prototype.vAnnule=function vAnnule()
{
	// Annule le timeout
	clearTimeout(this.m_nTimeout);
	delete this.m_nTimeout;

	// Fin de l'animation
	this.vFin();
};

// Marque la fin de l'animation
WDAnim.prototype.vFin=function vFin()
{
	// Memorise que l'animation est finie
	this.m_bFini=true;
	delete this.m_nTimeout;

	// Notifie le champ de la fin de l'animation (si le champ existe)
	if(this.m_sAliasChamp)
	{
		AppelMethodeChampPtr(this.m_sAliasChamp,WDChamp.prototype.AnimationFin,[this]);
	}
};

WDAnim.prototype.bFini=function bFini()
{
	return this.m_bFini;
};

WDAnim.prototype.dCourbeLineaire = function dCourbeLineaire (dAvancement)
{
	return dAvancement;
};
WDAnim.prototype.dCourbeAccelere = function dCourbeAccelere (dAvancement)
{
	return Math.sin(Math.PI / 2 * dAvancement);
};
WDAnim.prototype.dCourbeDecelere = function dCourbeDecelere (dAvancement)
{
	return 1 - Math.cos(Math.PI / 2 * dAvancement);
};

function AnimationJoueSurProprieteChamp(nValDebut,nValFin,nDuree,nCourbe,pfSetProp,sAliasChamp)
{
	var nType=0;
	return new WDAnim(pfSetProp,nValDebut,nValFin,nType,nCourbe,nDuree,sAliasChamp);
};

function WDAnimSurImage(oBaliseImg,sImageDebut,nOpaciteDebut,nType,nCourbe,nDuree,sImageFin,sAliasChamp)
{
	if(oBaliseImg!==undefined)
	{
		this.m_oBaliseImg=oBaliseImg;
		this.m_nOpaciteDebut=nOpaciteDebut;

		this.m_oDiv=document.createElement("div");
		this.SetSuperposable(this.m_oDiv);
		this.m_oDiv.style.overflow="hidden";
		this.AjoutFrere(this.m_oDiv);
		this.m_nX=this.GetX(oBaliseImg);
		this.m_nY=this.GetY(oBaliseImg);
		this.m_nLargeur=this.GetLargeur(oBaliseImg);
		this.m_nHauteur=this.GetHauteur(oBaliseImg);
		this.SetX(this.m_oDiv,this.m_nX);
		this.SetY(this.m_oDiv,this.m_nY);
		this.SetLargeur(this.m_oDiv,this.m_nLargeur);
		this.SetHauteur(this.m_oDiv,this.m_nHauteur);
		this.m_oBaliseImgTemp=this.oAjoutImageTemp(oBaliseImg,sImageDebut,nOpaciteDebut,nType,this.bImageTempFrere(nType));
		// Tableau des animations encore actives
		this.m_oBaliseImgTempFin=null;
		this.m_sVisibilite=this.GetVisibilite(oBaliseImg);
		if(this.b2Image(nType))
		{
			this.m_oBaliseImgTempFin=this.oAjoutImageTemp(oBaliseImg,sImageFin,nOpaciteDebut,nType);
			this.SetVisibilite(oBaliseImg,"hidden");
		}
		if(this.ms_nTypeFondu==nType)
		{
			this.SetOpacite(oBaliseImg,0);
		}

		// Appel de la classe de base (lance l'animation)
		WDAnim.prototype.constructor.apply(this,[this._fGetAnimFonction(nType),0,this.ms_nAvancementMax,nType,nCourbe,nDuree,sAliasChamp]);
	}
};

WDAnimSurImage.prototype=new WDAnim();
WDAnimSurImage.prototype.constructor=WDAnimSurImage;

WDAnimSurImage.prototype.ms_nAvancementMax=1000;
WDAnimSurImage.prototype.ms_nTypeFondu=1;
WDAnimSurImage.prototype.ms_nTypeBalayageBas=2;
WDAnimSurImage.prototype.ms_nTypeBalayageHaut=3;
WDAnimSurImage.prototype.ms_nTypeBalayageDroite=4;
WDAnimSurImage.prototype.ms_nTypeBalayageGauche=5;
WDAnimSurImage.prototype.ms_nTypeRecouvrementHaut=6;
WDAnimSurImage.prototype.ms_nTypeRecouvrementBas=7;
WDAnimSurImage.prototype.ms_nTypeRecouvrementGauche=8;
WDAnimSurImage.prototype.ms_nTypeRecouvrementDroite=9;
WDAnimSurImage.prototype.ms_nTypeRecouvrement=10;
WDAnimSurImage.prototype.ms_nTypeRecouvrementZoom=11;
WDAnimSurImage.prototype.ms_nTypeDecouvrement=12;
WDAnimSurImage.prototype.ms_nTypeDecouvrementZoom=13;
WDAnimSurImage.prototype.ms_tabAnimations = [];

// Les fonctions d'animation

WDAnimSurImage.prototype._fGetAnimFonction=function _fGetAnimFonction(nType)
{
	// Note : on ne fait pas une closure, on manipulera donc la fonction actuelle (et pas la fonction de meme nom au moment de l'appel)
	// mais normalement elles ne changent pas
	switch(nType)
	{
		case this.ms_nTypeFondu:
			return this._AnimFondu;
		case this.ms_nTypeBalayageHaut:
			return this._AnimBalayageHaut;
		case this.ms_nTypeBalayageBas:
			return this._AnimBalayageBas;
		case this.ms_nTypeRecouvrementHaut:
			return this._AnimRecouvrementHaut;
		case this.ms_nTypeRecouvrementBas:
			return this._AnimRecouvrementBas;
		case this.ms_nTypeBalayageGauche:
			return this._AnimBalayageGauche;
		case this.ms_nTypeBalayageDroite:
			return this._AnimBalayageDroite;
		case this.ms_nTypeRecouvrementGauche:
			return this._AnimRecouvrementGauche;
		case this.ms_nTypeRecouvrementDroite:
			return this._AnimRecouvrementDroite;
		case this.ms_nTypeRecouvrement:
			return this._AnimRecouvrement;
		case this.ms_nTypeRecouvrementZoom:
			return this._AnimRecouvrementZoom;
		case this.ms_nTypeDecouvrement:
			return this._AnimDecouvrement;
		case this.ms_nTypeDecouvrementZoom:
			return this._AnimDecouvrementZoom;
		default:
			return undefined;
	}
};

WDAnimSurImage.prototype._AnimFondu=function _AnimFondu(nAvancement)
{
	this.SetOpacite(this.m_oBaliseImg,this.__nAvancement(nAvancement,this.m_nOpaciteDebut));
	this.SetOpacite(this.m_oBaliseImgTemp,this.__nAvancementInverse(nAvancement,this.m_nOpaciteDebut));
};

WDAnimSurImage.prototype._AnimBalayageHaut=function _AnimBalayageHaut(nAvancement)
{
	this.__AnimBalayageVertical(nAvancement,false);
};

WDAnimSurImage.prototype._AnimBalayageBas=function _AnimBalayageBas(nAvancement)
{
	this.__AnimBalayageVertical(nAvancement,true);
};

WDAnimSurImage.prototype.__AnimBalayageVertical=function __AnimBalayageVertical(nAvancement,bBas)
{
	this.SetY(this.m_oBaliseImgTemp,this.m_nY+this.__nAvancement(nAvancement,this.m_nHauteur)*(bBas?1:-1));
	this.__AnimRecouvrementVertical(nAvancement,!bBas);
};

WDAnimSurImage.prototype._AnimRecouvrementHaut=function _AnimRecouvrementHaut(nAvancement)
{
	this.__AnimRecouvrementVertical(nAvancement,false);
};

WDAnimSurImage.prototype._AnimRecouvrementBas=function _AnimRecouvrementBas(nAvancement)
{
	this.__AnimRecouvrementVertical(nAvancement,true);
};

WDAnimSurImage.prototype.__AnimRecouvrementVertical=function __AnimRecouvrementVertical(nAvancement,bBas)
{
	this.SetY(this.m_oBaliseImgTempFin,this.m_nY+this.__nAvancementInverse(nAvancement,this.m_nHauteur)*(bBas?1:-1));
};

WDAnimSurImage.prototype._AnimBalayageGauche=function _AnimBalayageGauche(nAvancement)
{
	this.__AnimBalayageHorizontal(nAvancement,false);
};

WDAnimSurImage.prototype._AnimBalayageDroite=function _AnimBalayageDroite(nAvancement)
{
	this.__AnimBalayageHorizontal(nAvancement,true);
};

WDAnimSurImage.prototype.__AnimBalayageHorizontal=function __AnimBalayageHorizontal(nAvancement,bDroite)
{
	this.SetX(this.m_oBaliseImgTemp,this.m_nX+this.__nAvancement(nAvancement,this.m_nLargeur)*(bDroite?1:-1));
	this.__AnimRecouvrementHorizontal(nAvancement,!bDroite);
};

WDAnimSurImage.prototype._AnimRecouvrementGauche=function _AnimRecouvrementGauche(nAvancement)
{
	this.__AnimRecouvrementHorizontal(nAvancement,false);
};

WDAnimSurImage.prototype._AnimRecouvrementDroite=function _AnimRecouvrementDroite(nAvancement)
{
	this.__AnimRecouvrementHorizontal(nAvancement,true);
};

WDAnimSurImage.prototype.__AnimRecouvrementHorizontal=function __AnimRecouvrementHorizontal(nAvancement,bDroite)
{
	this.SetX(this.m_oBaliseImgTempFin,this.m_nX+this.__nAvancementInverse(nAvancement,this.m_nLargeur)*(bDroite?1:-1));
};

WDAnimSurImage.prototype._AnimRecouvrement=function _AnimRecouvrement(nAvancement)
{
	this.__AnimXXcouvrementInterne(this.__nAvancementInverseVal(nAvancement),this.m_oDiv);
	this.SetX(this.m_oBaliseImgTempFin,this.m_nX);
	this.SetY(this.m_oBaliseImgTempFin,this.m_nY);
};

WDAnimSurImage.prototype._AnimRecouvrementZoom=function _AnimRecouvrementZoom(nAvancement)
{
	this.__AnimXXcouvrementInterne(this.__nAvancementInverseVal(nAvancement),this.m_oBaliseImgTempFin);
};

WDAnimSurImage.prototype._AnimDecouvrement=function _AnimDecouvrement(nAvancement)
{
	this.__AnimXXcouvrementInterne(nAvancement,this.m_oDiv);
	this.SetX(this.m_oBaliseImgTemp,this.m_nX);
	this.SetY(this.m_oBaliseImgTemp,this.m_nY);
};

WDAnimSurImage.prototype._AnimDecouvrementZoom=function _AnimDecouvrementZoom(nAvancement)
{
	this.__AnimXXcouvrementInterne(nAvancement,this.m_oBaliseImgTemp);
};

// Code interne pour le Recouvrement/Decouvrement
// Donner Max-Avancement pour le recouvrement
WDAnimSurImage.prototype.__AnimXXcouvrementInterne=function __AnimXXcouvrementInterne(nAvancement,oCible)
{
	this.SetX(oCible,this.m_nX+this.__nAvancement(nAvancement,this.m_nLargeur)/2);
	this.SetY(oCible,this.m_nY+this.__nAvancement(nAvancement,this.m_nHauteur)/2);
	this.SetLargeur(oCible,this.__nAvancementInverse(nAvancement,this.m_nLargeur));
	this.SetHauteur(oCible,this.__nAvancementInverse(nAvancement,this.m_nHauteur));
};

WDAnimSurImage.prototype.__nAvancement=function __nAvancement(nAvancement,nValeur)
{
	return parseInt(nValeur*nAvancement/this.ms_nAvancementMax);
};

WDAnimSurImage.prototype.__nAvancementInverse=function __nAvancementInverse(nAvancement,nValeur)
{
	return this.__nAvancement(this.__nAvancementInverseVal(nAvancement),nValeur);
};

WDAnimSurImage.prototype.__nAvancementInverseVal=function __nAvancementInverseVal(nAvancement)
{
	return (this.ms_nAvancementMax-nAvancement);
};

// Les fonctions de manipulation des proprietes

// Opacite
WDAnimSurImage.prototype.GetOpacite=function GetOpacite(oBaliseImg)
{
	return _JCPOR(oBaliseImg.style.opacity,oBaliseImg);
};
WDAnimSurImage.prototype.SetOpacite=function SetOpacite(oBaliseImg,nVal)
{
	oBaliseImg.style.opacity=_JCPO(nVal,oBaliseImg);
};

// X
WDAnimSurImage.prototype.GetX=function GetX(oBaliseImg)
{
	return _JCCP(oBaliseImg.offsetLeft,oBaliseImg,true,true);
};
WDAnimSurImage.prototype.SetX=function SetX(oBaliseImg,nVal)
{
	oBaliseImg.style.left=_JCCP(nVal,oBaliseImg,true,false)+"px";
};

// Y
WDAnimSurImage.prototype.GetY=function GetY(oBaliseImg)
{
	return _JCCP(oBaliseImg.offsetTop,oBaliseImg,false,true);
};
WDAnimSurImage.prototype.SetY=function SetY(oBaliseImg,nVal)
{
	oBaliseImg.style.top=_JCCP(nVal,oBaliseImg,false,false)+"px";
};

// Largeur
WDAnimSurImage.prototype.GetLargeur=function GetLargeur(oBaliseImg)
{
	return oBaliseImg.offsetWidth;
};
WDAnimSurImage.prototype.SetLargeur=function SetLargeur(oBaliseImg,nVal)
{
	oBaliseImg.style.width=nVal+"px";
};

// Hauteur
WDAnimSurImage.prototype.GetHauteur=function GetHauteur(oBaliseImg)
{
	return oBaliseImg.offsetHeight;
};
WDAnimSurImage.prototype.SetHauteur=function SetHauteur(oBaliseImg,nVal)
{
	oBaliseImg.style.height=nVal+"px";
};

// Visibilite
WDAnimSurImage.prototype.GetVisibilite=function GetVisibilite(oBaliseImg)
{
	return oBaliseImg.style.visibility;
};
WDAnimSurImage.prototype.SetVisibilite=function SetVisibilite(oBaliseImg,sVal)
{
	oBaliseImg.style.visibility=sVal;
};

// Superposable
WDAnimSurImage.prototype.SetSuperposable=function SetSuperposable(oBalise)
{
	oBalise.style.position="absolute";
};

WDAnimSurImage.prototype.b2Image=function b2Image(nType)
{
	return (nType>this.ms_nTypeFondu)&&(nType<this.ms_nTypeDecouvrement);
};

WDAnimSurImage.prototype.bImageTempFrere=function bImageTempFrere(nType)
{
	return (nType==this.ms_nTypeRecouvrement);
};

WDAnimSurImage.prototype.AjoutFrere=function AjoutFrere(oBalise)
{
	if(this.m_oBaliseImg.nextSibling)
	{
		this.m_oBaliseImg.parentNode.insertBefore(oBalise,this.m_oBaliseImg.nextSibling);
	}
	else
	{
		this.m_oBaliseImg.parentNode.appendChild(oBalise);
	}
};

WDAnimSurImage.prototype.oAjoutImageTemp=function oAjoutImageTemp(oBaliseImg,sImage,nOpacite,nType,bFrere)
{
	var oBaliseImgTemp=new Image();
	this.SetSuperposable(oBaliseImgTemp);
	if(bFrere)
	{
		this.AjoutFrere(oBaliseImgTemp);
		this.SetX(oBaliseImgTemp,this.m_nX);
		this.SetY(oBaliseImgTemp,this.m_nY);
	}
	else
	{
		this.m_oDiv.appendChild(oBaliseImgTemp);
	}
	this.SetLargeur(oBaliseImgTemp,this.m_nLargeur);
	this.SetHauteur(oBaliseImgTemp,this.m_nHauteur);
	if((nOpacite<100)&&(nType!=this.ms_nTypeDecouvrement))
	{
		this.SetOpacite(oBaliseImgTemp,nOpacite);
	}
	oBaliseImgTemp.src=sImage;

	// Copie si besoin le handler de menu contextuel (pour l'option qui protege contre la sauvegarde directe de l'image)
	if(oBaliseImg.oncontextmenu)
	{
		oBaliseImgTemp.oncontextmenu=function(oEvent) { bStopPropagation(oEvent?oEvent:event); };
	}

	return oBaliseImgTemp;
};

WDAnimSurImage.prototype.vFin=function vFin()
{
	if(this.b2Image(this.m_nType))
	{
		this.SetVisibilite(this.m_oBaliseImg,this.m_sVisibilite);
	}
	// Supprime l'image temporaire du document
	this.m_oDiv.parentNode.removeChild(this.m_oDiv);
	(this.bImageTempFrere(this.m_nType)?this.m_oBaliseImg.parentNode:this.m_oDiv).removeChild(this.m_oBaliseImgTemp);
	delete this.m_oDiv;
	delete this.m_oBaliseImgTemp;
	delete this.m_oBaliseImgTempFin;
	
	// Supprime l'animation du tableau
	delete this.ms_tabAnimations[this.m_sAliasChamp];

	// Appel de la classe de base
	WDAnim.prototype.vFin.apply(this,arguments);
};

function sAnimationJoueSurImage(sValeur,oImage,sImageDebut,nOpaciteDebut,nType,nCourbe,nDuree,sAliasChamp)
{
	// Si on a deja une animation sur l'image, la termine
	var oAnimationOld = WDAnimSurImage.prototype.ms_tabAnimations[sAliasChamp];
	if (oAnimationOld)
	{
		nOpaciteDebut = oAnimationOld.m_nOpaciteDebut;
		// Force un dernier dessin puis annule
		oAnimationOld._Maj(1);
		oAnimationOld.vAnnule();
	}
	// Lance l'animation
	WDAnimSurImage.prototype.ms_tabAnimations[sAliasChamp] = new WDAnimSurImage(oImage,sImageDebut,nOpaciteDebut,nType,nCourbe,nDuree,sValeur,sAliasChamp);
	// Et retourne la valeur (pour le .src)
	return sValeur;
};
