
/**
 * Variables globales
 */
  var langue ;
  var dateFormat;
  var cstDateFormatAnglais     ;
  var cstDateFormatFrancais    ;
  var symbols = ["/", "\"", ">", "<", "&", "{", "}", "\\", "_", "-", ",", "(", ")", " ", ".", ";", "%", "£", "$", "#", "~", "+", "=", "|", ":", "!", "§", "?", "*", "%", "@", "'", "?", "`", "^", "°", " "];
  var forbiddenSymbolsInString = ["\"",  "<", ">", "\\", "|", ";"];
  var dateSeparator = "- :/";
  var eMailCaracters = "-@._'";


/**
 *
 * Initialisation des variables globales
 * Cette méthode rappatrie les variables précisant la langue et les formats de
 * dates qui doivent être déclarés de façon globale.
 */
function initControlForm(){

  if (isStringNull(langue)) {
    langue = "fr";
  }

  if (isStringNull(cstDateFormatAnglais)) {
    cstDateFormatAnglais =  "MM/DD/YYYY";
  }

  if (isStringNull(cstDateFormatFrancais)) {
    cstDateFormatFrancais =  "DD/MM/YYYY";
  }

  if (isStringNull(dateFormat)) {
    setDateFormat(cstDateFormatFrancais)
  }
}

/**
 * Setter de langue
 */
function setLangue(newLangue){
  langue = newLangue;
}

/**
 * Setter de dateFormat
 */
function  setDateFormat(newDateFormat){
  dateFormat = newDateFormat;
}

/*
* La fonction validateFields permet d?exécuter les contrôles de validation
* passés en paramètres. Pour chaque objet de validation, elle récupère le
* code du contrôle à appliquer ainsi que ces paramètres, puis, elle appel
* la fonction de contrôle appropriée.
*/
function validateFields(form, validationObjects ) {
   var ret = true ;
   initControlForm();
   /* On boucle sur les objets de validation */
   for  (i=0; i< validationObjects.length; i++){

     //var field =getFieldByName(form, validationObjects[i].fieldName);
     var field = document.getElementById(form.id + ':' + validationObjects[i].fieldName);
     var message = validationObjects[i].message;
     var messageDateNonValide = validationObjects[i].message2;
     switch (validationObjects[i].validator.toUpperCase()) {
     case ('DATE') :
	   var aFormat = validationObjects[i].format ;
       if (isDate(field, aFormat) == -1) {
		 ret= false ; field.focus() ; alert(message) ;
	   }else if (isDate(field, aFormat) == -2) {
		 ret= false ; field.focus() ; alert(messageDateNonValide) ;
	   }
	   break;

	 case('NUMBER') :
       if ( ! isNumeric(field)) {
		 ret = false ; field.focus() ; alert(message) ;
	   }
       break;
     case('EMAIL'):
       if ( ! isEmail(field)) {
		 ret = false ; field.focus() ; alert(message) ;
	   }
       break;
	 case('FLOAT'):
	   var decimal = validationObjects[i].decimal ;
	   var separator = validationObjects[i].separator;
	   if ( ! isFloat(field,decimal,separator)) {
		 ret = false ; field.focus() ; alert(message) ;
	   }
       break;

	 case('LENGTH') :
	   var min = validationObjects[i].min ;
   	   var max = validationObjects[i].max ;
	   if ( !validateLength(field,min,max) ) {
		 ret = false ; field.focus() ; alert(message) ;
	   }
       break;
	 case('ISNULL') :
	   if ( isNull(field)) {
		 ret = false ; field.focus() ; alert(message) ;
	   }
       break;
	 case('COMPTE') :
	   if ( ! validateCompte(field)) {
		 ret = false ; field.focus() ; alert(message) ;
	   }
       break;
     default:
       break;
     }

   }
   return ret ;
}




/******************************************************
* Les fonctions élémentaires de validation.
********************************************************/

/*
* Permet de savoir si une chaine est une date au format a Format.
* Renvoi true si la fonction s'est correctement terminée sinon false.
*/
function isDate(field, aFormat){

  var uneChaine = field.value;
  var bErreur=0;
  var sCharSep = "/";

  if (uneChaine.length!=0) {

     uneChaine=calculFormatDate(uneChaine,aFormat);

     if (uneChaine!="" && uneChaine!=null && uneChaine.length!=0 && uneChaine!="X") {
		var iPosFirst = uneChaine.indexOf(sCharSep);

        var iPosSecond = uneChaine.lastIndexOf(sCharSep);

        var iJour = uneChaine.substring(0, iPosFirst);
        var iMois = uneChaine.substring(iPosFirst + 1, iPosSecond);
        var iAn = uneChaine.substring(uneChaine.lastIndexOf(sCharSep) + 1);

        //test des plages
        if ( (iMois < 1 || iMois > 12) || (iJour < 1 || iJour > 31) || (iAn < 1900 || iAn > 2050) || ((iMois == 4 || iMois == 6 || iMois == 9 || iMois == 11) && (iJour == 31)) )
          bErreur = -2;

        //test sur les années bissextiles
        if (iMois == 2 && ((iJour > 29) || ((iJour == 29 && ((iAn / 4)!=parseInt(iAn / 4))))) )
          bErreur = -2;

      } else bErreur=-1;
  } else bErreur=-1;

  //if (bErreur) return false;
  //else return true;
  return bErreur;
}


