/**
 * Fichier de fonctions générales utiles pour Webeezy
 *
 * @package webeezy
 * @subpackage webservices
 * @author reservoir34
 * @copyright reservoir34
 * @date 19/08/2008
 */
/**
* Variable "raccourci" permettant d'accéder aux méthodes natives YAHOO des test des tests sur les types des variables
* @var object YAHOO.lang
*/
var CHECK = YAHOO.lang;
/**
 * Variable permettant d'accèder au méthodes YAHOO sur le DOM 
 * @var object YAHOO.lang
 */
var DOM = YAHOO.util.Dom;
/**
 * Variable permettant d'accéder aux méthode YAHOO sur Event
 */
var EVENT = YAHOO.util.Event;
/**
 * Variable permettant d'activer ou non le debug
 * @var bool
 */
var DEBUG = false || DEBUG;
var debug = DEBUG;
/**
 * Variable d'activation des debug utilisée à la construction des objet de type Weezbe*
 */
try
{
	var debugO = false || (location.hostname == 'sandboxes');
}
catch (e)
{
}
debugO = false;
/**
 * Objet de type date à l'instant du chargement du fichier
 * @var function
 */
var DATE = new Date();
var CURRENT_URL = typeof CURRENT_URL != 'undefined' ? CURRENT_URL : location.protocol + '//' + location.host + location.pathname;
/**
 * Fonction permettant de récupérer la date à l'instant t selon le format souhaité (19 Aout 2008):
 *	- YYMMDD : 080819
 *	- YYYYMMDD : 20080819
 *	- DDMMYY : 190808
 *	- DDMMYYYY : 19082008
 *
 * @param string le format souhaité
 * @param string optional le séparateur à utilisé pour séparé les années des mois des jours
 * @return string
 */
function getDateNow(/*string*/$_format/*string, $_separator*/)
{
	var dateNow = new Date();
	var Y = dateNow.getFullYear();
	var M = (parseInt(dateNow.getMonth() + 1) < 10 ? '0' + parseInt(dateNow.getMonth() + 1) : parseInt(dateNow.getMonth() + 1));
	var D = (dateNow.getDate() < 10 ? '0' + dateNow.getDate() : dateNow.getDate());
	/**
	 * Récupération de l'éventuel séparateur
	 */
	var s = typeof arguments[1] != 'undefined' ? arguments[1] : '';
	switch ($_format)
	{
		case 'YYMMDD':
			return new String(Y).substr(2, 2) + s + M + s + D;
			break;
		case 'YYYYMMDD':
			return Y + s + M + s + D;
			break;
		case 'DDMMYY':
			return D + s + M + s + new String(Y).substr(2, 2);
			break;
		case 'DDMMYYYY':
			return D + s + M + s + Y;
			break;
	}
	return '';
}
/**
 * Fonction permettant de récupérer la date à l'instant t selon le format souhaité (15h12m13s):
 *	- HHMMSS : 151213
 *	- HHhMMmSSs : 15h12m13s
 *
 * @param string le format souhaité
 * @param string optional le séparateur à utilisé pour séparé les heures des minutes des secondes
 * @return string l'heure au format demandé
 */
function getHourNow(/*string*/$_format/*string, $_separator*/)
{
	var dateNow = new Date();
	var H = (dateNow.getHours() < 10 ? '0' + dateNow.getHours() : dateNow.getHours());
	var M = (dateNow.getMinutes() < 10 ? '0' + dateNow.getMinutes() : dateNow.getMinutes());
	var S = (dateNow.getSeconds() < 10 ? '0' + dateNow.getSeconds() : dateNow.getSeconds());
	/**
	 * Récupération de l'éventuel séparateur
	 */
	var p = typeof arguments[1] != 'undefined' ? arguments[1] : '';
	switch ($_format)
	{
		case 'HHMMSS':
			return H + p + M + p + S;
			break;
		case 'HHhMMmSSs':
			return h + 'h' + M + 'm' + S + 's';
			break;
	}
	return '';
}
/**
 * trim supprime les espaces d'une chaine de caractères
 *
 * @param string chaine la chaine
 */
function trim(chaine)
{
	return chaine.replace(/^\s*|\s*$/, "");
}
/**
 * Plie/déplie un élément
 * @param HTMLElement|HTMLImageElement 	$_caller 		object déclencheur
 * @param HTMLElement|string|Array		$_elementID		élément à plier/déplier
 * $_caller permet de retrouver l'image '+/-' si elle existe et changer son image
 * @return void
 */
function expand($_caller, $_elementID /* $_forceExpand*/)
{
	$_forceExpand = (typeof (arguments[2]) != 'undefined') ? arguments[2] : false;
	if (isObject($_caller))
	{
		if ($_caller.tagName.toUpperCase() != 'IMG' && $_caller.getElementsByTagName('IMG').length == 1)
			$_caller = $_caller.getElementsByTagName('IMG')[0];
		if (isObject($_caller))
		{
			if (typeof (arguments[2]) != 'undefined')
				$_caller.src = ($_forceExpand == true) ? $_caller.src.replace(/reduce/g, 'expand') : $_caller.src.replace(/expand/g, 'reduce');
			else
				$_caller.src = ($_caller.src.indexOf('expand') > -1) ? $_caller.src.replace(/expand/g, 'reduce') : $_caller.src.replace(/reduce/g, 'expand');
		}
	}
	if (isArray($_elementID) && $_elementID.length > 1)
	{
		for( var a = 0; a < $_elementID.length; a++)
			$_elementID[a].style.display = ($_elementID[a].style.display == 'none' || $_forceExpand == true) ? 'block' : 'none';
	}
	else
	{
		if (isset($_elementID[0]) && isObject(DOM.get($_elementID[0])))
			$_elementID[0].style.display = ($_elementID[0].style.display == 'none' || $_forceExpand == true) ? 'block' : 'none';
		else
			if (isObject($_elementID))
				$_elementID.style.display = ($_elementID.style.display == 'none' || $_forceExpand == true) ? 'block' : 'none';
			else
				if ($_elementID = DOM.get($_elementID))
					$_elementID.style.display = ($_elementID.style.display == 'none' || $_forceExpand == true) ? 'block' : 'none';
	}
}
/**
 * Méthode d'affichage des message de debug
 *
 * @param string le contexte du message de debug (objet.methode)
 * @param string le message de débug (optionnel)
 * @param bool indique si c'est une erreur ou non afin que le message doit identifié comme une erreur ou pas dans la console
 * @return bool true
 */
