// Ce fichier contient les fonctions de control de saisi
// 
// La fonction principale est checkField(-, -, -, -, -)


//==================================================
// Declaration des formats par defaut
//==================================================
var separateurDecimal = ",";
var separateurMilliers = unescape("%A0");
var dateFormatIn = "dd/mm/yy";
var dateFormatOut = "DD/MM/yyyy";
var hourSeparator = ":";


//==================================================
//  tempStatus ecrit un message dans la bare d'état
//    et l'enlève automatiquement au bout de 4 sec
//==================================================
function tempStatus(message)
{
	window.status = message;
	window.setTimeout("window.status=''", 4000);
}

//==================================================
//  myReplace remplace une sous-chaine sans la 
//   considérer comme une expression régulière regex
//==================================================
function myReplace(str, oldStr, newStr) {
	return str.split(oldStr).join(newStr);
}

//==================================================
//  removeLeadingZeros enlève les 0 du début de la 
//   chaine afin d'éviter qu'elle ne soit considérée
//   comme un entier en base 8 ou 16
//==================================================
function removeLeadingZeros(str) {
	if (str == '')
		return str;
	var i = 0;
	while (i < str.length && str.substr(i , 1) == '0')
		i++;
	if (i == str.length)
		return '0';
	return str.substr(i);
}



//==================================================
// checkDate controle si une chaine (non vide) 
//   peut être intertprétée en date étant donné
//   un format d'entrée. Si c'est le cas, elle
//   elle rend la date suivant un format de retour,
//   sinon elle rend la chaine vide
//==================================================
function checkDate(strDate, srcFormat, dstFormat) {
// Le format :
// Séparateur / uniquement
// mm, MM, dd, DD, yy, yyyy

//--------------------------------------------------
// On verifie que le format d'entrée est acceptable
//--------------------------------------------------
	var srcFmt = srcFormat.split('/');
	var srcIndex = new Array(-1, -1, -1);
	var i;

	if(srcFmt.length != 3) return '';

	for(i = 0; i < 3; i++) {
		if(srcFmt[i].toLowerCase() == 'dd') {
			srcIndex[0] = i;
		} else if(srcFmt[i].toLowerCase() == 'mm') {
			srcIndex[1] = i;
		} else if(srcFmt[i].toLowerCase() == 'yy' || srcFmt[i].toLowerCase() == 'yyyy') {
			srcIndex[2] = i;
		} else {
			return '';
		}
	}
	for(i = 0; i < 3; i++) {
		if(srcIndex[i] == -1) return '';
	}

//--------------------------------------------------
// On verifie si le format de retour est acceptable
//--------------------------------------------------
	var dstIndex;
	var dstFmt;
	if (!dstFormat || dstFormat == '') {
		dstFmt = srcFmt;
		dstIndex = srcIndex;
	} else {
		dstFmt = dstFormat.split('/');
		dstIndex = new Array(-1, -1, -1);

		if(dstFmt.length != 3) return '';

		for(i = 0; i < 3; i++) {
			if(dstFmt[i].toLowerCase() == 'dd') {
				dstIndex[0] = i;
			} else if(dstFmt[i].toLowerCase() == 'mm') {
				dstIndex[1] = i;
			} else if(dstFmt[i].toLowerCase() == 'yy' || dstFmt[i].toLowerCase() == 'yyyy') {
				dstIndex[2] = i;
			} else {
				return '';
			}
		}
		for(i = 0; i < 3; i++) {
			if(dstIndex[i] == -1) return '';
		}
	}

//--------------------------------------------------
// Les formats sont OK, on vérifie la valeur donnée
//--------------------------------------------------
	var majFmt = new Array('DD', 'MM', 'YY');
	var unsortedDate = strDate.split('/');
	
	if (unsortedDate.length != 3)
		return '';
	
	for(i = 0; i < 3; i++) {
//		if(isNaN(unsortedDate[i])) {
		if(isNaN(removeLeadingZeros(unsortedDate[i]))) {
			return '';
		}
	}

	var sortDate = new Array(3);

	for(i = 0; i < 3; i++) {
//		sortDate[i] = parseInt(unsortedDate[srcIndex[i]]);
		sortDate[i] = parseInt(removeLeadingZeros(unsortedDate[srcIndex[i]]));
		// modif
		// rajouté par RaF pour éviter que dd/mm/ se transforme en dd/mm/NaN
		if (isNaN(sortDate[i])) {
			return '';
		}
		// fin modif
	}

		// vérification du mois
	if(sortDate[1] < 1 || sortDate[1] > 12) {
		return '';
	}

		// passage à 4 chiffres de l'année
	if(sortDate[2] < 100) {
		if(sortDate[2] > 90) {
			sortDate[2] += 1900;
		} else {
			sortDate[2] += 2000;
		}
	}

		// vérification du jours
	var maxDays;
	switch (sortDate[1]) {
		case 2:
			if((sortDate[2] % 4) == 0 && (!((sortDate[2] % 100) == 0) || (sortDate[2] % 400) == 0)) {
				maxDays = 29;
			} else {
				maxDays = 28;
			}
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			maxDays = 30;
		default:
			maxDays = 31;
	}

	if(sortDate[0] < 1 || sortDate[0] > maxDays) return '';


//--------------------------------------------------
// La valeur donnée est OK, 
//     on la rend selon le format de retour
//--------------------------------------------------
	for(i = 0; i < 3; i++) {
		if(dstFmt[dstIndex[i]].substring(0, 2) == majFmt[i]) {
			unsortedDate[dstIndex[i]] = '0000' + sortDate[i].toString();
			unsortedDate[dstIndex[i]] = unsortedDate[dstIndex[i]].substring(unsortedDate[dstIndex[i]].length - dstFmt[dstIndex[i]].length);
		} else {
			unsortedDate[dstIndex[i]] = sortDate[i].toString();
			if(unsortedDate[dstIndex[i]].length > dstFmt[dstIndex[i]].length) {
				unsortedDate[dstIndex[i]] = parseInt(unsortedDate[dstIndex[i]].substring(unsortedDate[dstIndex[i]].length - dstFmt[dstIndex[i]].length)).toString();
			}
		}
	}

	return unsortedDate.join('/');
}