/*
* Renvoie la date au format aFormat si ce dernier est renseigné sinon au format par défaut (français)
* , "" si sInput est vide, "X" si sInput est incorrect
*/
function calculFormatDate(sInput, aFormat) {
  var iPos=0;
  var sCharSep="";
  var sMois="";
  var sJour="";
  var sAn="";

  if (aFormat!="" && aFormat != null) {
  	setDateFormat(aFormat.toUpperCase());
  }
  else {
  	// format de date francais par défaut
  	setDateFormat(cstDateFormatFrancais);
  }

  if (sInput==""||sInput==null) {
    return "";
  }

  if (sInput.length!=dateFormat.length) {
    return "";
  }

  while (iPos<dateFormat.length){
    if (dateFormat.substring(iPos, iPos+3) == "MMM") {
      var trouve = false;
      sMois=sInput.substring(iPos, iPos+3);
      for (i=0; i<12; i++){
        if (sMois==moisReduitAnglais[i]) {
          sMois=i+1;
          trouve = true;
          break;
        }
      }
      if (trouve==false) {
        return "X"; // Mois pas trouvé
      }
      else {
        iPos=iPos+3;
      }
    }
    else if (dateFormat.substring(iPos, iPos+2) == "MM") {
      sMois=sInput.substring(iPos, iPos+2);
      if ( sMois.length == 2 && isCharNumeric(sMois.charAt(0)) && isCharNumeric(sMois.charAt(1)) ) {
        iPos=iPos+2;
      }
      else {
        return "X"; // Mois pas trouvé
      }
    }
    else if (dateFormat.substring(iPos, iPos+2) == "DD") {
      sJour=sInput.substring(iPos, iPos+2);
      if ( sJour.length == 2 && isCharNumeric(sJour.charAt(0)) && isCharNumeric(sJour.charAt(1))) {
        iPos=iPos+2;
      }
      else {
        return "X"; // Jour pas trouvé
      }
    }
    else if (dateFormat.substring(iPos, iPos+4) == "YYYY") {
      sAnnee=sInput.substring(iPos, iPos+4);
      if (sAnnee.length == 4 && isCharNumeric(sAnnee.charAt(0)) && isCharNumeric(sAnnee.charAt(1)) && isCharNumeric(sAnnee.charAt(2)) && isCharNumeric(sAnnee.charAt(3))) {
        iPos=iPos+4;
      }
      else {
        return "X"; // Année pas trouvée
      }
    }
    else if (dateFormat.substring(iPos, iPos+2) == "YY") {
      sAnnee=sInput.substring(iPos, iPos+2);
      if (sAnnee.length == 2 && isCharNumeric(sAnnee.charAt(0)) && isCharNumeric(sAnnee.charAt(1))) {
        sAnnee="20"+sAnnee;
        iPos=iPos+2;
      }
      else {
        return "X"; // Année pas trouvée
      }
    }
    else if (dateSeparator.indexOf(dateFormat.substring(iPos, iPos+1)) != -1) { // In la liste des sep (-/ :)
      sSep=sInput.substring(iPos, iPos+1);
      if (sSep == dateFormat.substring(iPos, iPos+1))
        iPos=iPos+1;
      else
        return "X"; // Separateur incorrect
    }
  }
  sMois = lpad(sMois, '0', 2);

  return (sJour + "/" + sMois + "/" + sAnnee);
}

/*
* Permet de savoir si un champ est numérique.
* Renvoi true si la fonction s'est correctement terminée sinon false.
*/
function isNumeric(unChamp) {
  var sChaine=unChamp.value;
  if (sChaine.length!= 0) {
    for (var iCpt=0;iCpt<sChaine.length;iCpt++) {
      var sCar=sChaine.charAt(iCpt);
      if (!isCharNumeric(sCar)) {
        return false;
      }
    }
  }
  return true;
}