function displayDebug(/*string*/$_context,/*string*/$_message,/*bool*/$_isError)
{
	if (DEBUG || debug)
	{
		$_message = (typeof (arguments[1]) != 'undefined') ? $_message : '';
		/**
		 * FF
		 */
		if ((typeof window.console != 'undefined') && isset(window.console) && isset(window.console.error) && isset(window.console.log))
		{
			if ($_isError)
				window.console.error($_context, ' : ', $_message);
			else
				window.console.log($_context, ' : ', $_message);
		}
	}
	return true;
}
/**
 * Fonction permettant de tester qu'une variable est définie ou non
 *
 * @param mixed la variable à tester
 * @return bool false si $_var vaut undefined ou null
 */
function isset(/*mixed*/$_var)
{
	//displayDebug({'function':'isset'},{'var':$_var});
	return ((typeof $_var != 'undefined') && $_var != null);
}
/**
 * Fonction permettant de tester si une valeur est vraie ou non
 *
 * @uses isset
 * @param $_var mixed la valeur à tester
 * @return bool
 */
function isTrue(/*mixed*/$_var)
{
	//displayDebug({'function':'isTrue'},{'var':$_var});
	if (!isset($_var))
		return false;
	else
		return ($_var == true || $_var == "true" || $_var == "on" || $_var == 1 || $_var == "1" || $_var == "vrai");
}
/**
 * Fonction permettant de tester si une valeur est fausse ou non
 *
 * @uses isTrue
 * @param $_var mixed la valeur à tester
 * @return bool
 */
function isFalse(/*mixed*/$_var)
{
	//displayDebug({'function':'isFalse'},{'var':$_var});
	return !isTrue($_var);
}
/**
 * Méthode permettant de tester si l'attribut est bien un tableau
 *
 * @uses isObject
 * @param array le tableau à vérifeir
 * @return bool true si c'est un tableau
 */
function isArray(/*array*/$_array)
{
	//displayDebug({'function':'isArray'},{'array':$_array});
	return isObject($_array) && $_array.constructor == Array;
}
/**
 * Fonction permettant de tester si une valeur est présente dans un tableau de valeurs
 *
 * @uses isArray
 * @uses isObject
 * @param string la valeur recherchée
 * @param array le tableau de valeurs
 * @return bool true si la valeur est présente|false si la valeur n'est pas présente ou que 
 */
function inArray(/*mixed*/$_value,/*array/object*/$_array)
{
	//displayDebug({'function':'inArray'},{'value':$_value},{'array':$_array});
	if ((!isArray($_array) && !isObject($_array)) || ((isArray($_array) || isObject($_array)) && count($_array) == 0))
		return false;
	var present = false;
	var len = $_array.length;
	for( var i = 0; (i < len) && !present; i++)
		present = present || ($_array[i] == $_value);
	return present;
}
/**
 * Fonction permettant de teser si une clef existe  pour une valeur dans le tableau
 *
 * @uses isArray
 * @uses isObject
 * @uses count
 * @param string le clef recherchée
 * @param array le tableau
 * @return bool true|false
 */
function keyInArray(/*string*/$_key,/*array/object*/$_array)
{
	//displayDebug({'function':'keyInArray'},{'key':$_key},{'array':$_array});
	if ((!isArray($_array) && !isObject($_array)) || ((isArray($_array) || isObject($_array)) && count($_array) == 0))
		return false;
	for( var key in $_array)
	{
		if (key == $_key)
			return true;
	}
	return false;
}
/**
 * Fonction permettant de compter le nombre d'attribut contenu par un tableau ou un objet Javascript
 *
 * @uses isArray (utilisant isObject, inutile de faire appel à isObject)
 * @param mixed le tableau ou l'objet ou autre chose dont il faut calculer le nombre d'attributs
 * @return int le nombre d'attributs
 */
function count(/*mixed*/$_array)
{
	//displayDebug('count',{'array':$_array});
	var counter = 0;
	if (isset($_array) && (isArray($_array) || isObject($_array)))
	{
		for( var indice in $_array)
			counter++;
	}
	else
	{
		if (isset($_array))
			counter = 1;
		else
			counter = 0;
	}
	return counter;
}
/**
 * Fonction permettant d'ajouter une valeur à un tableau (la valeur est ajouté au tableau par référence)
 * @param $_array array le tableau
 * @param $_value mixed la valeur
 * @param $_index int|string l'index auquel la valeur doit être enregistrée
 * @return array le tableau avec la nouvelle valeur
 */
function addValueToArray($_array, $_value, $_index)
{
	if (!isArray($_array))
		$_array = new Array();
	if (isset($_index))
		$_array[$_index] = $_value;
	else
		$_array[count($_array)] = $_value;
	return $_array;
}
/**
 * Fonction permettant de supprimer une valeur d'un tableau
 * @param $_value mixed la valeur à supprimer
 * @param $_array array le tableau duquel il faut supprimer la valeur
 * @return array le tableau sans la valeur
 */