//==================================================
// checkHour verifie si une chaine peut être
//  inteprétée en une heure. Le second paramètre
//  est le séparateur des heures / minutes
//==================================================
function checkHour(strHour, key) {
	var dstHour = new Array(0, 0);
	var srcHour = strHour.split(key);

	if(srcHour.length == 2) {
		for(i = 0; i < 2; i++) {
			dstHour[i] = srcHour[i];
		}
	} else {
		if(strHour.length <= 2) {
			dstHour[0] = strHour;
		} else if(strHour.length <= 4) {
			dstHour[0] = strHour.substring(0, strHour.length - 2);
			dstHour[1] = strHour.substring(strHour.length - 2);
		} else {
			return '';
		}
	}

	var hourLimit = new Array(23, 59);
	for(i = 0; i < 2; i++) {
		if(isNaN(dstHour[i])) {
			return '';
		} else if(parseInt(dstHour[i]) < 0 || parseInt(dstHour[i]) > hourLimit[i]) {
			return '';
		} else {
			dstHour[i] = '00' + dstHour[i];
			dstHour[i] = dstHour[i].substring(dstHour[i].length - 2);
		}
	}
	return dstHour.join(key);
}



//==================================================
// checkEmail contrôle si une chaine peut être 
//  syntaxiquement considérée comme une adresse
//  e-mail, si c'est le cas elle rend la valeur
//  d'entrée sinon elle rend la chaine vide.
//==================================================
function checkEmail(laValeur) {
   pos = laValeur.indexOf("@");
   if (pos == -1)
      return "";

   gauche = laValeur.substring(0 , pos);
   droite = laValeur.substr(pos + 1);

   if ( gauche == "" || escape(gauche) != gauche )
      return "";

   pos = droite.indexOf(".");
   if (pos == 0)
      return "";

   pos = droite.indexOf("..");
   if (pos != -1)
      return "";

   pos = droite.lastIndexOf(".");
   if ( (pos == -1) || (droite.indexOf("@") != -1) || (escape(droite) != droite) || ((pos != (droite.length - 3)) && (pos != (droite.length - 4))) )
      return "";

   return laValeur;
}



//==================================================
//  checkInteger essaie de convertir une chaine en 
//    un nombre entier; si elle y arrive, elle rend
//    une chaine qu'est le nombre trouvé reformatté 
//    avec l'éventuel séparateur de milliers.
//==================================================
function checkInteger(laValeur , sepMil) {
	var sep=separateurMilliers; var valTxt; var i; var j; var c; var res=""; var neg=0;
	
	if (sepMil)
	sep = sepMil;
	
	valTxt = removeLeadingZeros(laValeur);
	valTxt = myReplace(valTxt, " ", "");
	valTxt = myReplace(valTxt, sep, "");
	
	for (i=0 ; i<valTxt.length ; i++) {
		c = valTxt.substr(i , 1);
		if (i>0)
			if (c<"0" || c>"9")
				return "";
			else if ((c<"0" || c>"9") && c!="-") 
				return "";
	}

	nVal = parseInt(valTxt);   
	if (isNaN(nVal))
	  return "";

	valTxt = nVal.toString();
   
	if (valTxt.substr(0 , 1) == "-") {
		neg = 1;
		valTxt = valTxt.substr(1);
	}

	res="";
	for (j=0 , i=valTxt.length-1 ; i>=0 ; i-- , j++) {
		if (j!=0 && j%3 == 0)
			res = sep + res;
		res = valTxt.substr(i , 1) + res;
	}
	if (neg == 1)
		res = "-" + res;
   	
	return res;
}



