/*============================================================================================
 Fichier Javascript
 Fichier contenant divers Fonction systeme

 AUTEUR:					Alban BALLIEUX
 CREATION:					07/07/2008
 VARIABLE GLOBALES:
 MODIFICATIONS:
	Cédric POUYEZ	- 04/12/2008 - Ajout de  Str_pos
	Alban BALLIEUX	- 18/12/2008 - Ajout de la function SetFocus
				- 18/12/2008 - Ajout de isFunction
				- 20/02/2009 - CreePtId
				- 21/08/2009 - Modification de GetPtId, ajout de l'idpere
	Fabien THIERRY	- 14/01/2010 - Correction d'un bug dans InitBoxOver avec MSIE (Bloquait la page!)
===============================================================================================
	copyright 2009 Alban BALLIEUX - ballieuxa@laon.noirot
	http://www.phpmyportal.info

	This file is part of phpMyPortal.

    phpMyPortal is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or
    any later version.

    phpMyPortal is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with phpMyPortal; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===============================================================================================*/
/**
 * Fonction qui retourne un identifiant en fonction du parametre
 * si l'on passe un identifiant il le retourne sinon il va essayer de le créer
 * Retourne false s'il y a un probléme
 * 
 * @param {Object} id		string / pt
 * @param {Object} idPere	(optionnel:defaut=document)string / pt			Represente l'idenfiant conteneur (
 * 
 * @return {Object}			pt sur l'objet
 */
function GetPtId(IDa,IdPere){
	if (isObject(IdPere)){
		IdPere=GetPtId(GetPtId);
		if (!IdPere){
			IdPere=document;
		}
	}else{
		IdPere=document;
	}
	if (!isObject(IDa)){	
		if (IdPere.id == IDa) return document;
		if (isObject(IdPere.getElementById(IDa))){
			return IdPere.getElementById(IDa);
		}else{
			return false;
		}
	}
	return IDa;
}

/**
 * Recupération du parent le plus haut d'un type defini
 * 
 * @param {Object} obj		Objet source
 * @param {Object} Type		Type d'objet à rechercher
 * 
 * @return {Object}			Objet trouvé ou false en cas d'erreur ou que l'objet n'as pas été trouvé
 */
function GetParentElement(obj,Type){
	if (!isString(Type)) 		return false;
	if (!isset(obj)) 			return false;
	if (!isset(obj.parentNode)) return false;
	obj = obj.parentNode;
	while(obj.tagName!=Type){
		if (obj == document) 		return false;
		obj=obj.parentNode;
	}
	return obj;
}

/**
 * Fonction qui donne le focus à un champ ne fait rien si l'element n'a pas été trouvé
 * 
 * @param {Object} Id		Identifiant de la zone qui doit prendre le focus
 */
function SetFocus(Id){
	Pt = GetPtId(Id);
	if (isObject(Pt)){
		Pt.focus();
	}
}

/*********************************************************************
 * 
 * Liste des tests
 * 
 *********************************************************************/
/**
 * Test l'existance d'un element javascript
 * Permet d'eviter les doublons d'identifiant d'element HTML
 * 
 * @param {Object} ID		Element a tester
 */
function IdExiste(ID){
	return (GetPtId(ID)!=null);
}

/**
 * Test la validité d'un element javascript
 * Regarde si l'element est defini (Attention: Peut etre vide(''))
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isset(O){
	return !(typeof(O)=='undefined' || O==null);
}

/**
 * Test si la variable est un boolean
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isBool(O){
	return (typeof(O)=='boolean');
}

/**
 * Test si la variable est une chaine de caractere
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isString(O){
	return (typeof(O)=='string');
}

/**
 * Test si la variable est une chaine de caractere
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isEmpty(O){
	return ((typeof(O)!='undefined') && O=='');
}

/**
 * Test si la variable est un nombre
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isNumber(O){
	return (typeof(O)=='number');
}

/**
 * Test si la variable est un objet
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isObject(O){
	return (isset(O) && (typeof(O)!='undefined') && typeof(O)=='object');
}

/**
 * Test si la variable est une taille valide php (commence par un ou plusieur numérique et fini par '%' ou 'pt' ou 'px'
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isSize(O){
	if(typeof(O)=='string'){
		return O.match(new RegExp('^([0-9]+)([%]|px|pt)$', 'gi'));
	}
}

/**
 * Test si la variable est une fonction
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function isFunction(O){
	return (typeof(O)=='function');
}

/**
 * Test la valeur de la variable et retourne la valeur booleen
 * ex si la variable est du type string et est égale a "true" la fonction retournera true
 * 
 * @param {Object} O		Element a tester
 * 
 * @return {Bool}			true/false
 */