function removeValueOfArray($_value, $_array)
{
	var newArray = new Array();
	if (isArray($_array) && inArray($_value, $_array))
	{
		for( var index in $_array)
			if ($_array[index] !== $_value)
				newArray[index] = $_array[index];
		return newArray;
	}
	else
		return $_array;
}
/**
 * Fonction permettant de supprimer un élément du tableau par son index
 * @param $_index mixed l'index
 * @param $_array array le tableau duquel il faut surpprimer la valeur par l'index
 * @return array le tableau sans la valeur
 */
function removeElementOfArrayByIndex($_index, $_array)
{
	var newArray = new Array();
	if (isArray($_array) && keyInArray($_index, $_array))
	{
		for( var index in $_array)
			if (index !== $_index)
				newArray[index] = $_array[index];
		return newArray;
	}
	else
		return $_array;
}
/**
 * Méthode permettant de tester si l'attribut est bien un objet
 *
 * @uses isset
 * @uses isFunction
 * @param object l'objet à vérifier
 * @return bool true si c'est un objet
 */
function isObject($_object)
{
	//displayDebug({'function':'isObject'},{'object':$_object});
	return (isset($_object) && typeof $_object == "object") || isFunction($_object);
}
/**
 * Méthode permettant de tester si l'attribut est bien une fonction
 *
 * @uses isset
 * @param function l'objet à vérifier
 * @return bool true si c'est un objet
 */
function isFunction($_function)
{
	//displayDebug({'function':'isObject'},{'object':$_object});
	return (isset($_function) && isset($_function.prototype));
}
/**
 * Méthode retournant true si la valeur passée en paramètre est bien une chaine de caractère
 * @param $_string string
 * @return bool true si c'est une chaine de caractère|false dans le cas contraire
 */
function isString($_string)
{
	return (isset($_string) && typeof $_string == "string");
}
/**
 * Méthode de récupération de l'élément HTML à la source de l'événement généré compatible Mozilla/IE
 *
 * @param $_event event l'événement
 * @return HTMLElement l'élément HTML à l'origine de l'événement 
 */
function getEventSource($_event)
{
	displayDebug( { 'function' :'getEventSource' }, { 'event' :$_event });
	return (document.all && !$_event.target) ? event.srcElement : $_event.target;
}
/**
 * Fonction permettant simplement de récupèrer une chaine de caractère avec la première lettre en majuscule
 *
 * @param $_name string la chaine de caractères
 * @return la chaine de caractères avec la première lettre en masjuscule
 */
function getCamelCaseForm($_name)
{
	//displayDebug( { 'function' :'getCamelCaseForm', 'param' :$_name });
	return isset($_name) ? ($_name.charAt(0).toUpperCase()) + ($_name.substring(1)) : '';
}
/**
 * Fonction permettant de récupérer la valeur d'un champ de formulaire que ce soit une liste de sélection, un champ test ou testarea.
 * Pour cela, lui passer l'id de l'élément du formulaire. 
 * Pour le moment, elle contient les éléments de base d'un formulare, à faire évoluer si nécessaire
 *
 * @param string l'id de l'élément HTML du formulaire
 * @param HTMLElement l'élément HTML en question ($_di doit être null
 * @return la valeur du champ du fomulaire ou null si le champ n'a pas été trouvé
 */
function getFieldValue(/*string*/$_id/*HTMLElement $_HTMLelement*/)
{
	displayDebug('getFieldValue', Array($_id, arguments[1]), false);
	if (DOM.get($_id))
		var el = DOM.get($_id);
	else
	{
		if (isset(arguments[1]))
			var el = arguments[1];
	}
	if (isset(el))
	{
		switch (el.tagName)
		{
			case 'TEXTAREA':
				displayDebug('getFieldValue : TEXTAREA', el.innerHTML, false);
				return el.value;
				break;
			case 'IMG':
				displayDebug('getFieldValue : IMG', el.src, false);
				return el.src;
				break;
			case 'INPUT':
				switch (el.type)
				{
					case 'text':
					case 'TEXT':
					case 'PASSWORD':
					case 'password':
					case 'HIDDEN':
					case 'hidden':
					case 'RADIO':
					case 'radio':
					case 'FILE':
					case 'file':
						displayDebug('getFieldValue : INPUT', el.value, false);
						return el.value;
						break;
					case 'CHECKBOX':
					case 'checkbox':
						displayDebug('getFieldValue : INPUT', el.checked, false);
						return ((el.checked == 'on' || el.checked) ? 1 : 0);
						break;
					case 'IMAGE':
					case 'image':
						displayDebug('getFieldValue : INPUT', el.src, false);
						return el.src;
						break;
					default:
						displayDebug('getFieldValue : default', el.innerHTML, true);
						return el.innerHTML;
						break;
				}
				break;
			case 'SELECT':
				displayDebug('getFieldValue : SELECT', el.options[el.selectedIndex].value, false);
				return el.options[el.selectedIndex].value;
				break;
			default:
				displayDebug('getFieldValue : default', el.innerHTML, true);
				return el.innerHTML;
				break;
		}
		return null;
	}
	else
		return null;
}
/**
 * Fonction permettant de définir la valeur d'un champ de formulaire que ce soit une liste de sélection, un champ test ou testarea.
 * Pour cela, lui passer l'id de l'élément du formulaire. 
 * Pour le moment, elle contient les éléments de base d'un formulare, à faire évoluer si nécessaire
 *
 * @param string l'id de l'élément HTML du formulaire
 * @param mixed la valeur
 * @return la valeur du champ du fomulaire ou null si le champ n'a pas été trouvé
 */