//==================================================
//  checkFloat essaie de convertir une chaine en
//   un nombre réél; si elle y arrive, elle rend
//   une chaine qu'est le nombre trouvé reformatté
//   avec le séparateur de décimaux et l'éventuel 
//   séparateur de milliers. 
//==================================================
function checkFloat(laValeur , sepDeci, sepMil) {
   var sep=separateurMilliers; var sepDec=separateurDecimal; var valTxt; var i; var j; var c; var res=""; var neg=0; var pos; var sepDec;
   
   if (sepMil)
   	sep = sepMil;
   	
   if (sepDeci)
   	sepDec = sepDeci;

   valTxt = removeLeadingZeros(laValeur);
   valTxt = myReplace(valTxt, " ", "");
   valTxt = myReplace(valTxt, sep, "");
   valTxt = myReplace(valTxt , sepDec , ".");
	
	for (i=0 ; i<valTxt.length ; i++) {
		c = valTxt.substr(i , 1);
		if (i>0)
			if ((c<"0" || c>"9") && c!=".") 
				return "";
			else if ((c<"0" || c>"9") && c!="." && c!="-")
				return "";
	}

   if ( valTxt.indexOf(".") > -1 && valTxt.lastIndexOf(".") != valTxt.indexOf(".") )
   	return "";
   
   nVal = parseFloat(valTxt);
   if (isNaN(nVal))
      return "";

   valTxt = nVal.toString();
   
   if (valTxt.substr(0 , 1) == "-") {
   	neg = 1;
   	valTxt = valTxt.substr(1);
   }
   
   pos = valTxt.indexOf(".");
   if (pos == -1) {
   	partieEntiere = valTxt;
   	partieDecimale = "";
   } else if (pos == 0) {
   	partieEntiere = "0";
   	partieDecimale = valTxt.substr(1);
   } else {
   	partieEntiere = valTxt.substr(0, pos);
   	partieDecimale = valTxt.substr(pos+1);
   }
   
   res="";
   for (j=0 , i=partieEntiere.length-1 ; i>=0 ; i-- , j++) {
   	if (j!=0 && j%3 == 0)
   		res = sep + res;
   	res = partieEntiere.substr(i , 1) + res;
   }
   
   if (neg == 1)
   	res = "-" + res;
   	
   if (partieDecimale != "")
   	res = res + sepDec + partieDecimale;
   	
   return res;
}

//==================================================
// checkString permet d'appliquer un format sur une
//  chaîne de caractères. Le format est spécifié
//  dans le second paramètre. Il vaut 'lower', 
//  'upper' ou 'capitalize'.
//==================================================
function checkString(val, op) {
	if (val == '') {
		return '';
	}
	if (op.toLowerCase() == 'upper') {
		return val.toUpperCase();
	} else if (op.toLowerCase() == 'lower') {
		return val.toLowerCase();
	} else if (op.toLowerCase() == 'capitalize') {
		result = val.substring(0,1).toUpperCase();
		for (i=1 ; i<val.length ; i++)
		  if (val.substring(i-1, i) == ' ' || val.substring(i-1, i) == '-' || val.substring(i-1, i) == '\'')
		     result += val.substring(i, i+1).toUpperCase();
		  else
		     result += val.substring(i, i+1).toLowerCase();
		return result;
	} else {
		return val;
	}
}

// checkField est la fonction qui regroupe tous les tests
function checkField(laValeur , leType , estOblig , format1 , format2) {
   if (laValeur == "")
      if (estOblig)
         return false;
      else
         return true;


   if (leType.toLowerCase() == "date")
      return checkDate(laValeur , format1 , format2)

   if (leType.toLowerCase() == "hour")
      return checkHour(laValeur , format1);

   if (leType.toLowerCase() == "email")
      return checkEmail(laValeur);

   if (leType.toLowerCase() == "integer")
      return checkInteger(laValeur , format1);

   if (leType.toLowerCase() == "float")
      return checkFloat(laValeur , format1 , format2);
      
   if (leType.toLowerCase() == "string")
      return checkString(laValeur , format1);

   return laValeur;
}

//==================================================
// toSysNum prend en premier paramètre une valeur
//  numérique en chaine, en second paramètre le
//  séparateur de décimaux, en 3eme paramètre le
//  séparateur de milliers; et rend une chaine
//  prête pour un parse.
//==================================================
function toSysNum(valeur , sepDeci , sepMil) {
	var sep=separateurMilliers; var sepDec=separateurDecimal;
	
	if (sepMil)
   		sep = sepMil;
   	
  	if (sepDeci)
   		sepDec = sepDeci;
   	
	var res;
	res = myReplace(valeur , sep , "");
	res = myReplace(res , sepDec , ".");
	return res;
}