function vartest(O){
	if (isset(O)){
		if (O=="true"||O=="on") return true;
		if (O=="false"||O=="off") return false;
		return O;
	}else{
		return false;
	}
}

/**
 * Fonction qui test la valeur O et retourne un bool si possible
 * 
 * @param {Object} O		variable a tester
 * 
 * @return {Bool}			true/false
 */
function varBool(O){
	if (isBool(O)){
		return O;
	}else{
		if (O=='true') return true;
		if (O=='false') return true;
		return O;
	}
}

/*********************************************************************
 * 
 * Inclusion de fichiers
 * 
 *********************************************************************/

/**
 * Fonction d'inclusion de fichier javacript
 * Ajout le code dans le head de la page
 * 
 * @param {string} filename			Chemin complet du fichier à inclure
 */
function inc(filename){
// Je regarde si le fichier n'a pas deja été inclus
	if (isset(document.documentElement.innerHTML.match(new RegExp('src="'+filename+'"', 'gi')))) return;

	var head = document.getElementsByTagName('head').item(0);
	script = document.createElement('script');
	script.src = filename;
	script.type = 'text/javascript';
	head.appendChild(script);
}

/**
 * Fonction d'inclusion de fichier css
 * Ajout le code dans le head de la page
 * 
 * @param {string} filename			Chemin complet du fichier à inclure
 */
function inccss(filename){
// Je regarde si le fichier n'a pas deja été inclus
	if (isset(document.documentElement.innerHTML.match(new RegExp('<link[^<]*'+filename+'[^>]*>', 'gi')))) return;

	var head = document.getElementsByTagName('head').item(0);
	script = document.createElement('link');
	script.href = filename;
	script.type = 'text/css';
	script.rel = 'stylesheet';
	head.appendChild(script);
}

/**
 * Méthode de recupération du chemin d'un fichier déjà inclus
 * 
 * @param {string} filename		Nom du fichier à traiter
 */
function RecuperePath(filename){
	var LstSript=document.getElementsByTagName('script');
	var tmpcpt;
	for (tmpcpt=1;tmpcpt<LstSript.length;tmpcpt++){
		if (isset(LstSript[tmpcpt].src.match(new RegExp('(./)('+filename+')$', 'gi')))){
			return LstSript[tmpcpt].src.replace(new RegExp('(./)('+filename+')$', 'gi'),'$1');
		}
	}
}

/**
 * Affiche un message d'erreur permettant de débugger
 * Si la zone n'existe pas une div 'IDERREUR' est créé
 * Il est possible d'historiser les messages grace au caractère séparateur passé en paramètre
 * S'il n'est pas passé en parametre les messages sont écrasé
 * Les messages peuvent aussi être ajouté a une div existante
 * 
 * @param {Object} MES		Message é affcher
 * @param {Object} Sep		Caractere séparateur
 * @param {Object} Id		(Optionnel)Identitiant de la zone contenant le message
 */
function MessageErreur(MES,Sep,Id){
	if (GetPtId(Id)!=false){
		var IDDIV = GetPtId(Id);
	}else{
		var IDDIV = GetPtId('IDERREUR');
	}
	
	if (!isset(IDDIV)||IDDIV==false){
		var html = document.getElementsByTagName('html').item(0);
		PT = document.createElement('DIV');
		PT.id='IDERREUR';
		html.appendChild(PT);
	}else{
		PT=IDDIV;
	}
	if (!isset(Sep)){
		PT.innerHTML = MES;
	}else{
		PT.innerHTML = PT.innerHTML + Sep + MES;
	}
	return false;
}

/*********************************************************************
 * 
 * Recupération de données 
 * 
 *********************************************************************/

