//#14.00Aa WDUtil.JS
//VersionVI: 30F140021e
// Le seul support technique disponible pour cette librairie est
// accessible a travers le service "Assistance Directe".

// Attention a ne pas mettre d'accent dans ce fichier COMMENTAIRES inclus

// Detection du navigateur

var bIE = navigator.appName.indexOf("Microsoft") != -1;
var bIE7 = false;
// On fait un cas particulier pour IE7
if (bIE)
{
	var oExpr = new RegExp("MSIE ([0-9])+[\\.0-9]*");
	bIE7 = ((oExpr.exec(navigator.userAgent) != null) && (parseInt(oExpr.$1) >= 7));
}

// Sens de lecture
var bRTL = bIE ? (document.dir == "rtl") : (document.documentElement.dir == "rtl");
function GetStyleLeft(oStyle) { return bRTL ? oStyle.right : oStyle.left; }
function SetStyleLeft(oStyle, nVal, nOffset) { if (bRTL) { oStyle.right = (nVal - nOffset) + 'px'; } else { oStyle.left = (nVal + nOffset) + 'px'; } }

// Emulation de getElementById (IE4 et IE pocket)
var oGetId = null;
if (document.getElementById)
{
	oGetId = function(sNomChamp) { return document.getElementById(sNomChamp); };
}
else if (document.all)
{
	oGetId = function(sNomChamp) { return document.all(sNomChamp); };
}
else
{
	oGetId = function(sNomChamp) { return null; };
}

// Recupere l'objet attache a un champ
function oGetVarChamp (sAlias)
{
	try
	{
		var oVarChamp = eval("cl" + sAlias);
		if (typeof oVarChamp == "object")
		{
			return oVarChamp;
		}
	}
	catch (e)
	{
	}
	return null;
}

// Appele une methode donnee sur l'objet d'un champ s'il existe
function AppelVarChampMeth (sAlias, sFonction, tabParam)
{
	var oVarChamp = oGetVarChamp(sAlias);
	if (oVarChamp && oVarChamp[sFonction])
	{
		oVarChamp[sFonction].apply(oVarChamp, tabParam);
	}
}

// Stop la propagation des evenements
var bStopPropagation = null;
if (bIE)
{
//	bStopPropagation = function (oEvent) { if (oEvent.returnValue) { oEvent.returnValue = false; } return false; };
	bStopPropagation = function (oEvent) { oEvent.returnValue = false; return false; };
}
else
{
	bStopPropagation = function (oEvent) { if (oEvent.preventDefault) { oEvent.preventDefault(); } return false; };
}

// Attache une fonction a un evenement
function HookOnXXX (oCible, sEventIE, sEventFF, fFonction)
{
	if (oCible.addEventListener)
	{
		oCible.addEventListener(sEventFF, fFonction, false);
	}
	else
	{
		oCible.attachEvent(sEventIE, fFonction);
	}
}

// Detache une fonction d'un evenement
function UnhookOnXXX (oCible, sEventIE, sEventFF, fFonction)
{
	if (oCible.removeEventListener)
	{
		oCible.removeEventListener(sEventFF, fFonction, false);
	}
	else
	{
		oCible.detachEvent(sEventIE, fFonction);
	}
}

// Indique si un element est fils d'un autre
function bEstFils (oElement, oParent, oDocument)
{
	while (oElement && oElement != oDocument.body)
	{
		if (oElement == oParent)
		{
			return true;
		}
		oElement = oElement.parentNode;
	}
	return false;
}

// Encodage des valeurs

function WDEncode (bUTF8)
{
	// On aura besoin de transforme les chaines recus pour gerer les caratere interdit en ISO-8859-1 si besoin
	// Pas besoin de le faire en UTF-8 car il on deja ete encode pour avoir au final la bonne valeur unicode
	if (bUTF8 === undefined)
	{
		bUTF8 = ((document.charset ? document.charset : (document.characterSet ? document.characterSet : "iso-8859-1")).toLowerCase() != "iso-8859-1");
	}

	if (!bUTF8)
	{
		// On defini notre fonction d'encodage des parametres
		this.sEncodePOST = WDEncode.prototype.sEncodePOST_CP1252;

		// Et d'ecriture de valeur dans le HTML
		this.sEncodeCharset = WDEncode.prototype.sEncodeCharset_CP1252;
	}
	else
	{
		// Le fonctionnement par defaut des fonctions est OK
		// On defini notre fonction d'encodage des parametres
//		this.sEncodePOST = function (sValeur) { return encodeURIComponent(sValeur); };
		// Et d'ecriture de valeur dans le HTML
//		this.sEncodeCharset = function (sValeur) { return sValeur; };
	}
};