/*
* Permet de savoir si un champ est décimal
* Le séparateur est la , si langue = francais et . sinon
* Renvoi true si la fonction s'est correctement terminée sinon false.
*/
function isFloat(unChamp, decimal, separator) {

  var sChaine=unChamp.value;
  var nbOcc = 0;
  var decPos = 0;
  var decPart ="";

  if (sChaine.length!= 0) {
	  for (var iCpt=0;iCpt<sChaine.length;iCpt++) {
	      var sCar=sChaine.charAt(iCpt);
	      if (langue=="fr" && !isCharNumeric(sCar) && sCar != ",") nbOcc++;
	      if (langue!="fr" && !isCharNumeric(sCar) && sCar != ".") nbOcc++;
	      if (sCar == "," || sCar == ".") decPos = iCpt;
	  }

	  // CTRL de double "," ou "."
	  if (sChaine.indexOf(",") != sChaine.lastIndexOf(",")) nbOcc++;
	  if (sChaine.indexOf(".") != sChaine.lastIndexOf(".")) nbOcc++;

	  // CTRL partie decimal
	  decPart = sChaine.substring(decPos+1,sChaine.length);
	  if (decPart.length != decimal)nbOcc++
	  if (nbOcc!=0){
	    return false;
	  }
	  else return true;
  }
  else return true;
}


/**
* test si la longueur d'un champ est comprise dans l'intervale [min max]
**/
function validateLength(field,min,max) {
  var ret = true;
  var chaine = field.value;

  if (chaine.length != 0) {
	  // ctrl par rapport à la borne inferieure
	  if (min != "" && min != null && min>0) {
			if (chaine == "" || chaine == null ) {
				ret = false;
			}
			else if (chaine.length <min) {
			    ret = false;
			}
	  }
	  // ctrl par rapport à la borne superieure
	  if (max != "" && max != null && max>0) {
			if (chaine == "" || chaine == null ) {
				ret = false;
			}
			else if (chaine.length >max) {
			    ret = false;
			}
	  }
  }

  return ret;
}

/*
* Permet de savoir si un champ est un e-Mail.
* champ e-mailne peut contenir que les caractères alphanumériques en minuscule
* et majuscule sans accent, les chiffres (0 à 9), '_', '@', '.', '-' :
* Renvoi true si la fonction s'est correctement terminée sinon false.
*/
function isEmail(unChamp) {

  var sChaine=unChamp.value;
  var nbOcc = 0;

  if (sChaine.length!= 0) {

	  var regexp = new RegExp("^[a-zA-Z0-9_\\-\\.]{3,}@[a-zA-Z0-9\\-_]{2,}\\.[a-zA-Z]{2,4}$", "g");
	  if (!regexp.test(sChaine)) {
	    return false;
	  }
	  else {
	  	return true;
	  }
	  /**
	  /**
	  for (var iCpt=0;iCpt<sChaine.length;iCpt++) {
	      var sChar=sChaine.charAt(iCpt);
	      if ( !isCharNumeric(sChar) && !isCharLetter(sChar) && eMailCaracters.indexOf(sChar)==-1 )
	        nbOcc++;
	  }

	  // CTRL de double "@"
	  if (sChaine.indexOf("@") != sChaine.lastIndexOf("@")) nbOcc++;

	  var pos = sChaine.indexOf("@");
	  var post = sChaine.substring(pos+1,pos+2);
	  var pre = sChaine.substring(pos-1,pos);
	  var end = sChaine.substring(sChaine.length -1,sChaine.length);
	  var beg = sChaine.substring(0,1);

	  if (eMailCaracters.indexOf(post)!= -1) nbOcc++;
	  if (eMailCaracters.indexOf(pre) != -1) nbOcc++;
	  if (eMailCaracters.indexOf(end) != -1) nbOcc++;
	  if (eMailCaracters.indexOf(beg) != -1) nbOcc++;

	  if (nbOcc!=0) {
	    var caracters = "";
	    for (var iCpt=0;iCpt<eMailCaracters.length;iCpt++) {
	      caracters += eMailCaracters.charAt(iCpt)+ " ";
	    }
	    return false;
	  }
	  else return true;
	  **/
   }
   else return true;
}

/**
* test si un champ est null ou pas
**/
function isNull(field) {
    var oblig = false;
    //isnull est testé sur les combos
     if (field.type.toUpperCase().indexOf("SELECT") != -1) {
          if ( field.selectedIndex==-1 || field.options[field.selectedIndex].value==null || field.options[field.selectedIndex].value.length==0) {
              oblig=1;
          }
     }
     else {
          if ((field.value==null) || (field.value.length==0)) {
              oblig=1;
          }
     }
     if (oblig==1) {
          return true;
     }
     else {
    	  return false;
     }
}