/**
 * Fonction qui recupere toutes les valeurs des elements fils à partir d'un identifiant
 * 
 * @param {string/object} 	element		PtId ou Id identifiant à traiter
 * 
 * @return {array}			Tableau contenant les valeurs de la forme 
 * 							TVal[id][0] = idE[i].value;				valeur
 * 							TVal[id][1] = type;						type (input checkbox...)
 * 							TVal[id][2] = idE[i].name;				name de l'element
 * 							TVal[id][3] = text;						texte de l'element selectionné pour une combo/checkbox
 */
function GetValues(element){
	idE=GetPtId(element);

	return GetValuesID(idE);
}

/**
 * Récupère la valeur d'un élément donné
 */
function GetValue(element){
	idE=GetPtId(element);

	return idE.value;
}

var GTSaveValeur=new Array();

/**
 * Fonction qui retourne le type et la valeur d'un champ donnée dans un tableau (GTSaveValeur)
 * 
 * @param {Object} 	idP		Element pére
 * 
 * @return {array}			Tableau contenant les valeurs de la forme 
 * 							TVal[id][0] = idE[i].value;				valeur
 * 							TVal[id][1] = type;						type (input checkbox...)
 * 							TVal[id][2] = idE[i].name;				name de l'element
 * 							TVal[id][3] = text;						texte de l'element selectionné pour une combo/checkbox
 * 
 */
function SaveValeur(Id){
	TmpT=RecupereValeurs(PtId);
	if (TmpT)GTSaveValeur = TmpT;
}

/**
 * Fonction qui recupere toutes les valeurs des elements fils
 * 
 * @param {Object} 	idP		Element pére
 * 
 * @return {array}			Tableau contenant les valeurs de la forme 
 * 							TVal[id][0] = idE[i].value;				valeur
 * 							TVal[id][1] = type;						type (input checkbox...)
 * 							TVal[id][2] = idE[i].name;				name de l'element
 * 							TVal[id][3] = text;						texte de l'element selectionné pour une combo/checkbox
 * 
 */
function GetValuesID(idP){
	var TVal 	= new Array();
	var nu 		= 0;
	var type 	= '';

// Si l'element n'est pas valide je retourne une erreur
	if (!isObject(idP))	return false;
	
// Je boucle sur toutes les balises inputs
	idE		= idP.getElementsByTagName('input');
	for(i=0; i < idE.length; i++)
	{
	// Je passe l'element s'il n'a pas d'identifiant
		if (!idE[i].id) continue;
	// Appel a la fonction pour formater les valeurs dans un tableau
		TRet=RecupereValeurs(idE[i]);
		if (TRet)	TVal[idE[i].id] = TRet;
	}

// Je boucle sur toutes les listes deroulantes
	idE		= idP.getElementsByTagName('select');
	for(i=0; i < idE.length; i++)
	{
	// Je passe l'element s'il n'a pas d'identifiant
		if (!idE[i].id) continue;
	// Appel a la fonction pour formater les valeurs dans un tableau
		TRet=RecupereValeurs(idE[i]);
		if (TRet)	TVal[idE[i].id] = TRet;
	}
	if (isset(TVal)){
		return TVal;
	}else{
		return false;
	}
}

/**
 * Fonction qui retourne le type et la valeur d'un champ donnée dans un tableau
 * 
 * @param {Object} 	idP		Element pére
 * 
 * @return {array}			Tableau contenant les valeurs de la forme 
 * 							TVal[id][0] = idE[i].value;				valeur
 * 							TVal[id][1] = type;						type (input checkbox...)
 * 							TVal[id][2] = idE[i].name;				name de l'element
 * 							TVal[id][3] = text;						texte de l'element selectionné pour une combo/checkbox
 * 
 */
function RecupereValeurs(PtId){
	PtId=GetPtId(PtId);
	if (!isObject(PtId)) 	return '';
	type = PtId.type;
	name = PtId.id;
	TVal	= new Array();
	if (PtId.tagName.toLowerCase() == 'input'){
		if (type=='radio'||type=='checkbox'){
			if (PtId.checked){
				TVal[0] = PtId.value;
				TVal[1] = type;
				TVal[2] = PtId.name;	
			}
		}else{
			TVal[1] = type;
			TVal[2] = PtId.name;				
			if (type=='text'		||type=='hidden') 		TVal[0]=(PtId.value);
			if (type=='textarea') 							TVal[0]=(PtId.innerHTML);
		}
	}
	if (PtId.tagName.toLowerCase() == 'select'){
		TVal[0] = PtId.value;
		TVal[1] = type;
		TVal[2] = PtId.name;
		if (PtId.selectedIndex != -1){
			TVal[3] = PtId.options[PtId.selectedIndex].text;
		}else{
			TVal[3] = '';
		}
	}
	
	if (TVal.length>0){
		return TVal;
	}else{
		return false;
	}
}

