function Formulaire(formulaire)
// constructeur de la classe (en entrée : l'attribut "name" du formulaire à valider)
{
   // variables membres
   this.form=formulaire; // nom du formulaire
   this.erreurs=new Array(); // tableau des champs contenant des erreurs de saisie

   // tableaux des règles de validation appliquées aux champs
   this.regles=new Array();
   this.messages=new Array();
   this.validations=new Array();
   this.params=new Array();

   // méthodes
   this.regle=regleChamp;
   this.nettoyer=nettoyerChaine;
   this.valider=validerForm;
   this.liste=listeErreurs;
}

function regleChamp(champ, type, message, param)
/* ajoute une règle de validation :
- "champ" est la valeur de l'attribut "name" du champ
- "type" est la règle de validation proprement dite
- "message" est le message d'erreur en cas de validation erronée
- "param" est un paramètre facultatif, utilisé par ceratines règles */
{
   this.regles.push(champ);
   this.validations.push(type);
   this.messages.push(message);
   this.params.push(param);
}

function listeErreurs()
// retourne la liste des erreurs
{
   var x, liste="";
   
   // construction de la chaîne
   for(x=0; x<this.erreurs.length; x++) liste+="- "+this.erreurs[x]+"\n";
   
   return liste;
}

function nettoyerChaine(chaine)
// supprime les espaces en début et fin de chaîne (équivalent à la fonction PHP "trim()")
{
   regex=new RegExp("(^ +)|( +$)", "g");
   chaine=chaine.replace(regex, "");

   return chaine;
}