//==================================================
// prepNumsForSubmit prend en premier paramètre le
//  séparateur de décimaux, en second paramètre le
//  séparateur de milliers; les paramètres suivants
//  étant les 'Field' à reformatter.
//==================================================
function prepNumsForSubmit() {
	args = prepNumsForSubmit.arguments;
	
	sepDec = args[0];
	sepMil = args[1];
	
	for (i=2 ; i<args.length ; i++) {
		fld = args[i];
		fldVal = fld.value;
		fldVal = myReplace(fldVal , " " , "");
		fldVal = myReplace(fldVal , sepMil , "");
		fldVal = myReplace(fldVal , sepDec , ".");
		fld.value = fldVal;
	}
}

function ctrlNumField(aField, aType , mesg, sepDeci , sepMillier) {
	if (myReplace(aField.value , " " , "") == "") {
		aField.value = "";
		return true;
	}
	
	var sepMil = separateurMilliers;
	var sepDec = separateurDecimal;
	if (sepMillier)
 		sepMil = sepMillier;
 	if (sepDeci)
 		sepDec = sepDeci;
	var v;

	if (aType.toLowerCase() == "integer")
		v = checkField(aField.value, aType, false, sepMil);
	else
		v = checkField(aField.value, aType, false, sepDec, sepMil);

	if (v) {
		aField.value = v;
		return true;
	}

	if (mesg) {
		tempStatus(mesg);
 	}
	aField.value = '';
	return false;
}

function ctrlDateField(aField, mesg, formatIn, formatOut) {
	if (myReplace(aField.value , " " , "") == "") {
		aField.value = "";
		return true;
	}

	var formIn = dateFormatIn;
	var formOut = dateFormatOut;
	if (formatIn) {
		formIn = formatIn;
	}
	if (formatOut) {
		formOut = formatOut;
	}
	
	v = checkField(aField.value, 'date', false, formIn, formOut);
	
	if (v) {
		aField.value = v;
		return true;
	}

	if (mesg) {
		tempStatus(mesg);
	}
	aField.value = '';
	return false;
}

function ctrlHourField(aField, mesg, sep) {
	if (myReplace(aField.value , " " , "") == "") {
		aField.value = "";
		return true;
	}

	var separator = hourSeparator;
	if (sep) {
		separator = sep;
	}
	
	v = checkField(aField.value, 'hour', false, separator);
	
	if (v) {
		aField.value = v;
		return true;
	}

	if (mesg) {
		tempStatus(mesg);
	}
	aField.value = '';
	return false;
}
//============================================
// Compare deux dates
// parametres :
//		date1 la partie jour de la première date (par defaut '01/01/1970')
// 		hour1 la partie horaire de la première date (par défaut '00:00')
//		date2 la partie jour de la deuxième date (par defaut '01/01/1970')
// 		hour2 la partie horaire de la deuxième date (par defaut '00:00')
// 		formatDate le format de la date en entrée (par défaut 'DD/MM/yyyy')
//		sepHeure	le séparateur des heures (par défaut : )
// renvoit le nombre de millisecondes de différence
//		0 si (date1, hour1)==(date2, hour2)
//		>0 si (date1, hour1) > (date2, hour2)
//		<0 si (date1, hour1) < (date2, hour2)
//=============================================================
function compareDate(date1, hour1, date2, hour2, formatDate, sepHeure) {
	fDate = dateFormatOut;
	sep = hourSeparator;
	
	if (formatDate) {
		fDate = formatDate;
	}
	if (sepHeure) {
		sep = sepHeure;
	}
	var d1;
	var h1;
	var d2;
	var h2;	
	if (date1) {
		d1 = date1;
	} else {
		d1 = checkField("01/01/1970", "date", false, dateFormatOut, fDate);
	}
	if (hour1) {
		h1 = hour1;
	} else {
		h1 = checkField("00:00", "hour", false, hourSeparator, sep);
	}
	if (date2) {
		d2 = date2;
	} else {
		d2 = checkField("01/01/1970", "date", false, dateFormatOut, fDate);
	}
	if (hour2) {
		h2 = hour2;
	} else {
		h2 = checkField("00:00", "hour", false, hourSeparator, sep);
	}
	
	//controle
	
	s1 = checkHour(h1 , sep);
	s2 = checkDate(d1, fDate, 'MM/DD/yyyy');
	
	s3 = checkHour( h2 , sep);
	s4 = checkDate(d2, fDate, 'MM/DD/yyyy');
	
	startTime = new Date(s2.concat(" ").concat(s1));
	endTime    = new Date(s4.concat(" ").concat(s3));
	
	millidiff = startTime - endTime;
	return millidiff;
}