function setFieldValue(/*string*/$_id,/*HTMLElement*/$_value)
{
	displayDebug('setFieldValue', Array($_id, $_value), false);
	if (DOM.get($_id))
		var el = DOM.get($_id);
	if (isset(el))
	{
		switch (el.tagName)
		{
			case 'TEXTAREA':
				el.value = $_value;
				var error = false;
				try
				{
					el.innerHTML = $_value;
				}
				catch (e)
				{
					error = true;
					displayDebug('setFieldValue : TEXTAREA', e, true);
				}
				if (error)
				{
					try
					{
						el.innerText = $_value;
					}
					catch (e)
					{
						displayDebug('setFieldValue : TEXTAREA', e, true);
					}
				}
				displayDebug('setFieldValue : TEXTAREA', el.innerHTML, false);
				return el.value;
				break;
			case 'IMG':
				el.src = $_value;
				el.setAttribute('src', $_value);
				displayDebug('setFieldValue : IMG', el.src, false);
				return el.src;
				break;
			case 'INPUT':
				switch (el.type)
				{
					case 'text':
					case 'TEXT':
					case 'PASSWORD':
					case 'password':
					case 'HIDDEN':
					case 'hidden':
					case 'RADIO':
					case 'radio':
					case 'FILE':
					case 'file':
						el.value = $_value;
						el.setAttribute('value', $_value);
						displayDebug('setFieldValue : INPUT', el.value, false);
						return el.value;
						break;
					case 'CHECKBOX':
					case 'checkbox':
						if ($_value)
						{
							el.setAttribute('checked', 'checked');
							el.checked = true;
						}
						else
						{
							el.removeAttribute('checked');
							el.checked = false;
						}
						displayDebug('setFieldValue : INPUT', el.checked, false);
						return ((el.checked == 'on' || el.checked) ? 1 : 0);
						break;
					case 'IMAGE':
					case 'image':
						el.src = $_value;
						displayDebug('setFieldValue : INPUT', el.src, false);
						return el.src;
						break;
					default:
						el.innerHTML = $_value;
						displayDebug('setFieldValue : default', el.innerHTML, true);
						return el.innerHTML;
						break;
				}
				break;
			case 'SELECT':
				var options = el.options;
				var nbOptions = options.length;
				for( var index = 0; index < nbOptions; index++)
				{
					if (options[index].value == $_value)
					{
						el.selectedIndex = index;
						options[index].setAttribute('selected', 'selected');
					}
					else
						options[index].removeAttribute('selected');
				}
				displayDebug('setFieldValue : SELECT', el.options[el.selectedIndex].value, false);
				return el.options[el.selectedIndex].value;
				break;
			default:
				var error = false;
				try
				{
					el.innerHTML = $_value;
				}
				catch (e)
				{
					error = true;
					displayDebug('setFieldValue : default', e, true);
				}
				if (error)
				{
					try
					{
						el.innerText = $_value;
					}
					catch (e)
					{
						displayDebug('setFieldValue : default', e, true);
					}
				}
				displayDebug('setFieldValue : default', el.innerHTML, true);
				return el.innerHTML;
				break;
		}
	}
	else
		return null;
}
/**
 * Méthode qui supprime les accent dans une chaine
 * @param string $_expression : la chaine
 * @return string
 */
function removeAccents(/*string*/$_expression)
{
	var str = $_expression;
	var patternAccent = new Array("é", "è", "ê", "ë", "ç", "à", "â", "ä", "î", "ï", "ù", "ô", "ó", "ö");
	var patternReplaceAccent = new Array("e", "e", "e", "e", "c", "a", "a", "a", "i", "i", "u", "o", "o", "o");
	if ($_expression && $_expression != "")
	{
		for( var i = 0; i < patternAccent.length; i++)
		{
			while (str.indexOf(patternAccent[i]) != -1)
				str = str.replace(patternAccent[i], patternReplaceAccent[i]);
		}
	}
	return str;
}
/** 
 * Supprime les espaces inutiles en début et fin de chaine
 * @param string $_expression : la chaine
 */
function trim(/*string*/$_expression)
{
	if (typeof ($_expression) != 'undefined' && $_expression.length > 0)
	{
		var regExpBeginning = /^\s+/;
		var regExpEnd = /\s+$/;
		return $_expression.replace(regExpBeginning, '').replace(regExpEnd, '');
	}
	return $_expression;
}
function ucfirst($_expression)
{
	if ($_expression.length > 0)
		return $_expression[0].toUpperCase() + $_expression.substring(1);
	else
		return $_expression;
}
/**
 * Affiche le contenu d'un tableau
 * @param $_array			le tableau
 * @param [$_showInAlert] 	affiche dans une popup (sinon retourne le contenu)
 * @return String|void
 */
function print_r(/*Array */$_array, /*bool*/$_showInAlert)
{
	var content = '';
	if ((isArray($_array) && $_array.length > 0) || isObject($_array))
	{
		for( var prop in $_array)
		{
			content += "\n " + prop + " => " + $_array[prop];
		}
	}
	if (typeof (arguments[1]) == 'undefined' || arguments[1] == true)
		return alert(content);
	else
		return content;
}
/**
  * Renvoit le symbole HTML pour une devise en ISO
  * @return string
  */
function getCurrencySymbol($_currency)
{
	var symbol = '';
	switch ($_currency.toUpperCase())
	{
		case 'EUR':
			symbol = '&euro;';
			break;
		case 'USD':
			symbol = '$';
			break;
	}
	return symbol;
}
/**
 * Arrondit un nombre décimal
 * @param $_value		le nombre flottant à arrondir
 * @param [$_nbDecimal (default=2)] le nombre de décimales souhaité
 */
