/**
* Objet FormValidator
*
* Permet de g?rer la validation de formulaire
*
* Mettre onsubmit="return validator.check(this);" dans la balise <form>
*
* Utilisation :
* 	validator.addRules("id_du_champ","contraintes","nom du champ");
*
* Contraintes est une liste avec l'espace comme separateur
* les valeurs peuvent etre :
*		champ obligatoire 		=> required (marche aussi pour le select)
*		taille mini				=> minlength=X
*		taille maxi 			=> maxlength=X
*		champ numerique			=> numeric
*		nombre de decimales 	=> decimals=X
*		email					=> mail
*		entre 2 nombres			=> between=min|max
*		egal a un autre			=> equal=idAutreChamp
*       expression reguli?re	=> regexp=[a-zA-Z0-9]§
*									ATTENTION IL FAUT FINIR SA REGEXP PAR §
*
* Gestion carte cofinoga		
* 		Mettre carte=id_champ_num|id_champ_prefix et 'carte' en contrainte
*
* Gestion des boutons radios :
*
*		Mettre radio=nom_des_radios au lieu de l'id et required en contrainte.
*		Possibilite de preciser newline.
*
* Gestion des checkboxs :
*		Mettre check=id_check1|id_check2 ...
*		Regles possibles : minlength= maxlength=
*		Possibilite de preciser newline.
*
* Gestion des dates :
*
*		Mettre les 3 id des champs en les separant par des '|'
*		et dans l'ordre jour mois annee, puis mettre la contrainte 'date'.
*		Exemple : 
*			validator.addRules("idjour|idmois|idannee","date required","Date de naissance");
*
*		Pour verifier qu'une date est bien superieure a une autre :
*		Mettre les 3 id des champs de la deuxieme en les separant par des '|'
*		puis mettre dans les contraintes after=id_jour_date1|id_mois_date1|id_annee_date1
*		Il faut aussi passer les deux labels en les separant par des '|' en mettant
*		celui correspondant a la date qui doit etre superieure en premier.
*		
* Gestion des pièces d'identité :
*
*		carte identité 	: mettre id_du_champ et cni et delivrance=id_mois_delivrance|id_annee_delivrance en contrainte
*		passeport		: mettre id_du_champ et passeport en regle
*
*
* Utilisation de fonction(s) de validation externe :
*
*		Mettre function=nom_fonction ou function=nom_fonction1|nom_fonction2
*		Exemples :
*			validator.addRules("idduchamp","function=testDept","Champ");
*			validator.addRules("idduchamp","function=testDept|testAnnee","Champ");
*			validator.addRules("idduchamp","function=testDept required","Champ");
*
*		Les fonctions appelées prennent un argument qui correspond au champ et doivent retourner un
*		résultat de type ValidatorResult.
*		Exemple :
*			function testDept(field){
*				if(document.getElementById('un_autre_champ').value == 100 && field.value == 99)
*					return new ValidatorResult(true,null);
*				else
*					return new ValidatorResult(false,'Incoh&eacute;rence d&eacute;partement / pays');
*			}
*		
*
* Cette version fonctionne avec un formulaire se trouvant dans une table HTML.
* Par defaut, il rajoute une cellule apres le champ a valider.
* Si on veut que le message soit sur une nouvelle ligne,
* il suffit de mettre 'newline' dans les contraintes.
*
* Ne pas mettre d 'espace entre = et la valeur
* decimals peut etre mis a 0 pour un entier
*
* Exemple : validator.addRules("Description","maxlength=3 minlength=1 required","Description");
*
*/

