var debug=false;
var tabChamp=new Array();
var form=null;
var annuler=true;

function valider(formulaire)
{	
	if(formulaire.hidden_validation)
	{
		//alert("valider = "+formulaire.hidden_validation.value);
		if(formulaire.hidden_validation.value=="0")
			return true;
	}
	else
		return true;
	form=formulaire;
	// récupération de la liste des champs
	var listeChamp=null;
	listeChamp=form.hidden_liste_champs;
	if(!listeChamp||!listeChamp.value)
	{
		if(debug)
			alert(txtJS["errListeChamp"]);
		return false;
	}
			
	// Création du tableau contenant toutes les infos
	listeChamp=listeChamp.value.split(" ");
	//alert("avant"+listeChamp.length);
	for(var i=0;i<listeChamp.length;i++)
	{
		var nomChamp=listeChamp[i];
		if(!nomChamp)
			continue;
		var infoChamp=null;
		infoChamp=getValText(form,"js_"+nomChamp);
		if(infoChamp == null)
		{
			if(debug)
				alert(formateMessage(txtJS["errInfoChamp"],Array(nomChamp)));
			return false;
		}
		
		infoChamp=infoChamp.split("|");
		if(typeof(infoChamp)!="object"||infoChamp.length<4)
		{
			if(debug)
				alert(formateMessage(txtJS["errInfoChampAbs"],Array(nomChamp)));				
			return false;
		}
		
		tabChamp[nomChamp]=infoChamp;
	}	

	
	//boucle de validation
	for(var nomChamp in tabChamp)
	{
		var obligatoire=tabChamp[nomChamp][0];
		if(obligatoire>1)
			continue;
		
		//alert("Obligatoire : = "+nomChamp);
		var nomChampAValider = tabChamp[nomChamp][1];   // dans certains cas (dates) le input à valider à un name différent du nom de l'objChamp
		var descChamp=tabChamp[nomChamp][2];
		var fonctionLec=tabChamp[nomChamp][3];
		var fonctionVal=tabChamp[nomChamp][4];
		var paramValidation=tabChamp[nomChamp][5];
		
		if(fonctionLec=="null")
			continue;
		var val=eval(fonctionLec+"(form,"+(nomChampAValider?"nomChampAValider":"nomChamp")+")");
		
		if(val==null)
		{
			if(obligatoire==1)
			{
				alert(formateMessage(txtJS["errChampOblig"],Array(descChamp)));
				return false;
			}
			continue;
		}
		
		if(fonctionVal=="null")
			continue;
		
		/*if(!val)
			continue;*/  //Modif 18/09/2009, suite à ajout fonction getValDuree qui peut retourner 0
		
		if(fonctionVal.indexOf("valide")==0)
		{
			if(!eval(fonctionVal+"(descChamp,val"+(paramValidation?","+paramValidation:"")+")"))
			{
				//alert(formateMessage(txtJS["errChampInvalide"],Array(descChamp)));
				// affichage du message d'erreur à la charge de la fonction de validation.
				return false;			
			}
		}
		else
		{
			if(!eval(fonctionVal))
			{
				if(paramValidation)
					alert(descChamp+" : "+paramValidation);
				else
					alert(formateMessage(txtJS["errNonValide"],Array(descChamp)));
				return false;
			}
		}
	}
	
	return true;
}
//-----------------------------------------
// Fonctions utiles
//-----------------------------------------
function formateMessage(message,valeurs)
{
	// remplacement de variables : valeurs est un tableau dont chaque élément est utilisé pour remplacer les motifs __Pn__ présents dans message, n étant l'indice dans le tableau
	for(var i=0;i<valeurs.length;i++)
		message=message.replace("__P"+i+"__",valeurs[i]);
	return message;
}
	//-----------------------------------------
	// supprime les espaces inutiles d'une chaine
function cleanString(chaine)
{
	if(chaine==null||typeof(chaine)!="string")
		return "";
	var motif1=/^[ ]*(.*)$/;
	var motif2=/^(.*[^ ])[ ]*$/;
	var motif3=/[ ]{2,}/g;
	var temp=chaine.replace(motif1,"$1");  // supprime les espaces de début
	temp=temp.replace(motif2,"$1");   // supprime les espaces de fin
	temp=temp.replace(motif3," ");   // compacte les espaces inutiles
	return temp;
}
	//------------------------------------
function getInput(form,nom)
{
	var objetInput=eval("form."+nom);
	if(!objetInput)
	{
		if(debug)
			alert(formateMessage(txtJS["errPasDeChamp"],Array(nom,form.name)));
		return null;
	}	
	return objetInput;
}
	//--------------------------------------