function round(/*Float*/$_valueSource, /*Integer*/$_nbDecimal)
{
	var value = (typeof ($_valueSource) == 'object') ? $_valueSource.value : '' + $_valueSource;
	var nbDecimal = (typeof (arguments[1]) != 'undefined') ? $_nbDecimal : 2;
	operande = Math.pow(10, parseInt(nbDecimal));
	return Math.round(parseFloat(value) * Math.pow(10, $_nbDecimal)) / Math.pow(10, $_nbDecimal);
}
/**
 * Classe qui valide les types de données
 * 1. vérifie par rapport au type attendu
 * 2. formate la valeur dans le type atendu si nécessaire
 */
var Format = { CURRENCY_CODE :'\u20AC', PERCENT :'%',
/**
 * Méthode générique
 * Vérifie le format d'une valeur
 * @param HTMLElement|String	$_valueSource	valeur à vérifier
 * @param String				$_sigle			le sigle à acoller à la valeur (Euro, poucentage, kg, ...)
 * @return String	 la valeu r formatée
 */
as : function(/*HTMLElement|String*/$_valueSource, /*String*/$_sigle)
{
	var valueToCheck = (isObject($_valueSource)) ? $_valueSource.value : '' + $_valueSource;
	if (valueToCheck.indexOf($_sigle) == -1)
		valueToCheck += ' ' + $_sigle;
	if (isObject($_valueSource))
		$_valueSource.value = valueToCheck;
	return valueToCheck;
},
/**
 * Vérifie et formate une valeur flottante à 2 décimales
 * @param String|HTMLElement	$_valueSource	valeur ou object contenant la valeur à vérifier
 * param  String [$_sigle]		sigle à apposer à la valeur (ex: %, Euro)
 * @return Float
 */
asFloat : function(/* HTMLElement*/$_valueSource, /*String*/$_sigle)
{
	var sigle = (typeof (arguments[1]) != 'undefined') ? $_sigle : '';
	var valueToCheck = (typeof ($_valueSource) == 'object') ? $_valueSource.value : '' + $_valueSource;
	var exp = new RegExp('^[0-9-.]+$', 'g');
	// que des chiffres ?
	if (exp.test(valueToCheck))
	{
		// pas de point ni décimale
		if (valueToCheck.indexOf('.') < 0)
			valueToCheck += '.00';
		// le point existe mais pas de décimale
		else
			if (valueToCheck.indexOf('.') == valueToCheck.length - 1)
				valueToCheck += '00';
			// le point existe mais avec 1 seule décimale (format attendu : 2 décimales) -> on rajoute 1 décimale	
			else
				if (valueToCheck.indexOf('.') > -1 && valueToCheck.split('.')[1].length == 1)
					valueToCheck += '0';
				// le point existe mais avec 3 décimales (1 de trop) -> la valeur sera tronquée	
				else
					if (valueToCheck.indexOf('.') > -1 && valueToCheck.split('.')[1].length > 2)
						valueToCheck = valueToCheck.substr(0, valueToCheck.length - 1);
	}
	if (isObject($_valueSource))
		$_valueSource.value = valueToCheck + (($_valueSource.value.indexOf(sigle) == -1) ? sigle : '');
	return valueToCheck;
},
/**
 * Vérifie qu'une valeur de type monétaire a bien le sigle associé à sa devise
 * Soit la valeur de l'objet est mis à jour soit la valeur elle meme l'est 
 * @param HTMLElement|String	$_valueSource
 * @param Integer $_nbDecimal	nombre de décimales
 * @return String
 */
asCurrency : function(/*HTMLElement|String*/$_valueSource, /*Integer*/$_nbDecimal)
{
	if (typeof (arguments[1]) != 'undefined')
		return Format.as(Format.asFloat(round($_valueSource, 2)), Format.CURRENCY_CODE);
	//return round(Format.as($_valueSource, Format.CURRENCY_CODE), $_nbDecimal);
	else
		return Format.as($_valueSource, Format.CURRENCY_CODE);
},
/**
 * Vérifie le format d'une valeur de pourcentage
 * Formatte la valeur si besoin
 * @param HTMLElement|String	$_valueSource 
 * @return String 	la valeur formatée
 */
asPercent : function($_valueSource)
{
	return Format.as($_valueSource, Format.PERCENT);
} };
/**
 * Raccourci pour récupérer la valeur d'un noeud enfant XML
 * Vérifie que le noeud existe et renvoit sa valeur
 * Par défaut le 1er noeud enfant est vérifié
 * @param XMLNode $_node		le noeud XML
 * @param int [$_childIndex]	index du noeud enfant
 * @return String
 */
function getNodeValue($_node/*, $_childIndex*/)
{
	if (isObject($_node))
	{
		var childIndex = (typeof (arguments[1]) != 'undefined') ? $_childIndex : -1;
		var valueReturn = '';
		if (childIndex == -1 && $_node.firstChild && $_node.firstChild.nodeValue)
			valueReturn = $_node.firstChild.nodeValue;
		else
			if (childIndex >= 0 && $_node.childNodes[childIndex] && $_node.childNodes[childIndex].nodeValue)
				valueReturn = $_node.childNodes[childIndex].nodeValue;
		return XML.removeCDATA(valueReturn);
	}
	return '';
};
/**
 * Transform un document XML en une String
 * @param $_xmlDocument
 * @return String|void
 */
function XMLToString(/*XMLDocument*/$_xmlDocument)
{
	try
	{
		return new XMLSerializer().serializeToString($_xmlDocument);
	}
	catch (e)
	{
		alert(e.message);
		return '';
	}
};
var XML = {};
/**
 * Supprime l'instruction <![CDATA[]]> d'une valeur de noeud XML
 */