WDEncode.prototype =
{
	// Fonctionnement par defaut des fonctions d'encodage : pour les pages UTF8
	// Encodage pour l'ecriture dans le POST : simple echapement
	sEncodePOST:function (sValeur)
	{
		return encodeURIComponent(sValeur);
	},

	// Encodage pour l'ecriture dans la page : ne fait rien
	sEncodeCharset:function (sValeur)
	{
		return sValeur;
	},

	// Version pour les pages non UTF8 (CP1252) des fonctions d'encodage
	// Encodage pour l'ecriture dans le POST : remplacement de tous les carateres unicodes par leur valeur CP1252 si possible
	sEncodePOST_CP1252:function (sValeur)
	{
		// Traite les carateres unicodes
		sValeur = sValeur.replace(/[\u0100-\uFFFF]/g, function(sCar) { var n = sCar.charCodeAt(0); var i; var nLimiteI = WDEncode.prototype.tabConvCP1252.length; for(i = 0; i < nLimiteI; i++) { if(WDEncode.prototype.tabConvCP1252[i] == n) { return String.fromCharCode(i + 128); } } return sCar; } );
		// Escape le tout
		sValeur = escape(sValeur);
		// Et remplace le + car il represente l'encodage de l'espace
		return sValeur.replace(/\+/g, "%2B");
	},

	// Encodage pour l'ecriture dans la page : remplace les carateres qui ne sont pas dans l'alphabet par leur valeur UNICODE
	sEncodeCharset_CP1252:function (sValeur, bHTML)
	{
		// Le jeu de caratere de windows est CP1252. Qui est un surensemble de ISO-8859-1
		// Il faut convertir tous les carateres entre 0x80 et 0x9F en leur version unicode

		// Puis les caractere de la plage
		// 128 = 0x80
//		if (bHTML)
//			sValeur = sValeur.replace(/[\x80-\x9F]/g, function(sCar) { return "&#" + clWDAJAXMain.sConvCP1252[sCar.charCodeAt(0) - 128] + ";"; } );
//		else
//			sValeur = sValeur.replace(/[\x80-\x9F]/g, function(sCar) { return String.fromCharCode(clWDAJAXMain.sConvCP1252[sCar.charCodeAt(0) - 128]); } );
		sValeur = sValeur.replace(/[\x80-\x9F]/g, function(sCar) { return String.fromCharCode(WDEncode.prototype.tabConvCP1252[sCar.charCodeAt(0) - 128]); } );

		if (bHTML)
		{
			// Les caracteres restant (0xA0-0xFF) sont encode normalement en HTML
			sValeur = sValeur.replace(/[\xA0-\xFF]/g, function(sCar) { return "&#" + sCar.charCodeAt(0) + ";"; } );
		}

		// Renvoi de la valeur convertie
		return sValeur;
	},

	// Le tableau pour la conversion depuis CP1252
	//					128		129?	130		131		132		133		134		135		136		137		138		139		140		141?	142		143?	144?	145		146		147		148		149		150		151		152		153		154		155		156		157?	158		159
	//					0x80	0x81	0x82	0x83	0x84	0x85	0x86	0x87	0x88	0x89	0x8A	0x8B	0x8C	0x8D	0x8E	0x8F	0x90	0x91	0x92	0x93	0x94	0x95	0x96	0x97	0x98	0x99	0x9A	0x9B	0x9C	0x9D	0x9E	0x9F
	tabConvCP1252:	[	8364,	129,	8218,	402,	8222,	8230,	8224,	8225,	710,	8240,	352,	8249,	338,	141,	381,	143,	144,	8216,	8217,	8220,	8221,	8226,	8211,	8212,	732,	8482,	353,	8250,	339,	157,	382,	376	],

	// Fonction de reencodage en HTML
	sEncodeInnerHTML:function (sValeur, bRemplaceBR, bPasEncodeBalise)
	{
		// Remplace le minimum de caracteres
		if (!bPasEncodeBalise)
		{
			sValeur = sValeur.replace(/&/g, "&amp;");
			sValeur = sValeur.replace(/</g, "&lt;");
			sValeur = sValeur.replace(/>/g, "&gt;");
//			sValeur = sValeur.replace(/\'/g, "&apos;");
//			sValeur = sValeur.replace(/\"/g, "&quot;");
		}

		// Si le charset de la page est Latin1 (Donc pas en UTF-8)
		// => On transforme les caractere de CP1252 en leur equivalent unicode qui va fonctionner
		// => On encode les autres caracteres > 127
		// Appele le pointeru qui pointe deja sur la bonne fonction
		sValeur = this.sEncodeCharset(sValeur, true);

		if (bRemplaceBR)
		{
			// Met des balises BR pour les marques de lignes
			sValeur = sValeur.replace(/\r\n/g, "<BR>");
			sValeur = sValeur.replace(/\n/g, "<BR>");
		}

		// Renvoi de la valeur
		return sValeur;
	}
};

// Instancie un objet principal
var clWDEncode = new WDEncode(_bUTF8_);


// Gestion des elements popup de la page
function WDPopupAutomatique (oElement, oObjetParent)
{
	// Memorise les parametres
	this.m_oElement = oElement;
	this.m_oObjetParent = oObjetParent;

	var oThis = this;
	// Cree la methode de hook dans la classe
	if (bIE)
	{
		this.m_fOnFocus = function () { return oThis.OnFocus(event); }
		this.m_fOnBlur = function () { return oThis.OnBlur(event); }
	}
	else
	{
		this.m_fOnFocus = function (event) { return oThis.OnFocus(event); }
		this.m_fOnBlur = function (event) { return oThis.OnBlur(event); }
	}
};