/**
 * Fonction d'initialisation du box over (evenement) 
 */
function InitBoxOver(){
// Je regarde si la zone n'existe pas
	if (GetPtId('DBOXOVER') == false){
	// Je crée la zone
		PtBO=document.createElement('DIV');
		PtBO.id='DBOXOVER';
		PtBO.style.position='absolute';
		PtBO.style.display='none';
		PtBO.name='DBOXOVER';
		if (Div=GetPtId('ElDivers')){
			Div.appendChild(PtBO);
		}
		AjouteEvent('onmousemove', RBoxOver);
	}
}

/**
 * fonction appelée lorsque la souris bouge
 * 
 * @param {Object} e
 */
function RBoxOver(e){
	if (!e) var e = window.event;
	if (typeof BoxOver == 'function' ){
		BoxOver(e);
	}
}

/**
 * Crée un identifiant unique en fonction d'un radical
 * 
 * @param {string} Radical
 * 
 * @return {string}	Identifiant créé
 */
function UniqueId(Radical){
	var UID=0;
	if (!isset(Radical)){
		Radical='';
	}
	while(isset(GetPtId(Radical+UID))){
		UID++;
	}

	return Radical+UID;
}

/**
 * Methode permettant de rendre compatible IE et Firefox pour l'attribut target d'un evenement.
 * PId Pointeur sur l'identifiant de l'element
 * 
 * @param {Object} PId	Pointeur sur l'element parent
 * 
 * @return {Object/false}		PtId sur l'element target ou false s'il y a un problème
 */
function ETarget(PId){
	if (!isset(PId)) 			return false;
	if (isset(PId.target))		return PId.target;
	if (isset(PId.srcElement)) 	return PId.srcElement;
	return false;
}


/*********************************************************************
 * 
 * Explosion de paramètre passé sous forme XML
 * 
 *********************************************************************/

/**
	Fonction de parcage de chaine Xml dans un tableau.
	Dépendence : CBExplodeXML

	NomVar	string	Nom de variable é créer ou é completer
	Xml		string	Chaine de caractére a traiter

	return 	bool/Array	Tableau formaté ou false en cas d'erreur
*/
// Initialisation de la Variable global par defaut
if(!isset(TXML))				var TXML = new Array();
function ExplodeXML(Xml,NomVar){
// J'ajoute le nom de la variable é remplir en entete suivi d'un "#" de la chaine pour qu'elle puisse etre traiter dans l'expression reguliere
	if (!isset(NomVar)){
		window.TXML = new Array();
		NomVar='TXML';
	}
	if (!isObject(window[NomVar])){
		window[NomVar] = new Array();
	}
	Xml = Xml.replace(new RegExp("^<[?][^?]*[?]>", 'gi'),'');
	if ((NomVar+'#'+Xml).replace(new RegExp("(<([^>]+)>)(.*)<\/\\2>", 'gi'),CBExplodeXML)){
		return eval(NomVar);
	}
	return false;
}

/**
	Fonction appellée recursivement pour exploser une chaine XML et la mettre dans un tableau

	Les Parametres sont ceux de l'expression reguliere
*/
function CBExplodeXML(A,B,C,D,E,F,G,H){
// Je recupere le nom de la variable et la profondeur dans le tableau
	Tmp=(new RegExp("^([^#]*)#", 'gi')).exec(F);

// Je prépare la variable
	if (isset(Tmp)){
		Tmp=Tmp[1]+'[\''+C+'\']';
	}else{
		Tmp='[\''+C+'\']';
	}
// J'initialise le tableau si besoin et je mets la valeur
	Val=(new RegExp("^([^<]*)", 'gi')).exec(D);
	if (isset(Val)&&Val[1]!=''){
		Val=Val[1];
	}else{
		Val='';
	}
	eval('if (!isObject('+Tmp+')){'+Tmp+'= new Array();}');
// Je regarde s'il y a une valeur et je l'affecte ou je reboucle pour allé a un niveau supérieur dans l'architecture
	if (isString(Val)){
		eval(Tmp+'=Val;');
	}else{
		Tmp=Tmp+'#'+D;

		Tmp.replace(new RegExp("(<([^>]+)>)(.*)<\/\\2>", 'gi'),CBExplodeXML);
	}
}