XML.removeCDATA = function($_string)
{
	//Verify whether this is a CDATA string
	if ($_string.substring(0, 9) == "<![CDATA[")
	{
		//Removing <![CDATA[
		$_string = $_string.substring(9, $_string.length);
		//Removing ]]>
		$_string = $_string.substring(0, $_string.length - 3);
	}
	else
		if ($_string.substring(0, 12) == "&lt;![CDATA[")
		{
			//Removing &lt;![CDATA[
			$_string = $_string.substring(12, $_string.length);
			//Removing ]]&lt;
			$_string = $_string.substring(0, $_string.length - 6);
		}
	return $_string;
};
XML.addCDATA = function($_string)
{
	return '<![CDATA[' + $_string + ']]>';
};
/**
 * Cette classe statique sert uniquement pour WeMarketEbay actuellement
 * Son rôle est de vérifier la validité du formulaire d'ajout de produit vers eBay
 * 1. Elle récupère via Ajax un modèle XML fourni par le Web Service de WeMarketEbay 
 * qui décrit les types des différentes propriété d'un item eBay
 * ex: <Item.StartPrice>float</float>
 * 2. Elle parcourre le formulaire de produit à vendre
 * 3. Elle compare le type attendu avec le type de la valeur du champ du formulaire
 * 4. Soit elle annule l'envoi du formulaire si erreurs et met en évidence les éléments erronés 
 * 5. Soit elle soumet le formulaire
 * @return void
 */
var FORM = {};
/**
 * Crée une chaine de tous les éléments d'un formulaire pour un envoi POST via Ajax
 * @param string|HTMLFormElement 	$_form		formulaire dont les éléments sont à sérialiser
 * @param array 	$_elsToAdd 	autres éléments à rajouter en plus de ceux du formulaire $_form
 * @return string
 */
FORM.serialize = function($_form /*, $_elsToAdd*/)
{
	if (!isObject($_form) && isObject(DOM.get($_form)))
		$_form = DOM.get($_form);
	if (!isObject($_form))
		return '';
	var $_elsToAdd = isArray(arguments[1]) ? arguments[1] : [];
	var els = $_form.elements;
	var data = [];
	if (els.length > 0)
	{
		for( var idx in els)
		{
			if (typeof (els[idx]) == 'object' && els[idx].getAttribute('name') != null)
			{
				switch (els[idx].tagName.toLowerCase())
				{
					case 'input':
						switch (els[idx].getAttribute('type'))
						{
							case 'checkbox':
								data.push(els[idx].name + '=' + ((els[idx].checked == true) ? els[idx].value : 'off'));
								break;
							case 'radio':
								if (els[idx].checked == true)
									data.push(els[idx].name + '=' + trim(els[idx].value));
								break;
							default:
								data.push(els[idx].name + '=' + trim(els[idx].value));
						}
						break;
					case 'select':
						if (els[idx].getAttribute('multiple') == 'multiple')
						{
							elName = els[idx].name + ((els[idx].name.indexOf('[]') == -1) ? '[]' : '');
							for( var b = 0; b < els[idx].options.length; b++)
							{
								if (els[idx].options[b].selected == true)
									data.push(elName + '=' + trim(els[idx].value));
							}
						}
						else
							data.push(els[idx].name + '=' + trim(els[idx].value));
						break;
					default:
						data.push(els[idx].name + '=' + trim(els[idx].value));
						break;
				}
			}
		}
	}
	if (count($_elsToAdd) > 0)
	{
		for( var elIndex in $_elsToAdd)
			data.push(elIndex + '=' + $_elsToAdd[elIndex]);
	}
	return data.join('&');
};
/**
 * Cache du schema XML des types de données
 * @var Array
 */
FORM.schema = null;
/**
 * Récupère en Ajax le schéma XML des types attendus par eBay
 * @return void
 */
FORM.loadSchema = function()
{
	var parameters = "action=getObjectSchema";
	doAjaxRequest('POST', EBAY_OBJECT_WEBSERVICE_URL, parameters, 'FORM.storeSchema', 'XML');
};
/**
 * Fonction de Callback et de cache qui stocke le schéma XML dans une variable statique
 * @param XmlHttpRequest 	$_response		l'objet qui encapsule la réponse XML
 * @return void
 */
FORM.storeSchema = function($_response)
{
	// si la réponsee st au format XML on procède au stockage
	if (isObject($_response) && $_response.responseXML)
		FORM.schema = $_response.responseXML;
};
/**
 * Valide les élément d'un formulaire
 * @param string $_formName : nom du formulaire à scanner
 * @return void
 */