WDPopupAutomatique.prototype =
{
//	m_oElement:				null,
//	m_oObjetParent:			null,
//	m_fOnFocus:				null,
//	m_fOnBlur:				null,
//	m_nTimeoutFocus:		null,
//	m_fTimeout:				null,

	// Affiche le champ
	Affiche:function (oEvent, oParam)
	{
		// Efface le timeout existant si besoin
		this.__ClearTimeout();

		// Hook les onfocus/onblur des elements
		this.__HookOnFocusBlurRecursif(this.m_oElement);

		// Appel le champ hote
		this.m_oObjetParent.AfficheInterne(oEvent, oParam);

		// Affiche l'element
		this.m_oElement.style.display = "block";

		// Donne le focus au premier champ APRES l'affichage
		try
		{
			this.m_oElement.getElementsByTagName("A")[0].focus();
		}
		catch (e)
		{
		}
	},

	// Notification de que champ doit etre masquer
	Masque:function (oEvent)
	{
		// Efface le timeout existant si besoin
		this.__ClearTimeout();

		// Supprime les hooks
		this.__UnhookOnFocusBlurRecursif(this.m_oElement);

		// Masque le champ
		this.m_oElement.style.display = "none";

		// Appel le champ hote
		this.m_oObjetParent.MasqueInterne(oEvent);
	},

	// Hook les onfocus/onblur des liens
	__HookOnFocusBlurRecursif:function (oElement)
	{
		// Hook l'element uniquement s'il peut recevoir le focus
		if (oElement.focus)
		{
			HookOnXXX(oElement, 'onfocus', 'focus', this.m_fOnFocus);
			HookOnXXX(oElement, 'onblur', 'blur', this.m_fOnBlur);
		}

		// Et ses fils qui ne sont pas du texte simple
		var oFils = oElement.firstChild;
		while (oFils)
		{
			if (oFils.nodeName != "#text")
			{
				this.__HookOnFocusBlurRecursif(oFils);
			}
			oFils = oFils.nextSibling;
		}
	},

	// Supprime les hooks
	__UnhookOnFocusBlurRecursif:function (oElement)
	{
		// Unhook l'element uniquement s'il peut recevoir le focus
		if (oElement.focus)
		{
			UnhookOnXXX(oElement, 'onfocus', 'focus', this.m_fOnFocus);
			UnhookOnXXX(oElement, 'onblur', 'blur', this.m_fOnBlur);
		}

		// Et ses fils qui ne sont pas du texte simple
		var oFils = oElement.firstChild;
		while (oFils)
		{
			if (oFils.nodeName != "#text")
			{
				this.__UnhookOnFocusBlurRecursif(oFils);
			}
			oFils = oFils.nextSibling;
		}
	},

	// Evenement avant l'affectation en AJAX du contenu du calendrier
	PreAffecteHTML:function (bDepuisAJAX)
	{
		// Si le champ est affiche : supprime les hooks
		if (this.m_oElement.style.display == "block")
		{
			this.__UnhookOnFocusBlurRecursif(this.m_oElement);
		}
	},

	// Evenement apres l'affectation en AJAX du contenu du calendrier
	PostAffecteHTML:function (bDepuisAJAX)
	{
		// Si le champ est affiche : restaure les hooks
		if (this.m_oElement.style.display == "block")
		{
			this.__HookOnFocusBlurRecursif(this.m_oElement);
		}
		// Donne le focus au premier champ
		try
		{
			this.m_oElement.getElementsByTagName("A")[0].focus();
		}
		catch (e)
		{
		}
	},

	// Notification qu'un lien a pris le focus.
	OnFocus:function (oEvent)
	{
		// Efface le timeout existant si besoin
		this.__ClearTimeout();
	},

	// Notification que le champ a perdu le focus.
	// Il faut tester si le focus est parti dans un autre champ du calendrier ou a l'exterieur
	OnBlur:function (oEvent)
	{
		// On veut detecter les pertes de focus du calendrier
		// Sauf que la perte de focus d'un lien peut donner le focus a un autre lien du calendrier
		// => On fait un timeout de 1ms qui sera annule par le onfocus de l'autre lien si besoin
		if (!this.m_nTimeoutFocus)
		{
			// Cree une fonction qui appele la fonction de masquage
			var oThis = this;
			this.m_fTimeout = function(event) { oThis.Masque(event); };
			// Cree la fonction de visibilite globale
			fTimeout = this.m_fTimeout;
			this.m_nTimeoutFocus = setTimeout("fTimeout(undefined);", 1);
		}
	},

	// Efface le timeout existant si besoin
	__ClearTimeout:function ()
	{
		// Supprime le timeout actif
		if (this.m_nTimeoutFocus)
		{
			// Invalide le timeout aupres du systeme
			clearTimeout(this.m_nTimeoutFocus);

			// Supprime la fonction cree (globale et la reference locale)
			fTimeout = null;
			delete this.m_fTimeout;

			// Supprime le membre
			delete this.m_nTimeoutFocus;
		}
	}
};