/**
Fonctions de création d'objets de validation.
**/
// Objet de validation de type DATE
/**
function addDateValidatorObject(listValidationObjects, fieldName, dateFormat) {
	var obj = new dateValidatorObject(fieldName, dateFormat);
	listValidationObjects.push(obj);

}
**/
function dateValidatorObject(fieldName, dateFormat, message, message2){
    this.validator = "DATE";
    this.fieldName = fieldName;
    this.format = dateFormat;
    this.message = message;
    this.message2 = message2;
}

// objet de validation de type LENGTH
/**
function addLengthValidatorObject(listValidationObjects,fieldName,min,max) {
	alert("addDateValidatorObject()");
	var obj = new lengthValidatorObject(fieldName, min,max);
	listValidationObjects.push(obj);
}
**/
function lengthValidatorObject(fieldName, min,max,message){

    this.validator = "LENGTH";
    this.fieldName = fieldName;
    this.min = min;
    this.max = max;
    this.message = message;

}

// objet de validation de type NUMBER
/**
function addNumberValidatorObject(listValidationObjects,fieldName) {
	var obj = new numberValidatorObject(fieldName);
	listValidationObjects.push(obj);

}
**/
function numberValidatorObject(fieldName, message){
    this.validator = "NUMBER";
    this.fieldName = fieldName;
    this.message = message;
}

// objet de validation de type FLOAT
/**
function addFloatValidatorObject(listValidationObjects,fieldName,decimal) {
	var obj = new floatValidatorObject(fieldName, decimal);
	listValidationObjects.push(obj);

}
**/
function floatValidatorObject(fieldName, decimal, separator ,message){
    this.validator = "FLOAT";
    this.fieldName = fieldName;
    this.decimal = decimal;
    this.separator = separator;
    this.message = message;
}

// objet de validation de type EMAIL
/**
function addEmailValidatorObject(listValidationObjects,fieldName) {
	var obj = new emailValidatorObject(fieldName);
	listValidationObjects.push(obj);

}
**/
function emailValidatorObject(fieldName, message){
    this.validator = "EMAIL";
    this.fieldName = fieldName;
    this.message = message;
}

// objet de validation de type ISNULL
/**
function addNotEmptyValidatorObject(listValidationObjects,fieldName) {
	var obj = new notEmptyValidatorObject(fieldName);
	listValidationObjects.push(obj);

}
**/
function notEmptyValidatorObject(fieldName, message){
    this.validator = "ISNULL";
    this.fieldName = fieldName;
    this.message = message;
}

/*
* Permet de récupérer une référence sur un champ (dans le formulaire précisé)
* dont le nom est passé en paramètre.
*/
function getFieldByName(unFormulaire,unNomDeChamp) {
  if (unFormulaire!=null) {
    if (unNomDeChamp!=null && unNomDeChamp.length>0) {
      var nbElt=unFormulaire.elements.length;
      var indice=-1;

      for (var cptElt=0;cptElt<nbElt;cptElt++) {
        var field=unFormulaire.elements[cptElt];
        var nomField=field.name;
        var nbCarNom=nomField.length;
        for (var cptCar=0;cptCar<nbCarNom;cptCar++) {
          var car=nomField.charAt(cptCar);
          if (car=="$") {
            indice=cptCar;
            break;
          }
        }

        var nomCalc;
        if (indice!=-1) {
          nomCalc=nomField.substring(0,indice);
          indice=-1;
        } else {
          nomCalc=nomField;
        }

        if (nomCalc==unNomDeChamp) {
          return field;
        }
      }
    }
  }
  return null;
}


/*
* test si une chaine est null
*/
function isStringNull(maChaine) {
  if (maChaine==null || maChaine=="" || maChaine.length==0)
   return true;
  else
   return false;
}

/*
 * Teste si le caractère est numérique (entre 0 et 9)
 * retourne faux sinon
 */
function isCharNumeric(sChar) {
  if ((sChar<"0"||sChar>"9"))
    return false;
  else
    return true;
}

/*
* Teste si le caractère est une lettre sans accent(en majuscule ou pas)
* retourne faux sinon
*/
function isCharLetter(sChar) {
  if ((sChar>="a" && sChar<="z") || (sChar>="A" && sChar<="Z"))
    return true;
  else
    return false;
}

/*
* Ajoute un caractère en tête d'une chaine
*/
function lpad(uneChaine, unCar, nombre) {
        var sChaine='';
        var taille;

  uneChaine=''+uneChaine;
  taille=nombre - uneChaine.length;
  while (taille>0) {
    sChaine=sChaine+unCar;
    taille--;
  }
  sChaine=sChaine+uneChaine;
  return sChaine;
}