function validerForm()
// valide le formulaire : chaque champ doit vérifier les règles qui lui ont été définies
{
   var x, regex, msg="";
   eval("var formulaire=document."+this.form+";");
   
   // si aucune règle n'a été définie, la validation est toujours vraie
   if(!this.regles.length) return true;
   
   // on examine chaque champ
   for(x=0; x<this.regles.length; x++)
   {
      // on effectue au préalable un petit nettoyage sur le champ à valider
      eval("formulaire."+this.regles[x]+".value=this.nettoyer(formulaire."+this.regles[x]+".value);");
      
      switch(this.validations[x])
      {
         // le champ doit avoir le même contenu qu'un autre
         case "comparaison":
            eval("if(formulaire."+this.regles[x]+".value!='"+this.params[x]+"') this.erreurs.push(this.messages[x]);");
            break;
           	    
         /* le champ doit avoir une certaine longueur : c'est le dernier paramètre sous la forme "min,max"
         (0 signifiant pas de minimum ou de maximum) */
         case "longueur":
            eval("var longueur=formulaire."+this.regles[x]+".value.length;");
            if(longueur)
            {
               var temp=this.params[x].split(",( +)?");
               mini=parseInt(temp[0]);
               maxi=parseInt(temp[1]);
               
               if((mini && longueur<mini) || (maxi && longueur>maxi)) this.erreurs.push(this.messages[x]);
            }
            break;		

         // le champ (uniquement s'il est rempli) doit vérifier une expression régulière
         case "regex":
            switch(this.params[x])
            {
               // quelques exemples...
               case "mail":
                  //regex=new RegExp("^[a-z0-9_]([.-]?[a-z0-9_]+)+@[a-z0-9_]([.-]?[a-z0-9_]+)+\.([a-z]{2,4}|[a-z]{6})$", "gi");
				                  
				  var atom = "[!#-'*+\\-\\/-9=?A-Z^-~]+";
				  regex=new RegExp("^"+atom+"(\\."+atom+")*@"+atom+"(\\."+atom+")*\\.[a-zA-Z]{2,4}$", "gi");
				  				  
                  break;
                  
               case "alpha_num":
                  regex=new RegExp("^[_a-z0-9]+$", "gi");
                  break;
                  
               case "code_postal":
                  regex=new RegExp("^(0[1-9]|[1-9][0-9])[0-9]{3}$", "g");
                  break; 
				  
               case "date":
                  regex=new RegExp("^[0-3][0-9][/-.](0[1-9]|1[0-2])[/-.][0-9]{4}$", "g");
                  break;
                  
               // par défaut (non vide)
               default:
                  regex=new RegExp("^.+$", "g");

            }
            
            eval('if(formulaire.'+this.regles[x]+'.value!="" && !regex.exec(formulaire.'+this.regles[x]+'.value)) this.erreurs.push(this.messages[x]);');
            break;
            
         case "requis":
         default:
         // le champ doit juste être rempli
            eval('if(formulaire.'+this.regles[x]+'.value=="") this.erreurs.push(this.messages[x]);');
      }
   }
 
   		// On traite ici les erreurs qui n'ont pas fait l'objet d'une règle

message_erreur=("");

var erreur_radio = "";
if(taillemax!=0) {
		
	//  On vérifie que le client à selectionner (bouton radio) oui ou nom pièce jointe	
		var erreur_radio = "pas_besoin";
		//var monform = document.getElementById("formContact");
		//var myCB = monform.getElementsByTagName("input")
		var myCB = formulaire.getElementsByTagName("input")
		var check = 0;
			for (var i=0; i<=myCB.length-1; i++)
				if (myCB[i].type.toLowerCase()=="radio") {
					if(myCB[i].checked) check++;
					}
			if(check==0) {
					
erreur_radio= "- Voulez-vous oui ou non joindre une pièce?\n";
var deb ="Le formulaire comporte des erreurs :\n\n";
		var plus = erreur_radio; 
		var fin ="\nMerci.";
		var msg =deb+erreur_radio+fin;
		alert(msg);
		return false;
			} 

}

					
//  Comme cette sélection est impérative on ne signale pas les autres erreurs 	
if(erreur_radio =="") {		
		
		 	
//On vérifie qu'au moins un destinataire est sélectionné (checkbox coché) si le choix est possible		
if(nb_label > 1) {										
		var erreur_checkbox = "";
		//var monform = document.getElementById("formContact");
		//var myCB = monform.getElementsByTagName("input")
		var myCB = formulaire.getElementsByTagName("input")
		var check = 0;
			for (var i=0; i<=myCB.length-1; i++)
				if (myCB[i].type.toLowerCase()=="checkbox") {
					if(myCB[i].checked) check++;
					}
			if(check==0) {
			var erreur_checkbox= "- Veuillez sélectionner au moins un destinataire.\n";
			} 
		message_erreur= message_erreur+erreur_checkbox;
}
		
		// On vérifie que le client à sélectionner (liste déroulante) l'objet du contact
		var erreur_liste = "";
		var objet=document.getElementById("formContact").objet.value;
		if(objet == 0) {
			var erreur_liste= "- Veuillez choisir l'objet de votre message.\n";
			}
		message_erreur= message_erreur+erreur_liste;

if(taillemax!=0) {		
		// Si le client a sélectionné avec pièce jointe (boutons radio couplés) on vérifie qu'il a effectivement joint la pièce 
		var erreur_piece = "";
		var bouton = document.getElementsByName("Piece_jointe");
		var i = 0;
		for(i; i<bouton.length ; i++) {
			if(bouton[i].checked)
			break;
		}
		var bouton = bouton[i].value;

		var piece =document.getElementById('formContact').Fichier.value;
		if((bouton=="avec_piece") && (piece=="")) {
			var erreur_piece= "- Veuillez rechercher la pièce jointe.\n";
			}
		message_erreur= message_erreur+erreur_piece;		
}		
		
				
	// Le défi anti-spam est-il saisi si oui la réponse est-elle correcte   
		var erreur_captcha ="";
		var captcha=document.getElementById("formContact").captcha.value;
		var vcaptcha=document.getElementById("formContact").vcaptcha.value; 
			if(captcha == "") {
			var erreur_captcha= "- Veuillez répondre au défi anti-spam.\n";
			}
			else if(hex_md5(captcha)!=vcaptcha) {
			var erreur_captcha= "- Votre réponse au défi anti-spam est incorrecte.\n";
			}
		message_erreur = message_erreur+erreur_captcha;
 
 
 
 
 
 
 
  
   // en cas d'erreur, on affiche les différents messages
   if((this.erreurs.length) || message_erreur.length) {
		var deb ="Le formulaire comporte des erreurs :\n\n"+this.liste();
		var plus = message_erreur; 
		var fin ="\nMerci.";
		var msg =deb+message_erreur+fin;
		alert(msg);
		return false;
	}
	   
	   // en cas de succès, on envoie le formulaire
	   return true;
}

}