function getVal(nom)
{
	// fonction générique, peut être appelée depuis une fonction de validation pour se baser sur la valeur d'un autre champ
	// ne peut pas être appelé avant appel de la fonction valider, qui définit la variable globale form.
	return eval(tabChamp[nom][2]+"(form,nom)");
}
/*-----------------------------------------
 Fonctions de lecture de la valeur des objets champs 
 	form		objet formulaire
 	nom			nom de l'objet champ (= nom du champ de formulaire pour les cas simple)
 	
 	retour		null si l'utilisateur n'a rien renseigné, ou en cas d'erreur
 				dans le cas contraire : objet non nul contenant les infos entrées par l'utilisateur (sous forme de chaine de caractère ou de tableau pour les cas plus complexes)
-----------------------------------------*/
function getValCheckbox(form,nom)
{
	// a terminer. Probleme : comment connaitre le nombre de cases a cocher, necessaire pour construire le nom des input checkbox.
	var i=1;
	var tabVal=Array();
	while(1)
	{
		var cb=null;
		cb=eval("form."+nom+"_"+i);
		if(cb==null || !cb[1].type || cb[1].type != "checkbox")
			break;
		if(cb[1].checked)
			tabVal.push(cb[1].value);
		i=i<<1;
	}
	return tabVal.length<1?null:tabVal;
}
	//-----------------------------------------
function getValDuree(form,nom)
{
	var heures = getValText(form,nom+"_h");
	var minutes = getValText(form,nom);
	if(heures == null && minutes == null)
		return null;
	heures = parseInt(heures,10);
	minutes = parseInt(minutes,10);
	if(isNaN(Number(heures)) && isNaN(minutes))
		return null;
	heures = isNaN(heures)?0:heures;
	minutes = isNaN(minutes)?0:minutes;
	return minutes + heures * 60;
}
	//-----------------------------------------
// retourne "jour entier" ou un objet contenant les heures et minutes de début et de fin (hDeb, mDeb, hFin, mFin), en valeurs numériques, ou NaN si erreur de saisie
function getValHeure(form,nom)
{
	var cb = getInput(form,nom+"_entier");
	if(cb && cb.checked)
		return "jour entier";
	
	var dh = getInput(form,nom+"_dh");
	var dm = getInput(form,nom+"_dm");
	var fh = getInput(form,nom+"_fh");
	var fm = getInput(form,nom+"_fm");
	if(!dh || !fh)
		return null;
	var typeChamp = dh.type;
	var hDeb,mDeb="00",hFin,mFin="00";
	var fonctionLecture = getValText;
	if(typeChamp == "select-one")
		fonctionLecture = getValSelect;
	
	hDeb = fonctionLecture.call(form,form,nom+"_dh");
	hFin = fonctionLecture.call(form,form,nom+"_fh");
	if(dm.type != "hidden") mDeb = fonctionLecture.call(form,form,nom+"_dm");
	if(fm.type != "hidden") mFin = fonctionLecture.call(form,form,nom+"_fm");
	if(hDeb == null && hFin == null)
	{
		if(dm.type == "hidden" && fm.type == "hidden")
			return null;
		if(mDeb == null && mFin == null)
			return null;
	}
	hDeb = parseInt(hDeb,10);
	hFin = parseInt(hFin,10);
	mDeb = parseInt(mDeb,10);
	mFin = parseInt(mFin,10);
		
	var valeur = new Object();
	valeur.hDeb = hDeb;
	valeur.mDeb = mDeb;
	valeur.hFin = hFin;
	valeur.mFin = mFin;
	
	return valeur;
}
	//---------------------------
function getValMdp(form,nom)
{
	var mp=getInput(form,nom);
	var mp1=getInput(form,nom+"_1");
	var mp2=getInput(form,nom+"_2");
	var mp3=getInput(form,nom+"_3");
	
	if(mp==null||mp2==null||mp3==null)
	{
		if(debug)
			alert(formateMessage(txtJS["errPasswordChamp"],Array(nom,form.name)));
		return null;
	}
	var mpval=mp.value;
	var mp1val=mp1==null?null:cleanString(mp1.value);
	var mp2val=cleanString(mp2.value);
	var mp3val=cleanString(mp3.value);
	
	if(mpval=="" && (mp2val=="" && mp3val=="" && (mp1val==null || mp1val=="")))
		return null;	
	return Array(mpval,mp1val,mp2val,mp3val);
}
	//---------------------------