function FormValidator()
{
	this.rules 	= new Array();
	this.isGood	= true;
	this.focused = false;
	this.firstPass = true;
	this.incohIds = new Array();
	
	this.changeRuleField = function(oldField, newField){
		for(fieldId in this.rules){
			if(oldField == fieldId){
				var temp = this.rules[fieldId];
				this.removeRules(oldField);
				this.addRules(newField,temp.rules,temp.label);
				break;
			}
		}
	}
	
	this.removeRules = function(ruleName){
		var temp = this.rules;
		this.rules 	= new Array();
		var isNl = false;
		for(key in temp){
			if(key != ruleName)
				this.rules[key] = temp[key];
			else
				isNl = temp[key].rules.indexOf("newline") != -1;
		}
		
		if(!isNl && document.getElementById("formValidatorTd"+ruleName))
			document.getElementById("formValidatorTd"+ruleName).parentNode.removeChild(document.getElementById("formValidatorTd"+ruleName));
		if(isNl && document.getElementById("formValidatorTr"+ruleName))
			document.getElementById("formValidatorTr"+ruleName).parentNode.removeChild(document.getElementById("formValidatorTr"+ruleName));
	}
	
	this.removeAll = function(){

		for(ruleName in this.rules){
			var isNl = this.rules[ruleName].rules.indexOf("newline") != -1;
					
			if(!isNl && document.getElementById("formValidatorTd"+ruleName))
				document.getElementById("formValidatorTd"+ruleName).parentNode.removeChild(document.getElementById("formValidatorTd"+ruleName));
			if(isNl && document.getElementById("formValidatorTr"+ruleName))
				document.getElementById("formValidatorTr"+ruleName).parentNode.removeChild(document.getElementById("formValidatorTr"+ruleName));
		}
		this.rules 	= new Array();
	}
	
	this.addRules = function(fieldId,rules,label){
		this.rules[fieldId] = {rules:rules, label:label};

		var par = null;
		suiv = null;
		var di	= document.createElement("div");
		di.id	= "erreur"+fieldId;
	
		var td = document.createElement("td");
		
	   if(rules.indexOf('large') == -1){
			td.className = "check";
		
		}
		else {
	
			td.className = "check";
			td.style.width = "100%";
		}
		td.id = "formValidatorTd"+fieldId;
		
		
		
		td.appendChild(di);
		//alert(fieldId);
		if(fieldId.indexOf("|") != -1 && fieldId.indexOf("check") == -1){
			var ids = fieldId.split("|");
			par = getRow(document.getElementById(ids[1]));
		}
		else if(fieldId.indexOf("radio") != -1 ){
			deb 	= fieldId.indexOf('radio')+6;
			val 	= fieldId.substring(deb);	
			var rads = document.getElementsByName(val);
			par = getRow(rads[rads.length-1]);
		}else if(fieldId.indexOf("check") != -1 ){
			deb 	= fieldId.indexOf('check')+6;
			val 	= fieldId.substring(deb);	
			if(val.indexOf("|") != -1){
				vals 	= val.split("|");
				par 	= getRow(document.getElementById(vals[vals.length-1]));
			}else
				par 	= getRow(document.getElementById(val));
		}
		else{
		//alert(fieldId);
			par = getRow(document.getElementById(fieldId));
		}
		
		if(fieldId.indexOf("carte=") != -1){
			var deb 		= fieldId.indexOf('carte')+6;
			var val 		= fieldId.substring(deb);	
			var vals		= val.split("|");
			document.getElementById(vals[0]).maxLength = "11";
		}
		
		if(rules.indexOf('newline') == -1){
			par.appendChild(td);
		}
		else{
			var colsval = par.getElementsByTagName("td").length + par.getElementsByTagName("th").length;
			var nl = document.createElement("tr");
			
			if(rules.indexOf('racSimulTable') != -1){
				td.colSpan=colsval-1;
				nl.appendChild(td);
				var td2 = document.createElement("td");
				td2.className = "suppr";
				nl.appendChild(td2);
			} else {
				td.colSpan=colsval;
				nl.appendChild(td);
			}			
	
			nl.id = "formValidatorTr"+fieldId;
			if(par.nextSibling)
				par.parentNode.insertBefore(nl,par.nextSibling);
			else
				par.parentNode.appendChild(nl);
		}
		
		if(rules.indexOf('numeric') != -1)
		{
			document.getElementById(fieldId).onkeypress = function(e){
				var keyCode;
				
				if(!e){
					e = window.event;	
					keyCode = e.keyCode
				}
				else{
					keyCode = e.charCode;
					if(keyCode == 0)
						return;
				}
				
				if(!(keyCode >= 48 && keyCode <=57))
				{					
					
					dec = true;
					if(rules.indexOf('decimals') != -1)
					{
						deb 	= rules.indexOf('decimals')+9;
						space 	= rules.indexOf(' ',deb);
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);	
						dec 	= parseInt(val) != 0;
					}
					else
						dec = false;
					switch(keyCode)
					{
						case 44:	
							if((this.value.indexOf('.') == -1 && dec)){
								if(document.all)
									e.keyCode = 46;
								else{
									this.value += ".";
									validator.stopKeyPress(e);
								}
							}
							else
								validator.stopKeyPress(e);
							break;
						case 46:
							if(this.value.indexOf('.') != -1 || !dec)
								validator.stopKeyPress(e);
							break;
						default:
							validator.stopKeyPress(e);
					}
				}
				else
				{
					if(rules.indexOf('decimals') != -1)
					{
						deb 	= rules.indexOf('decimals')+9;
						space 	= rules.indexOf(' ',deb);
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
						if(this.value.indexOf('.') != -1)
						{
							if(this.value.length - this.value.indexOf('.') - 1 == parseInt(val))
								validator.stopKeyPress(e);
						}
					}
				}
			}
		}
		
		// Ajouté par Jérôme MIVIELLE 06/2007 : N'autorise que les touches alpha,
		// transforme en majuscule et gère les accents et les 'ç'
		// utilisé pour les champs nom et prénom
		
		if(rules.indexOf('alpha') != -1)
		{
			document.getElementById(fieldId).onkeypress = function(e){
				var keyCode;
				
				if(!e){
					e = window.event;	
					keyCode = e.keyCode
				}
				else{
					keyCode = e.charCode;
					if(keyCode == 0)
						return;
				}
				
				if(!(keyCode >= 97 && keyCode <=122) && !(keyCode >= 65 && keyCode <=90)) {
					
					validator.stopKeyPress(e);	
					
					switch(keyCode) {
						case 224:
						case 225:
						case 226:
						case 227:
						case 228:
							this.value += 'a';
							break;
						case 231:
							this.value += 'c';
							break;
						case 232:
						case 233:
						case 234:
						case 235:
							this.value += 'e';
							break;
						case 236:
						case 237:
						case 238:
						case 239:
							this.value += 'i';
							break;
						case 242:
						case 243:
						case 244:
						case 245:
						case 246:
							this.value += 'o';
							break;
						case 249:
						case 250:
						case 251:
						case 252:
							this.value += 'u';
							break;
						case 32:
							this.value += ' ';
							break;
						default:
					}
				}
			}
		}
		
		// Ajouté par Vincent Dubois le 20/09/2006 : blocage des touches non numériques
		// pour les champs de type date
		if (rules.indexOf('date') != -1) {
			var champsDate = fieldId.split("|");
			for (var i=0;i<champsDate.length;i++) {
				field = champsDate[i];
				document.getElementById(field).onkeypress = function(e){
					var keyCode;
					
					if(!e){
						e = window.event;	
						keyCode = e.keyCode
					}
					else{
						keyCode = e.charCode;
						if(keyCode == 0)
							return;
					}
					
					if(!(keyCode >= 48 && keyCode <=57))
					{					
						
						dec = true;
						if(rules.indexOf('decimals') != -1)
						{
							deb 	= rules.indexOf('decimals')+9;
							space 	= rules.indexOf(' ',deb);
							val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);	
							dec 	= parseInt(val) != 0;
						}
						else
							dec = false;
						switch(keyCode)
						{
							case 44:	
								if((this.value.indexOf('.') == -1 && dec)){
									if(document.all)
										e.keyCode = 46;
									else{
										this.value += ".";
										validator.stopKeyPress(e);
									}
								}
								else
									validator.stopKeyPress(e);
								break;
							case 46:
								if(this.value.indexOf('.') != -1 || !dec)
									validator.stopKeyPress(e);
								break;
							default:
								validator.stopKeyPress(e);
						}
					}
					else
					{
						if(rules.indexOf('decimals') != -1)
						{
							deb 	= rules.indexOf('decimals')+9;
							space 	= rules.indexOf(' ',deb);
							val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
							if(this.value.indexOf('.') != -1)
							{
								if(this.value.length - this.value.indexOf('.') - 1 == parseInt(val))
									validator.stopKeyPress(e);
							}
						}
					}
				}
			}
		}
		
	}
	
	this.stopKeyPress = function(e){
		if(!document.all)
			e.preventDefault();
		 else
			 e.keyCode = 0;
		 return false;
	}
	
	
	/**
	* Verification d'email
	* @param	String l'email
	* @return	boolean
	*/ 
	this.isMail = function(string) {
		if (string.search(/^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6})$/) != -1)
			return true;
		else
			return false;
	}
	
	this.checkDay = function(val){
		return ( val.length==2 && (!isNaN(val) && (parseInt(val,10) > 0 && parseInt(val,10) < 32)));
	}
	
	this.checkMonth = function(val){
		return ( val.length==2 && (!isNaN(val) && (parseInt(val,10) > 0 && parseInt(val,10) < 13)));
	}
	
	this.checkYear = function(val){
		return ( val.length==4 && (!isNaN(val) && (parseInt(val,10) > 1849 && parseInt(val,10) < 2051)));
	}
	
	this.checkDateIsFull = function(o){
		if( (trim(o.day) && (!trim(o.month) || !trim(o.year)))
				|| (trim(o.year) && (!trim(o.month) || !trim(o.day)))
				|| (trim(o.month) && (!trim(o.day) || !trim(o.year))))
			return false;
		return true;
	}
	
	this.checkDateIsEmpty = function(o){
		if( !trim(o.day) && !trim(o.month) && !trim(o.year))
			return true;
		return false;
	}
	
	this.getDateObj = function(id){
		var ids = id.split("|");
		var j1 = document.getElementById(ids[0]).value;
		var m1 = document.getElementById(ids[1]).value;
		var a1 = document.getElementById(ids[2]).value;
		return {day:j1,month:m1,year:a1};
	}
	
	this.isBissextile = function(annee) {
		if( (this.is_int(annee/4) && !this.is_int(annee/100)) || this.is_int(annee/400))
			return true; //annee bissextile
		else
			return false;
	}
	
	this.is_int = function(Num){
		return !(Num-parseInt(Num)>0);
	}
	
	/*
	* Vérifie qu'une date est valide : 31/30 jours,
	* 29/28 jours en fevrier
	*/
	this.checkDateIsValid = function(dObj) {
		var isGood = true;
		var year = dObj.year;
		var day = dObj.day;
		var month = dObj.month;
		if ((this.checkYear(year)) && (this.checkMonth(month)) && (this.checkDay(day))) {
			if ((month==2) || (month==4) || (month==6) || (month==9) || (month==11)) {
				if (month==2) {
					if (this.isBissextile(year))
						isGood = day<30;
					else
						isGood = day<29;
				}
				else
					isGood = day<31;
			}
		}
		else {
			isGood=false;
		}
		return isGood;
	}
	
	this.checkDate = function(id,label,isRequired){
		var dGood 	= true;
		var dObj = this.getDateObj(id);
		if(isRequired){
			/*dGood = (this.checkDateIsFull(dObj) && 
					(this.checkDay(dObj.day) && this.checkMonth(dObj.month)
							&& this.checkYear(dObj.year)));*/
			dGood = this.checkDateIsValid(dObj);
		}
		else{
			if(!this.checkDateIsFull(dObj) && !this.checkDateIsEmpty(dObj))
				dGood = false;
			else{
				/*dGood = this.checkDay(dObj.day) && this.checkMonth(dObj.month)
							&& this.checkYear(dObj.year);*/
				dGood = this.checkDateIsValid(dObj);
			}
		}
			
		return dGood;
	}
	
	this.check = function(theForm){
		
		this.checkPass(theForm);
		this.firstPass = false;
		this.clearIncohIds();
		return this.checkPass(theForm);
	}
	
	/**
	* Verifie le formulaire
	* 
	* @param	Form	Le formulaire
	* @return	boolean 
	*/
	this.checkPass = function(theForm){

		this.isGood = true;		
		for(id in this.rules)
		{
			if(typeof this.rules[id] != "function"){
				rules	= this.rules[id].rules;
				label	= this.rules[id].label;
				this.setErrMess(id,"");
				
				if(id.indexOf("|") != -1){
				
					// Une règle similaire à la regle avec "function" sauf que nous passons en paramètre la chaine avec les pipes
					if(rules.indexOf("pipefunction") != -1){
					
						deb 		= rules.indexOf('pipefunction')+13;
						space 		= rules.indexOf(' ',deb);
						val 		= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
						var foncs 	= val.split("|");
						
						for(var i=0;i<foncs.length;i++){
							var fname = foncs[i];
							var res = eval(fname).call(null,id);
							
							if(!res.valid)
								this.setErrMess(id,res.errMess);
						}
						
						
					}
						
					// Ajouté par Fahd Haiti le 27/06/2006
					// Cette partie permet de contrôler si une date est ultérieur à la date du jour
					// El ne fonctionne que dans le cas de la présence de "mois" et "année" séparé par un "|"
					if(rules.indexOf("date_passee") != -1){
						var identifiants = id.split("|");
						
						today = new Date();
						
						mois =  document.getElementById(identifiants[0]).value;
						annee =  document.getElementById(identifiants[1]).value;
						
						// Détermination du navigateur pour la gestion de l'annéee
						var AgntUsr=navigator.userAgent.toLowerCase();
						var NavYes=AgntUsr.indexOf('mozilla')!=-1&&AgntUsr.indexOf('compatible')==-1?1:0;
						var todayAnnee;
						
						if(NavYes){
							todayAnnee = today.getYear() + 1900;
						} else {
							todayAnnee = today.getYear();
						}
						
						if(annee > todayAnnee){
							
							this.setErrMess(id,"date supérieure à la date du jour");
						}
						else if (annee == todayAnnee && mois > (today.getMonth() + 1)){
							this.setErrMess(id,"date supérieure à la date du jour");
						}
					}
					
					// Ajouté par Fahd Haiti le 27/06/2006
					// Cette partie permet de contrôler si une date est postérieur à la date du jour
					// El ne fonctionne que dans le cas de la présence de "mois" et "année" séparé par un "|"
					else if(rules.indexOf("date_futur") != -1){
						var identifiants = id.split("|");
						
						today = new Date();
						
						mois =  document.getElementById(identifiants[0]).value;
						annee =  document.getElementById(identifiants[1]).value;
						
						// Détermination du navigateur pour la gestion de l'annéee
						var AgntUsr=navigator.userAgent.toLowerCase();
						var NavYes=AgntUsr.indexOf('mozilla')!=-1&&AgntUsr.indexOf('compatible')==-1?1:0;
						var todayAnnee;
						
						if(NavYes){
							todayAnnee = today.getYear() + 1900;
						} else {
							todayAnnee = today.getYear();
						}
						
						
						if(annee < todayAnnee){
							this.setErrMess(id,"date inférieure à la date du jour");
						}
						else if (annee == todayAnnee && mois <= (today.getMonth() + 1)){
							this.setErrMess(id,"date inférieure à la date du jour");
						}
					}
							
					else if(rules.indexOf("date") != -1){
						if(!this.checkDate(id,label,rules.indexOf("required") != -1))
							this.setErrMess(id,"Date non valide");
					}
					
					if(rules.indexOf("after") != -1){
						deb 	= rules.indexOf('after')+6;
						space 	= rules.indexOf(' ',deb);
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
						
						var labs = label.split("|");
						var d0 = this.getDateObj(id);
						var d1 = this.getDateObj(val);
						
						if( (this.checkDateIsFull(d0) && this.checkDateIsFull(d1))
							&& (this.checkDate(id,labs[0],false) && this.checkDate(val,labs[1],false) )){
							var cGood = true;
							if(parseInt(d0.year,10) < parseInt(d1.year,10)){
								cGood = false;
							}
							else if((parseInt(d0.year,10) == parseInt(d1.year,10)) && (parseInt(d0.month,10) < parseInt(d1.month,10))){
								cGood = false;
							}
							else if((parseInt(d0.year,10) == parseInt(d1.year,10)) && 
								    (parseInt(d0.month,10) == parseInt(d1.month,10)) &&
								    (parseInt(d0.day,10) <= parseInt(d1.day,10))){
								cGood = false;
							}
								
							if(!cGood)
								this.setErrMess(id,labs[1]+" doit pr&eacute;c&eacute;der "+labs[0]);		
						}	
						else					
							this.setErrMess(id,labs[1]+" doit pr&eacute;c&eacute;der "+labs[0]);		
					}
					if(id.indexOf("carte") != -1){
						total = 0;
						position = 0;
						deb 		= id.indexOf('carte')+6;
						val 		= id.substring(deb);	
						vals		= val.split("|");
						var chaine1 = document.getElementById(vals[0]).value;
						var chaine2 = document.getElementById(vals[1]).value;
						var chaineCourante = chaine2+chaine1;
						mult=1;
						totalpartiel=0;
						total = parseInt( chaineCourante.substring( chaineCourante.length-1 , chaineCourante.length ) );
						position=(chaineCourante.length-2);
						for(position;position>=0;position--)
						{
							mult= 3 - mult;
							totalpartiel = mult* parseInt(chaineCourante.substring(position,position+1));
		
							if (totalpartiel > 9)
							{
								totalpartiel += 1;
							}
							total += totalpartiel;
		 				}
						total = total % 10;
						if(total != 0)
							this.setErrMess(id,"Num&eacute;ro de carte invalide");
					}
					
				
					
					
					if(id.indexOf("check") != -1){
						if(rules.indexOf('minlength') != -1){
							deb 	= rules.indexOf('minlength')+10;
							space 	= rules.indexOf(' ',deb);
			
							val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
							
							deb 	= id.indexOf('check')+6;
							idc 	= id.substring(deb);
							idcs	= idc.split("|");
							
							var cmptc = 0;
							for(var i=0;i<idcs.length;i++){
								var curc = document.getElementById(idcs[i]);
								if(curc.checked)
									cmptc++;
							}
							
							if(cmptc < val){
								this.setErrMess(id,"Il doit y avoir au moins "+val+" "+label);	
							}
						}
						if(rules.indexOf('maxlength') != -1){
							deb 	= rules.indexOf('maxlength')+10;
							space 	= rules.indexOf(' ',deb);
			
							val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
							
							deb 	= id.indexOf('check')+6;
							idc 	= id.substring(deb);
							idcs	= idc.split("|");
							
							var cmptc = 0;
							for(var i=0;i<idcs.length;i++){
								var curc = document.getElementById(idcs[i]);
								if(curc.checked)
									cmptc++;
							}
							
							if(cmptc > val){
								this.setErrMess(id,"Il doit y avoir au maximum "+val+" "+label);	
							}
						}
					}
				}	
				else if(id.indexOf("radio") != -1){
				
					deb 		= id.indexOf('radio')+6;
					val 		= id.substring(deb);	
					var rads 	= document.getElementsByName(val);
					var checked = false;
					var cmpt	= 0;
					while(cmpt < rads.length && !checked){
						checked = rads[cmpt].checked;
						cmpt++;
					}
					if(!checked)
						this.setErrMess(id,label+" est obligatoire");		
				}else if(id.indexOf("check") != -1){
					if(rules.indexOf('minlength') != -1)
					{
						deb 	= rules.indexOf('minlength')+10;
						space 	= rules.indexOf(' ',deb);
		
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
						
						deb 	= id.indexOf('check')+6;
						idc 	= id.substring(deb);
						
						if(val > 1 || (val <=1 && !document.getElementById(idc).checked) ){
							this.setErrMess(id,"Il doit y avoir au moins "+val+" "+label);	
						}
					}
					
				}else{
					field 	= document.getElementById(id);
						
					if(rules.indexOf('required') != -1)	{
						if((field.type == "text" || field.type == "password"
						|| field.type == "hidden" || field.type == "file" || 
							field.nodeName.toLowerCase() == "textarea")
								&& !trim(field.value))
							this.setErrMess(id,label+" est obligatoire.");		
						else if(field.nodeName.toLowerCase() == "select" && (
							field.options[field.selectedIndex].value == "-1" ||
							field.options[field.selectedIndex].value == "" 
							))
							this.setErrMess(id,label+" est obligatoire.");
		
					}
					
					if(rules.indexOf("cni") != -1){
						
						var ci 	= document.getElementById(id);
						var num = ci.value;
											
						if(trim(num)){	
							if(num.length == 12){
							
								deb 	= rules.indexOf('delivrance')+11;
								space 	= rules.indexOf(' ',deb);
								val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
								var deli = val.split("|");
								var mois = document.getElementById(deli[0]).value;
								var an 	 = document.getElementById(deli[1]).value.substring(2,4);
								var dptf  = document.getElementById(deli[2]);
								var dpt;
								if(dptf.nodeName.toLowerCase() == "select")
									dpt = dptf.options[dptf.selectedIndex].value;
								else
									dpt = dptf.value;
								
								if(num.substring(0,2) != an || num.substring(2,4) != mois || num.toLowerCase().substring(4,6) != dpt.toLowerCase())
									this.setErrMess(id,"Incoh&eacute;rence avec la date de d&eacute;livrance ou le d&eacute;partement");
							}
							else{
							
								this.setErrMess(id,"Num&eacute;ro non coh&eacute;rent");
							}
						}
					}
	
					if(rules.indexOf("passeport") != -1){
						
						var pas	= document.getElementById(id);
						var num = pas.value;
						
						if(trim(num)){	
							if(num.length != 9)
								this.setErrMess(id,"Num&eacute;ro non coh&eacute;rent");
						}
					}	
					
					if(rules.indexOf("sejour") != -1){
						
						var pas	= document.getElementById(id);
						var num = pas.value;
						
						if(trim(num)){	
							if(num.length != 10)
								this.setErrMess(id,"Num&eacute;ro non coh&eacute;rent");
						}
					}	
					
					if(rules.indexOf("function") != -1){
						field		= document.getElementById(id);
						deb 		= rules.indexOf('function')+9;
						space 		= rules.indexOf(' ',deb);
						val 		= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
						var foncs 	= val.split("|");
	
						for(var i=0;i<foncs.length;i++){
							var fname = foncs[i];
							var res = eval(fname).call(null,field);
							if(!res.valid)
								this.setErrMess(id,res.errMess);
						}
					}
					
					if(rules.indexOf('equal') != -1)
					{
						deb 	= rules.indexOf('equal')+6;
						space 	= rules.indexOf(' ',deb);
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
						if(field.value != document.getElementById(val).value)
							this.setErrMess(id,label+" doivent &ecirc;tre identiques.");	
						
					}
					
					
					if(rules.indexOf('numeric') != -1)
					{
						if((field.type == "text")
								&& trim(field.value)){
							field.value = field.value.replace(",",".");
							if(isNaN(field.value))
								this.setErrMess(id,label+" est num&eacute;rique.");
							else if(rules.indexOf("decimals") != -1){
									if(field.value.indexOf(".") != -1){
										deb 	= rules.indexOf('decimals')+9;
										space 	= rules.indexOf(' ',deb);
										val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
										if((field.value.length - field.value.indexOf('.') - 1) > parseInt(val))
											this.setErrMess(id,"Pas plus de "+val+" d&eacute;cimales pour "+label);
									}
							}
							else{
								if(field.value.indexOf(".") != -1)
									this.setErrMess(id,"Pas de d&eacute;cimales pour "+label);
							}
							if(!isNaN(field.value) && rules.indexOf("between")){
								deb 	= rules.indexOf('between')+8;
								space 	= rules.indexOf(' ',deb);
								val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
								bornes 	= val.split("|");
								var fval = parseFloat(field.value);
								var bmin = parseFloat(bornes[0]);
								var bmax = parseFloat(bornes[1]);
								if(fval < bmin || fval > bmax)
									this.setErrMess(id,label+" doit &ecirc;tre entre "+bmin+" et "+bmax);
							}
						}
		
					}
					
					if(rules.indexOf('maxlength') != -1)
					{
						deb 	= rules.indexOf('maxlength')+10;
						space 	= rules.indexOf(' ',deb);
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
		
						if((field.type == "text" || field.type == "password" || field.nodeName.toLowerCase() == "textarea")
								&& ! (trim(field.value).length <= val) )
							this.setErrMess(id,"Pas plus de "+val+" caract&egrave;res pour "+ label);
		
						if(field.nodeName.toLowerCase() == "select" && field.multiple)
						{
							cmptsel = 0;
		
							for (j = 0; j < field.options.length; j++)
							    if (field.options.options[j].selected)
									cmptsel++;
		
							if(cmptsel > val)
								this.setErrMess(id,"Pas plus de "+val+" &eacute;l&eacute;ments dans "+label);	
						}
					}
		
					if(rules.indexOf('minlength') != -1)
					{
						deb 	= rules.indexOf('minlength')+10;
						space 	= rules.indexOf(' ',deb);
		
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
		
						if((field.type == "text" || field.type == "password" || field.nodeName.toLowerCase() == "textarea")){
							if(!(field.value.length >= val) && (trim(field.value).length > 0)) 
							this.setErrMess(id,"Pas moins de "+val+" caract&egrave;res pour "+ label);
						}
		
						if(field.nodeName.toLowerCase() == "select" && field.multiple)
						{
							cmptsel = 0;
							for (j = 0; j < field.options.length; j++)
							    if (field.options.options[j].selected)
									cmptsel++;
		
							if(cmptsel < val)
								this.setErrMess(id,"Pas moins de "+val+" &eacute;l&eacute;ments dans "+label);	
						}
					}
					
					if(rules.indexOf('regexp') != -1)
					{
						deb 	= rules.indexOf('regexp')+7;
						space 	= rules.indexOf('§',deb);
						val 	= space == -1 ? rules.substring(deb) : rules.substring(deb,space);
		
						if((field.type == "text" || field.type == "password" || field.nodeName.toLowerCase() == "textarea")){
							var reg = new RegExp(val,"");
							if(!reg.test(field.value))
								this.setErrMess(id,label);
						}
					}
					
					if(rules.indexOf('mail') != -1)
					{
						if(trim(field.value))
							if(!this.isMail(field.value))
								this.setErrMess(id,"Adresse mail invalide");
					}
				}
			}
		}
		this.focused = false;
		return this.isGood;
	}
	
	this.setIncohIds = function (incohIds) {
		this.incohIds = incohIds;
	}
	
	this.clearIncohIds = function () {
		for (var i = 0; i < this.incohIds.length; i++){
					document.getElementById(this.incohIds[i]).style.display = "none";
				}
	}
	
	

	this.setErrMess = function(fieldId,message){
		sp		= document.getElementById("erreur"+fieldId);
		img		= document.createElement("img");
		imb		= document.createElement("img");
		img.src = "./images/checked-ok-transp.gif";
		imb.src = "./images/checked-false-transp.gif";
		img.alt = "Champ ok";
		imb.alt = "Champ invalide";
		
		if(message != "*" && message != "")
			this.isGood = false;
		
		messErr = document.createElement("span");
		if(message != "*" && message != "")
			messErr.innerHTML = message;	
		else
			messErr.innerHTML = this.rules[fieldId].label+" ok";	

		if(sp.childNodes.length != 0)
			while(sp.childNodes.length > 0)
				sp.removeChild(sp.firstChild);
		
		if(!this.firstPass && !this.isGood)
			sp.appendChild(messErr);
		
		if(message != "*" && message != ""){	
			if(!this.firstPass && !this.isGood)
				sp.insertBefore(imb,sp.firstChild);
			if(!this.focused){
			
				if(fieldId.indexOf("|") != -1){
					var spl = fieldId.split("|");
					document.getElementById(spl[spl.length-1]).focus();		
				}
				else if(fieldId.indexOf("radio") != -1){
					var spl = fieldId.split("=");
					var compRName = spl[spl.length-1];
					document.getElementsByName(compRName)[0].focus();		
				}
				else if(fieldId.indexOf("=") != -1){
					var spl = fieldId.split("=");
					document.getElementById(spl[spl.length-1]).focus();		
				}
				else{
				if(!document.getElementById(fieldId).tpe=='hidden')
					document.getElementById(fieldId).focus();
					}
				this.focused = true;
			}
			
		}
		else{
			if(!this.firstPass && !this.isGood)
				sp.insertBefore(img,sp.firstChild);
		}
		
		
		
	}
}

var validator = new FormValidator();

ValidatorResult = function(bool,label){
	this.valid 		= bool;
	this.errMess 	= label;
}