// RockForm (version In)
// Validation de formulaire automatisé en temps réel
// Nécessite jquery 1.3.2 ou +
// Version 1.0 du 10 juin 2009
// Auteurs :
// 		Maxime BERNNARD-JACQUET
// 		Thierry LEMOULEC
// 		BAPTISTE MILLOU
// pour www.dysign.fr

$(document).ready(function(){
	
	//textes pour l'affichage du nombre de champs restants
	var reste = "Il vous reste <strong>";
	var champ = "</strong> champ à remplir";
	var champs = "</strong> champs à remplir";
	var ok = "Vous pouvez valider :";
	
	// Expressions régulières
	// Ajoutez vos expressions régulières dans cet objet et nommez simplement vos champs HTML de la même manière que le nom de la regex
	var regex = {
		"select"   : new RegExp("^(.|\n|\r|\n\r){1,}$","i") ,	// texte de 3 caractères minimum, retour à la ligne possible
		"texte"   : new RegExp("^(.|\n|\r|\n\r){3,}$","i") ,	// texte de 3 caractères minimum, retour à la ligne possible
		"mail"    : new RegExp("^([a-zA-Z0-9_-])+([.]?[a-zA-Z0-9_-]{1,})*@([a-zA-Z0-9-_]{2,}[.])+[a-zA-Z]{2,3}\\s*$","i") , // adresse mail valide customer@fai.ext
		"mdp"     : new RegExp("^.{8,32}$","i") ,	// mot de passe entre 5 et 32 caractères
		"date"    : new RegExp("^[0-9]{2}/[0-9]{2}/[0-9]{4}$","i") , // date au format 01/01/2000
		"ip"      : new RegExp("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$","i") , // adresse IPV4
		"tel"     : new RegExp("^(.|\n|\r|\n\r){5,}\\s*$","i") ,	// numero de téléphone français
		"cp" 	  : new RegExp("^[a-zA-Z0-9_-]{5,}$","i"),	// code postal
		"fichier" : new RegExp("^.+\.[a-zA-Z]{2,5}$","i")	// fichiers à uploader
	};
	// ###-----------------### Vous n'avez rien besoin de changer au delà de cette limite ###-----------------###
	// variables globales
	var timer;
	var ex="";
	var foc;
	var reg;
	
	// FONCTION de détection des formulaires afin d'initialiser le comptage et les événements de vérification de champs
	// VARIABLES n : nom [str] - nom des formulaires
	$("form").each(function() {
	
		// formulaire concerné (cas de multi formulaire)
		var n=$(this).attr("name"); 

		//comptage initial
		compte(n);
		
		// vérification des champs au lancement
		$("form[name='"+n+"'] :input[class*='obligatoire'][type!='checkbox']").each(function()  { expression(this); verification(this,n); });
		$("form[name='"+n+"'] :input[class*='obligatoire'][type='checkbox']").each(function() { verifbox(this,n); });
																									   
		$("form[name='"+n+"'] :input[class*='valide'][type!='checkbox']").each(function()  { expression(this); verification(this,n); });
		$("form[name='"+n+"'] :input[class*='valide'][type='checkbox']").each(function() { verifbox(this,n); });
	
		// OBLIGATOIRE
		// gestion d'événements sur tous les champs qui ont une classe obligatoire et qui ne sont pas des checkbox
		$("form[name='"+n+"'] :input[class*='obligatoire'][type!='checkbox']").focus(function() { foc=$(this); expression(foc); });
		$("form[name='"+n+"'] :input[class*='obligatoire'][type!='checkbox']").keyup(function() { verification(this,n);  });
		$("form[name='"+n+"'] :input[class*='obligatoire'][type!='checkbox']").change(function() { verification(this,n); });		
		// gestion d'événements sur toutes les checkbox
		$("form[name='"+n+"'] :input[class*='obligatoire'][type='checkbox']").click(function() { verifbox(this,n); });
		
		// VALIDE
		$("form[name='"+n+"'] :input[class*='valide'][type!='checkbox']").focus(function() { foc=$(this); expression(foc); });
		$("form[name='"+n+"'] :input[class*='valide'][type!='checkbox']").keyup(function() { verification(this,n);  });
		$("form[name='"+n+"'] :input[class*='valide'][type!='checkbox']").change(function() { verification(this,n); });
		
		// permet la vérification d'un champ à interval régulier. Afin de palier au problème lié au non événement lorsqu'un utilisateur choisi dans une liste de suggestion un mot en le cliquant 
		$("form[name='"+n+"'] :input[type='text'][class*='obligatoire']").focus(function(){ clearInterval(timer); timer=setInterval(function(){ test(foc,n)}, 500); });
		$("form[name='"+n+"'] :input[type='text'][class*='obligatoire']").blur(function(){ clearInterval(timer); });
	});
	
	// FONCTION de comptage du nombre de champs obligatoires restants
	// PARAMETRES n : nom [string] - nom du formulaire concerné
	// VARIABLES i : compteur [int] - compteur de champs obligatoires
	function compte(n) {
		var i=0;
		$("form[name='"+n+"'] :input[class*='obligatoire']").each(function() { i++; });
		
		if (i==0) {
			$("form[name='"+n+"'] :input[type='submit']").removeAttr("disabled");
			$("form[name='"+n+"'] :input[type='submit']").addClass("complet");
			$("form[name='"+n+"'] .forminfo").html(ok);
		} else {
			$("form[name='"+n+"'] :input[type='submit']").attr("disabled","disabled");
			$("form[name='"+n+"'] :input[type='submit']").removeClass("complet");
			(i==1)? $("form[name='"+n+"'] .forminfo").html(reste+i+champ) : $("form[name='"+n+"'] .forminfo").html(reste+i+champs);
		}
		
	}
	
	// FONCTION de vérification du changement de la valeur "value" du champ, ce qui impliquerait que la personne a cliqué dans l'autocompletebox
	// PARAMETRES t : this [obj] - objet concerné par le test | n : nom [obj] - nom du formulaire concerné (cas de multi formulaire)
	function test(t,n) {
		if (ex!=$(t).attr("value")) {
			ex = $(t).attr("value");
			verification(t,n);
		}
	}
	
	// FONCTION qui permet d'associer l'expression régulière à tester en fonction du type de champ (texte, mail, tel...)
	// PARAMETRES t : this [obj] - objet concerné par le test
	// VARIABLES  c : class [str] - classes du champ 
	function expression(t) {
		var c = $(t).attr("class");
		
		// recherche la regex à utiliser en fonction de la classe du champ
		for(key in regex) {
			if(c.indexOf([key])!=-1 ){
				reg=key;
			}
		}	
	}
	
	// FONCTION de vérification d'un champ
	// PARAMETRES t : this [obj] - champ concerné | n : nom [obj] nom du formulaire concerné (cas de multi formulaire)
	// VARIABLES  c : class [str] - classes du champ | v : valide [bool] - vérification valide ou non | b : confirmation [bool] - vérification de la confirmation | var d : identifiant [str] - identifiant du champ (cas de re saisie de confirmation)
	function verification(t,n)  { 		
		var c = $(t).attr("class");
		var d = $(t).attr("id");
		var v = false;
		var b = true;
		
		// si c'est un champ de confirmation, vérification que la valeur corresponde à la première saisie
		if(d.indexOf("verif")!=-1) {
			b=confirmation(t,n);
		}
		
		// vérification si c'est un champ destiné a être vérifié par une re saisie
		if (d.indexOf("chp")!=-1) {
			var m=$(t).attr("id").substr(3,$(t).attr("id").length);
			verification($("form[name='"+n+"'] :input[id='verif"+m+"']"),n)
		}
		
		// vérification de la conformité du champ avec la regex
		if($(t).attr("value").match(regex[reg]) ){
			v=true;
		}
		
		if (v && b) { 
			if (c.indexOf("obligatoire")!=-1) { // mais changement seulement si on passe de obligatoire a valide (donc une fois) (laisser en cascade)
				$(t).addClass("valide");
				$(t).removeClass("obligatoire");
				$(t).next().html('<img src="visu_site/val.png" width="16" height="16" alt="Valide" />');
			}
		} else if(c.indexOf("valide")!=-1) { // sinon, si on passe de valide à obligatoire (donc une fois)  
			$(t).addClass("obligatoire");
			$(t).removeClass("valide");
			$(t).next().html('<img src="visu_site/obl.png" width="16" height="16" alt="Obligatoire" />');
		}
		compte(n);
	}
	
	// FONCTION de validation des checkbox
	// PARAMETRES t : this [obj] - champ concerné | n : nom [obj] nom du formulaire concerné (cas de multi formulaire)
	function verifbox(t,n) {
		if ($(t).attr("checked")) {
			$(t).addClass("valide");
			$(t).removeClass("obligatoire");
			$(t).next().html('<img src="visu_site/val.png" width="16" height="16" alt="Valide" />');
		} else { 
			$(t).addClass("obligatoire");
			$(t).removeClass("valide");
			$(t).next().html('<img src="visu_site/obl.png" width="16" height="16" alt="Obligatoire" />');
		}
		compte(n);
	}
	
	// FONCTION de confirmation de la saisie d'un champ. ex : champ mot de passe à taper 2 fois
	// PARAMETRES t : this [obj] - champ concerné | n : nom [obj] nom du formulaire concerné (cas de multi formulaire)
	// VARIABLES  m : id champ [int] - identifiant du champ à vérifier | f : first [str] - valeur du champ à confirmer | s : second [str] - valeur du champ de confirmation
	function confirmation(t,n)  { 
		var m=$(t).attr("id").substr(5,$(t).attr("id").length);
		
		var f=$("form[name='"+n+"'] :input[id='chp"+m+"']").attr("value");
		var s=$("form[name='"+n+"'] :input[id='verif"+m+"']").attr("value");
			
		if(f==s) { return true; }
	}
});