/**
 * fonction de rediction ...
 * 
 * @param {Object} URL		Url de redirection
 */
function Redirige(URL){
	document.location=URL;
}

/**
 * Permet de vider un champ
 * 
 * @param {Object} id		Identifiant du champ a vider
 */
function Vide(id){
	GetPtId(id).value='' ;
}

//-------------------------------------------------
// Gestion d'erreurs
//--------------------------------------------------

/**
 * Méthode appelée lors d'une erreur Js
 *
 * @param {Object} msg		Message d'erreur
 * @param {Object} url		Url contenant l'erreur
 * @param {Object} ligne	Ligne de l'erreur
 */
function ActionErreur(msg,url,ligne,test){
	xajax_phpmyportal('LOG_ERR_JS',msg,url,ligne, window.navigator.userAgent);
}

/**
 * Prépare l'evenement d'erreur
 */
function InitGestionErreur(){
	onerror=ActionErreur ;
}

/**
 * Variable globale utilisée par RetardExec
 */
var GRetartExec = new Array();

/**
 * Execute un code à retardement et remet le compteur a zero a chaque nouvel appel
 * Méthode utilisé lors d'une saisie pour enregistré une fois le code finis de tapé 
 * et éviter de d'enregistré sur l'appuie de chaque touche
 * 
 * @param {Object} 	id		Identifiant du timer (permet de gerer plusieur appui de touche
 * @param {Object} 	js		Code javascript executé en fin de timer
 * @param {int} 	delai	Délai d'attente avant enregistrement
 * @param {int} 	Cpt		(privé)Compteur utilisé pour savoir si l'on est au dernier clic
 * @param {int} 	Auto	(privé)0 pour lancer le timer/1 la fonction s'auto appel
 */
function RetardExec(id,js,delai,Cpt,Auto){
// Initialisation du timer sur chaque clic
	if (!isset(Auto))				Auto=0;
	if (!isset(delai))				delai=500;							// temps du rappel
	if (!GRetartExec&&!isset(GRetartExec))		window.GRetartExec=new Array();
	if (!isset(GRetartExec[id]))	window.GRetartExec[id]=0;
	
// Je regarde si l'on a executé la méthode ou si elle se rappelle
	if(Auto!=1){
		GRetartExec[id]=GRetartExec[id]+1;
		js=js.replace(new RegExp("'", "ig"),"\\'");					//On remet les / dans l'appel js
		js2='RetardExec(\''+id+'\',\''+js+'\',1,\''+GRetartExec[id]+'\',1)';
		setTimeout(js2,delai);										//TimeOut d'une seconde
	}else{
		if (GRetartExec[id] == Cpt){
			GRetartExec[id]=0;
			js = js.replace('#VAL#', parseFloat(GetPtId(id).value)); // Affectation de la valeur dans l'input
			eval(js);
		}
	}
}

//-------------------------------------------------
// Gestion des macros
//--------------------------------------------------

/**
 * private
 * 
 * parse les macros d'une chaine
 *  . Macro = #Id#Valeur#
 * 
 * @param {Object} Macro			Macro a parser
 * @param {Object} Id				Identifiant
 * @param {Object} Valeur			Valeur
 */
function CallBackMacro(Macro,Id,Valeur){
	Cpt						= TMacro['CPT']+1;
	TMacro['CPT']			= Cpt;
	TMacro[Cpt]				= new Array();
	ExpId					= new RegExp("([^:]*):([^:]*):(.*)", "ig"); 

	if (Id.match(ExpId)) {
		var IdTable = Id.replace(ExpId, '$1');
		var IdLig = Id.replace(ExpId, '$2');
		var IdCol = Id.replace(ExpId, '$3');
	}
	TMacro[Cpt]['macro'] 	= Macro;
	TMacro[Cpt]['id'] 		= Id;
	TMacro[Cpt]['valeur']	= Valeur;
	TMacro[Cpt]['idtable'] 	= IdTable;
	TMacro[Cpt]['idlig'] 	= IdLig;
	TMacro[Cpt]['idcol'] 	= IdCol;
	
	return true;
}