function getValMeta(form,nom)
{
	/*var meta = getInput(form,nom);
	if(!meta)
		return null;*/
	var objMeta = eval("obj_"+nom);
	if(!objMeta)
		return null;
	valeur = objMeta.donneValeur();
	valeur = valeur ? valeur : " ";
	return Array(form,nom,valeur);
	// ne jamais retourner de valeur nulle, il faut forcer la validation
	// cas particulier qui brise la logique construite pour les autres types de champ.
}
	//---------------------------
function getValRadio(form,nom)
{
	var tabRadio=getInput(form,nom);
	if(!tabRadio)
		return null;
	var valRadio=null;
	for(var i=0;i<tabRadio.length;i++)
	{
		if(!tabRadio[i].checked)
			continue;
		valRadio=tabRadio[i].value;
		break;
	}
	if(valRadio=="")
		valRadio=null;
	return valRadio;
}
	//---------------------------
function getValSelect(form,nom)  // a utiliser pour select sur lequel la valeur 0 est pertinente.
{
	var sel=getInput(form,nom);
	if(!sel)
		return null;
	
	if(sel.type=="text")		// cas d'un objChamp avec liste vide (requete retournant resultat vide par exemple)
		return getValTxt(form,nom);
	if(sel.selectedIndex==-1)
		return null;
	return sel.options[sel.selectedIndex].value;
}
	//-----------------------------------------
function getValSelectNoZero(form,nom)  // select commencant par option "--" avec value="0", considere comme absence de choix utilisateur
{
	var sel=getInput(form,nom);
	if(!sel)
		return null;
	
	if(sel.type=="text")		// cas d'un objChamp avec liste vide (requete retournant resultat vide par exemple)
		return getValTxt(form,nom);
	if(sel.selectedIndex==-1)
		return null;
	var val=sel.options[sel.selectedIndex].value;
	return val=="0"?null:val;
}
	//-----------------------------------------
function getValText(form,nom)
{
	var objTxt=getInput(form,nom);
	if(!objTxt)
		return null;
	
	var valTxt=cleanString(objTxt.value);
	if(valTxt=="")
		valTxt=null;
	return valTxt;
}
	//-----------------------------------------
function getValUpload(form,nom)
{
	var tab=eval("form."+nom);
	if(!tab || typeof(tab)!="object")
		return null;
	
	var hidden=tab[0];
	var fichier=tab[1];
	
	if(hidden.type!="hidden" || fichier.type!="file")
		return null;
	
	var hiddenVal=cleanString(hidden.value);
	var fichierVal=cleanString(fichier.value);
	
	var retour;
	if(hiddenVal.length<1 && fichierVal.length<1)
		retour=null;
	else
		retour=Array(hiddenVal,fichierVal);
	return retour;
}
//---------------------------
/*	Fonction de validation
	Paramètres :
 		descChamp :			description de l'objet champ (pour affichage des erreurs)
 		val	:				valeur à valider
 		param optionels		passés dans le tableau js_nomDuChamp (5ème élément, liste de paramètres séparés par des virgules, rajoutée après les 2 premiers paramètres)
-----------------------------------------*/
function valideImage(descChamp,val)
{
	var nom=val[1];
	if(nom.length<1)
		return true;
	nom=nom.toLowerCase();
	var morceaux=nom.split(".");
	if(morceaux.length<2)
	{		
		alert(formateMessage(txtJS["errImgExt"],Array(descChamp)));
		return false;
	}
	var ext=morceaux[morceaux.length-1];
	var tabExt=Array("jpg","jpeg","gif","png","swf");
	for(i in tabExt)
	{
		if(tabExt[i]==ext)
			return true;
	}
	alert(formateMessage(txtJS["errImgExt"],Array(descChamp)));
	return false;
}
	//--------------------------
function valideLongueur(descChamp,val,longueur)
{
	if(debug&&!longueur)
	{
		alert(formateMessage(txtJS["errParamAbs"],Array(descChamp,"valideLongueur")));
		return false
	}
	if(typeof(val)!="string"||val.length<longueur)
	{
		alert(formateMessage(txtJS["errTropCourt"],Array(descChamp,longueur)));
		return false;
	}
	return true;
}
	//-------------------------