FORM.validate = function(/*string*/$_formName)
{
	if (document.forms[$_formName] && document.forms[$_formName].elements.length > 0 && isObject(FORM.schema))
	{
		// tableau qui va contenir les messages d'erreur présentés à l'utilisateur
		var fieldsValueExpectedTypeMessage = new Array();
		// tableau qui va contenir les pointeurs vers les éléments du formulaire
		var DOMElements = new Array();
		// parcours des éléments du formulaire
		for( var a = 0; a < document.forms[$_formName].elements.length; a++)
		{
			// pointeur courant
			var formElement = document.forms[$_formName].elements[a];
			/* on vérifie que l'ID de l'élément est de type "object[propriété]"
			 * ex : <input type="text" id="object[StartPrice]" name="object[StartPrice]" />
			 */
			if (formElement.id.indexOf($_formName) > -1)
			{
				// récupération 'propre' de l'élément dans le DOM
				var DOMElement = DOM.get(formElement.id);
				// on récupère le label associé à l'élément
				var labelFor = DOM.get('label_' + DOMElement.id);
				/** on poursuit uniquement si l'élément est associé à un label
				 * car sinon on peut pas vérifier si l'élément est obligatoire ou non
				 * de plus : si le label existe pas, il peut s'agir d'un élément passif
				 */
				if (labelFor)
				{
					var attributeExplode = formElement.id.split('[');
					// nom de l'attribut qui va servir a la comparaison de type avec le schema XML
					var attributeName = attributeExplode[attributeExplode.length - 1].split(']')[0];
					var fieldLabel = labelFor.firstChild.nodeValue;
					// valeur saisie par l'utilisateur dans le champs courant 
					var fieldValue = trim(formElement.value);
					// élément obligatoire ou pas
					var fieldIsRequired = (labelFor.innerHTML.indexOf('*') > -1);
					// on ne procède à les comparaison de type que sur des éléments obligatoires
					if (fieldIsRequired)
					{
						// stockage du ponteur de l'élement dans le tableau
						DOMElements[a] = DOMElement;
						var wrongValue = 0;
						/*
						 * On vérifie ici que l'élément qui permettent une saisie libre (text, textarea) 
						 */
						if (formElement.type == 'text' || formElement.type == 'textarea')
						{
							// On récupère le type s'il existe, puis on le compare avec la donnée saisie dans le formulaire
							if (FORM.schema.getElementsByTagName(attributeName).length > 0)
							{
								var attributeTypeNode = FORM.schema.getElementsByTagName(attributeName)[0];
								var attributeValueType = attributeTypeNode.childNodes[0].nodeValue.toUpperCase();
								if (attributeValueType)
								{
									// le type est INTEGER -----------------------------------------------------------------
									if (attributeValueType.indexOf('INT') > -1)
									{
										// erreur : le champs est vide
										if (fieldValue.length < 1)
											wrongValue++;
										// erreur : ce n'est pas pas un nombre
										if (isNaN(fieldValue))
											wrongValue++;
										// ajout d'un message d'erreur pour l'utilisateur
										if (wrongValue > 0)
											fieldsValueExpectedTypeMessage[a] = 'nombre entier requis (ex: 15)';
									}
									// le type est DOUBLE /FLOAT ------------------------------------------------------------------
									else
										if (attributeValueType.indexOf('DOUBLE') > -1 || attributeValueType.indexOf('FLOAT') > -1)
										{
											// pas de '.'
											if (fieldValue.indexOf('.') < 1)
												wrongValue++;
											// moins de 2 dicémales après le '.'
											if (fieldValue.indexOf('.') > 0 && (fieldValue.split('.').length > 0) && fieldValue.split('.')[1].length < 2)
												wrongValue++;
											// ajout d'un message d'erreur pour l'utilisateur
											if (wrongValue > 0)
												fieldsValueExpectedTypeMessage[a] = 'nombre décimal requis (ex: 1.00)';
										}
										// le type est STRING ------------------------------------------------------------------
										else
											if (attributeValueType.indexOf('STRING') > -1)
											{
												// erreur : chaine vide
												if (fieldValue.length < 1)
													wrongValue++;
												// erreur : c'est un nombre
												if (!isNaN(fieldValue))
													wrongValue++;
												// ajout d'un message d'erreur pour l'utilisateur
												if (wrongValue > 0)
													fieldsValueExpectedTypeMessage[a] = 'chaîne requise';
											}
											// le type est URI 	--------------------------------------------------------------------
											else
												if (attributeValueType.indexOf('URI') > -1 || attributeValueType.indexOf('URL') > -1)
												{
													// erreur : la saisie ne contient pas 'http'
													if (fieldValue.indexOf('http') == -1)
														wrongValue++;
													// ajout d'un message d'erreur pour l'utilisateur
													if (wrongValue > 0)
														fieldsValueExpectedTypeMessage[a] = 'URL requise (ex: http://www.domaine.com/resource.html)';
												}
												// Aucune erreur -----------------------------------------------------------------------
												else
												{
													// on crée quand même un message vide, pour ne pas décaler le mapping entre la pile 
													// des messages et la pile des éléments du formulaire
													fieldsValueExpectedTypeMessage[a] = ' ';
												}
								}
							}
							// Si le schema des types ne contient pas d'information pour l'attribut obligatoire
							// et qu'il s'agit d'un type texte vide :
							else
								if (formElement.type == 'text' && trim(fieldValue) == '')
								{
									// ajout d'un message d'erreur pour l'utilisateur
									fieldsValueExpectedTypeMessage[a] = 'chaîne requise';
								}
						}
						/**
						 * On vérifie un élément obligatoire à choix fermé (ici : liste déroulante)
						 * La valeur de l'élement n'est jamais erronée puisque les valeurs sont prédéfinies
						 * mais si un choix est proposé et que l'utilisateur n'en fait pas, il y a une erreur
						 */
						else
						{
							// le champs est obligatoire mais l'utilisateur n'a pas fait de choix
							if (fieldValue == '' || fieldValue == '-10')
								wrongValue++;
							// ajout d'un message d'erreur pour l'utilisateur								
							if (wrongValue > 0)
								fieldsValueExpectedTypeMessage[a] = 'choix requis';
						}
					}
				}
			}
		}
		var formContainsErrors = 0;
		// parcours des piles des éléments stockés et messages d'erreur associés
		for( var index in DOMElements)
		{
			if (typeof (DOMElements[index]) != 'undefined' && DOMElements[index].id)
			{
				var currentElement = DOMElements[index];
				var currentExpectedTypeMessage = fieldsValueExpectedTypeMessage[index];
				// on met visuellement en évidence l'élement erroné	
				if (currentElement && currentElement.parentNode)
				{
					if (typeof (currentExpectedTypeMessage) != 'undefined')
					{
						// application d'une CSS "champ erroné"
						currentElement.className = 'FormElementWrong';
						formContainsErrors++;
					}
					else
						if (currentElement.className == 'FormElementWrong')
						{
							// le champe est valide : on annule la CSS "champ erroné" 
							currentElement.className = 'FormElement';
						}
				}
			}
		}
	}
	/**
	 * s'il y a eu verification du formulaire (pile d'éléments non vide) et qu'il n'y a pas d'erreur
	 * on envoie le formulaire 
	 */
	if (DOMElements.length > 0 && formContainsErrors == 0)
		DOM.get($_formName).submit();
	// sinon pas d'envoi, et les éléments erronés sont déjà marqués visuellement
};
/**
 * Variable d'animation qui permet de conserver son instance
 */