/**
 * Execute une macro sur une chaine	
 * exemples de macro:
 * ##V#  					Value de la valeur par defaut
 * #TABLE273:1:3#T#  		TextContent de la cellule 1,3 de la table TABLE273
 * #:L+1:C+3#T#  			TextContent de la cellule courante +1 ligne ,+3 colonnes
 * ##A:size#				Valeur de l'attribut size de la valeur par defaut
 * 
 * @param {Object} 		Chaine		Chaine complete contenant les macros
 * @param {Object} 		Id			Identifiant par défaut (Target) quand non specifié dans la macro
 * 
 * @return {string}					Chaine formatée
 */
function Macro(Chaine, Id){
	window['TMacro']		= new Array();
	window['TMacro']['CPT'] = 0;
	var remplace;
	var PtId				= GetPtId(Id);
	var i;
	
// Préparation de la chaine (on mets les valeurs dans la tableau TMacro
	var ExpMacro = new RegExp("#([^#]*)#([^#]*)#", "ig");
	
	Chaine.replace(ExpMacro, CallBackMacro);
	
// Je boucle sur les valeurs
	for (i = 1;i <= window['TMacro']['CPT'];i++){
	// Traitement des tables
		if (isset(TMacro[i]['idtable'])){
			Id = TMacro[i]['idtable'];
			if (GetPtId(Id)!=false){
				var IdTab = GetPtId(TMacro[i]['idtable']);
			}else{
				var IdTab = PtId.offsetParent;
			}
			if (isObject(IdTab)) {
				if (PtId != false) {
					L = PtId.parentNode.rowIndex;
					C = PtId.cellIndex;
				}
				else {
					L = 0;
					C = 0;
				}
				
				L = eval(TMacro[i]['idlig'].replace('L', L));
				C = eval(TMacro[i]['idcol'].replace('C', C));
				
				Id = IdTab.rows[L].cells[C];
			}
		}else{
		// Traitement des elements autre que les tables
			if (GetPtId(TMacro[i]['id'])){
				Id=GetPtId(TMacro[i]['id']);
			}else{
				Id=PtId;
			}
		}
	// Parsage des valeurs et des attributs
		if (TMacro[i]['valeur'].match(new RegExp("[^:]*:([^#]*)"))){
			m 		= TMacro[i]['valeur'].replace(new RegExp("([^:]*):([^#]*)"), '$1');
			Attr 	= TMacro[i]['valeur'].replace(new RegExp("([^:]*):([^#]*)"), '$2');
		}else{
			m		= TMacro[i]['valeur'];
		}
	// Execution de la macro
		remplace=ExecMacro(m,Id, Attr);
		if (isset(remplace)) {
			Chaine = Chaine.replace(TMacro[i]['macro'], remplace);
		}
	}
	return Chaine;
}


/**
 * Fonction Generique de macro javascript
 * 
 * @param {Object} Chaine		Chaine à macroter ...
 * @param {Object} TypeMacro	Nom de la macro à appliquer
 * 'V'	value de l'identifiant
 * 'H'	innerHTML de l'identiant
 * 'T'	textContent de l'identifiant
 * 'A'	Attribut de l'identifiant (Attr: attribut)
 * 
 * @param {Object} Macro	
 * @param {Object} Id			
 * @param {Object} Attr			
 */
function ExecMacro(Macro, Id, Attr){
	var PtId			= GetPtId(Id);
	var ChaineRemplace;
	switch (Macro) {
		case 'V': //ID -> Valeur
			ChaineRemplace = PtId.value;
			break;
		case 'H': //ID -> HTML
			ChaineRemplace = PtId.innerHTML;
			break;
		case 'T': //ID -> text
			ChaineRemplace = PtId.textContent;
			break;
		case 'A': // Récupère l'attribut d'un identifiant (Ex:Identifiant.Attribut)
			while (PtId.tagName != 'HTML' && !isset(eval("GetPtId(PtId)."+Attr)) && isset(PtId.parentNode)) {PtId = PtId.parentNode;}
			if (isset(eval("GetPtId(PtId)."+Attr))){
				ChaineRemplace = eval("GetPtId(PtId)."+Attr);
			}
			break;
	}
	return ChaineRemplace;
}

 //============================================================================================
 //
 //	Fonction mathématiques
 //
 //============================================================================================