function valideMdp(descChamp,val,longueur)
{
	if(debug&&!longueur)
	{
		alert(formateMessage(txtJS["errParamAbs"],Array(descChamp,"valideMotDePasse")));
		return false
	}
	
	if(typeof(val)=="string")
	{
		if(val.length<longueur)
		{
			alert(formateMessage(txtJS["errTropCourt"],Array(descChamp,longueur)));
			return false;
		}
	}
	
	var ancien=val[0];
	var saisieAncien=val[1];
	var nouveau=val[2];
	var confirm=val[3];
	
	if(ancien!="")  // modification, l'ancien mot de passe est en md5 dans ancien
	{
		if(confirm==""&&nouveau==""&&(saisieAncien==""||saisieAncien==null))
			return true;
	}
	
	if(saisieAncien!=null&&saisieAncien.length<longueur)
	{
		alert(formateMessage(txtJS["errMdpAncien"],Array(descChamp,longueur)));
		return false;
	}
	
	if(nouveau=="")
	{
		if(confirm!="")
		{
			alert(formateMessage(txtJS["errMdpNouveau"],Array(descChamp)));
			return false;
		}
	}
	if(confirm=="")
	{
		alert(formateMessage(txtJS["errMdpConfirm"],Array(descChamp)));
		return false;
	}
	if(confirm!=nouveau)
	{
		alert(formateMessage(txtJS["errMdpNoMatch"],Array(descChamp)));
		return false;
	}
	if(nouveau.length<longueur)
	{
		alert(formateMessage(txtJS["errTropCourt"],Array(descChamp,longueur)));
		return false;
	}
	return true;
}
	//-------------------------
function valideEmail(descChamp,val)
{
	if(val.match(/^([a-zA-Z0-9_]+[\.-]?)+[a-zA-Z0-9_]+@([a-z0-9_]+[\.-])+[a-z]{2,3}$/))
		return true;
	alert(formateMessage(txtJS["errAdrMail"],Array(descChamp)));
	return false;
}
	//-------------------------
function valideDate(descChamp,val)
{
	elem=val.split("/");
	if(typeof(elem)!="object"||elem.length!=3)
	{
		alert(formateMessage(txtJS["errDateForm"],Array(descChamp)));
		return false;
	}
	var jour=parseInt(elem[0],10);
	var mois=parseInt(elem[1],10);
	var annee=parseInt(elem[2],10);
	if(isNaN(jour)||isNaN(mois)||isNaN(annee))
	{
		alert(formateMessage(txtJS["errDateForm"],Array(descChamp)));
		return false;
	}
	
	// années bissextiles
	var tabMaxJour=new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
	if(annee%4==0)
	{
		if(annee%100!=0)
			tabMaxJour[2]=29;
		else if(ann%400==0)
			tabMaxJour[2]=29;
	}
	
	//controle validite
	if(mois<1||mois>12)
	{
		alert(formateMessage(txtJS["errDateMois"],Array(descChamp)));
		return false;
	}
	
	if(jour<1||jour>tabMaxJour[mois])
	{
		alert(formateMessage(txtJS["errDateJour"],Array(descChamp)));
		return false;
	}
	
	return true;
}
	//-------------------------
// val est soit "jour entier", soit un objet contenant heures et minutes de début et de fin (valeur numérique, pas de texte !!!)
function validePlageHoraire(descChamp,val)
{
	if(val == "jour entier")
		return true;
	if(!valideHeure(descChamp,Array(val.hDeb,val.mDeb)))
		return false;
	if(!valideHeure(descChamp,Array(val.hFin,val.mFin)))
		return false;
	var debut = val.hDeb*60+val.mDeb;
	var fin = val.hFin*60+val.mFin;
	if(fin<debut)
	{
		alert(formateMessage(txtJS["errDebFin"],Array(descChamp)));
		return false;
	}
	return true
}
	//-------------------------
// val est un tableau contenant heures et minutes
function valideHeure(descChamp,val)
{
	if(val.length<2 || isNaN(val[0]) || isNaN(val[1]))
	{
		alert(formateMessage(txtJS["errFormatHeure"],Array(descChamp)));
		return false;
	}
	var h = val[0];
	var m = val[1];
	if(h<0 || h>23 || m<0 || m>59)
	{
		alert(formateMessage(txtJS["errFormatHeure"],Array(descChamp)));
		return false;
	}
	return true;
}
	//-------------------------
// pour la validation de metadonnée, val est un tableau contenant form, nomChamp et valeur
function valideMeta(descChamp,val)
{
	if(typeof(val)!="object" && val.length<3)
		return true; // attention, permissif en cas d'erreur de conception...
	
	var objMeta = eval("obj_" + val[1]);
	if(!objMeta)
		return true;
	return objMeta.valider();
}

function annuler_validation(formulaire)
{
	//alert("annuler validation");
	if(formulaire.hidden_validation&&formulaire.hidden_validation.value)
		formulaire.hidden_validation.value="0";
}