var anim;
var idElement;
var attributesAnimation;
/**
 * Fonction qui montre un élément à l'aide d'une animation YUI
 */
function showEl($_id)
{
	idElement = $_id;
	attributesAnimation = { opacity : { from :0, to :1 } };
	newFade();
}
/**
 * Fonction qui montre un élément à l'aide d'une animation YUI
 */
function hideEl($_id)
{
	idElement = $_id;
	attributesAnimation = { opacity : { from :1, to :0 } };
	newFade();
}
/**
 * Fonction qui crée une instance de l'animation et la lance
 */
function newFade()
{
	anim = new YAHOO.util.Anim(idElement, attributesAnimation, 2, YAHOO.util.Easing.easeOut);
	anim.animate();
}
/**
 * Renvoit le nom du script qui est dans l'URL
 * par défaut sans l'extension
 * @param bool (optional) $_withExtension	extension o/n
 * @return string
 */
function getFilename(/*$_withExtension*/)
{
	$_withExtension = (typeof (arguments[0]) != 'undefined') ? arguments[0] : false;
	var slashRegExp = new RegExp('/');
	filename = parse_url(location.href, 'PHP_URL_PATH').replace(/\/(.*)\//, '').replace(slashRegExp, '');
	if ($_withExtension == true)
		return filename;
	return filename.substr(0, filename.lastIndexOf('.'));
}
/**
 * Fonction like parse_ul de php
 * @param $_str
 * @param $_component
 * @return string|object
 */
function parse_url($_str, $_component)
{
	// http://kevin.vanzonneveld.net
	// +      original by: Steven Levithan (http://blog.stevenlevithan.com)
	// + reimplemented by: Brett Zamir (http://brettz9.blogspot.com)
	// %          note: Based on http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
	// %          note: blog post at http://blog.stevenlevithan.com/archives/parseuri
	// %          note: demo at http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
	// %          note: Does not replace invaild characters with '_' as in PHP, nor does it return false with
	// %          note: a seriously malformed URL.
	// %          note: Besides function name, is the same as parseUri besides the commented out portion
	// %          note: and the additional section following, as well as our allowing an extra slash after
	// %          note: the scheme/protocol (to allow file:/// as in PHP)
	// *     example 1: parse_url('http://username:password@hostname/path?arg=value#anchor');
	// *     returns 1: {scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor'}
	var o = { strictMode :false, key : [ "source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor" ], q : { name :"queryKey", parser :/(?:^|&)([^&=]*)=?([^&]*)/g }, parser : { strict :/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, loose :/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-protocol to catch file:/// (should restrict this)
	} };
	var m = o.parser[o.strictMode ? "strict" : "loose"].exec($_str),uri = {},i = 14;
	while (i--)
	{
		uri[o.key[i]] = m[i] || "";
	}
	// Uncomment the following to use the original more detailed (non-PHP) script
	/*
	    uri[o.q.name] = {};
	    uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
	    if ($1) uri[o.q.name][$1] = $2;
	    });
	    return uri;
	*/
	switch ($_component)
	{
		case 'PHP_URL_SCHEME':
			return uri.protocol;
		case 'PHP_URL_HOST':
			return uri.host;
		case 'PHP_URL_PORT':
			return uri.port;
		case 'PHP_URL_USER':
			return uri.user;
		case 'PHP_URL_PASS':
			return uri.password;
		case 'PHP_URL_PATH':
			return uri.path;
		case 'PHP_URL_QUERY':
			return uri.query;
		case 'PHP_URL_FRAGMENT':
			return uri.anchor;
		default:
			var retArr = {};
			if (uri.protocol !== '')
			{
				retArr.scheme = uri.protocol;
			}
			if (uri.host !== '')
			{
				retArr.host = uri.host;
			}
			if (uri.port !== '')
			{
				retArr.port = uri.port;
			}
			if (uri.user !== '')
			{
				retArr.user = uri.user;
			}
			if (uri.password !== '')
			{
				retArr.pass = uri.password;
			}
			if (uri.path !== '')
			{
				retArr.path = uri.path;
			}
			if (uri.query !== '')
			{
				retArr.query = uri.query;
			}
			if (uri.anchor !== '')
			{
				retArr.fragment = uri.anchor;
			}
			return retArr;
	}
}
/**
 * tableau brut de la QueryString
 * @var Array
 */
var GETraw = GET = new Array();
/**
 * Récupère un paramètre en GET (dans l'URL)
 * Equivalent du $_GET de PHP
 * @param $_parameter string le nom du paramètre en get
 * @return string|null
 */
function $_GET($_parameter)
{
	if (GETraw.length == 0 && location.href.indexOf('?') > -1)
	{
		var cleanLoc = '';
		if (location.href.indexOf('#') > -1)
			cleanLoc = location.href.substr(0, location.href.indexOf('#'));
		else
			cleanLoc = location.href;
		if (location.href.indexOf('&') > -1)
			GETraw = cleanLoc.split('?')[1].split('&');
		else
			GETraw = [ cleanLoc.split('?')[1] ];
		for( var a = 0; a < GETraw.length; a++)
		{
			GET[GETraw[a].split('=')[0]] = GETraw[a].split('=')[1];
		}
	}
	if (count(GET) > 0)
	{
		switch ($_parameter)
		{
			case 'any':
				return GET;
				break;
			default:
				if (isset(GET[$_parameter]))
					return GET[$_parameter];
				break;
		}
	}
	return null;
}