/**
 * Fonction d'arrondie, gère le nombre de chiffre après la virgule
 * 
 * @param {float} 	num				le nombre à arrondir
 * @param {int} 	precision		le nombre de chiffre après la virgule
 */
 function round(num, precision){
	 puiss = Math.pow(10,precision);
	 return Math.round(num * puiss)/ puiss;
 }
 
 function Number(Chaine){
 	return Chaine.match(new RegExp("([0-9.,]*)", "ig"))[0];
 }

/**
 * Fonction permettant de creer un timestamp
 * 
 * @return int			timestamp
 */
 function TimeStamp(){
 	return Math.floor((new Date()).getTime() / 1000);
 }
 
 //============================================================================================
 //
 //	Fonction divers
 //
 //============================================================================================

/**
 * Sauvegarde les propriétés d'un element
 * 
 * @param {Object} Id				Identifiant contenant la proprieté a sauvegarder
 * @param {Object} Propriete		Nom de la propriété à Sauvegarder ex: style.backgroundColor
 * @param {Object} Valeur			Nouvelle valeur ... 
 */
function SavEtAppliquePropriete(Id,Propriete,Valeur){
	PtId = GetPtId(Id);
	if (PtId == false) return;
	if (!isset(window.Propriete))						window.Propriete = new Array();
	if (!isset(window.Propriete[PtId.id]))				window.Propriete[PtId.id] = new Array();
	if (!isset(window.Propriete[PtId.id][Propriete]))	window.Propriete[PtId.id][Propriete] = new Array();
	
	if (eval("PtId."+Propriete+"=Valeur;") == Valeur) return;
	
	eval("PtId."+Propriete+"=Valeur;");
	
	window.Propriete[PtId.id][Propriete]=Valeur;
}

/**
 * Restaure les propriétés sauvegardé par SavEtAppliquePropriete
 * 
 * @param {Object} Id				Identifiant contenant la proprieté à restaurer
 * @param {Object} Propriete		Nom de la propriété à restaurer ex: style.backgroundColor
 */
function RestaureEtAppliquePropriete(Id,Propriete){
	PtId = GetPtId(Id);
	if (PtId == false) return;

	if (!isset(window.Propriete[PtId.id][Propriete]))	return;
	
	eval("PtId."+Propriete+"=window.Propriete[PtId.id][Propriete];");
	
	delete window.Propriete[PtId.id][Propriete];
}
 
/**
 * Applique un identifiant a l'id et au name de tous les elements contenu dans IdParent (utilisé par Ajoute_Ligne)
 * A rendre compatible avec les macros ... ;-)
 * 
 * @param {object} 	IdParent	objet parent
 * @param {int} 	Index		Chaine à ajouté à la suite de l'identifiant
 */
 function AppliqueIndexId(IdParent, Index){
 	if (!GetPtId(IdParent))	return false;
 	
 	var T = GetPtId(IdParent).children;
 	
 	if (T.length > 0){
	 	for (I in T){
	 		if (GetPtId(T[I])){
	 			if (T[I].nodeName=="INPUT" || T[I].nodeName=="SELECT"){
			 		if (T[I].id != ''){
			 			T[I].id = T[I].id + Index;
			 		}
			 		if (T[I].name != ''){
			 			T[I].name = T[I].name + Index;
			 		}
		 		}
		 		AppliqueIndexId(T[I], Index);
	 		}
	 	}
 	}
 	return true;
 }
 
/**
 * Recupere le nom du navigateur ... 
 *
 */ 
function Navigateur(){
	return navigator.appName;
}

/**
 * Fonction permettant de valider un formulaire
 *
 * string		Id		Identifiant du formulaire a valider
 */
function Submit(Id){
	var PtId = GetPtId(Id);
	if (PtId != false){
		PtId.submit();
	}
}
 //============================================================================================
 //
 //	Fonction de compatibilité IE
 //
 //============================================================================================
 
 /**
  * Recupere le dernier identifiant enfant
  *
 * @param {object} 	Id 			Identifiant parent
  */
 function getLastElementChild(Id){
 	return GetPtId(Id.children[Id.children.length-1]);
 }
 