//* FILE **********************************************************************
//*                                                                          **
//* NAME: inputTextWithOnChange.h                                            **
//*                                                                          **
//* GOAL: Print a INPUT TEXT Form element, with data consistency check       **
//*       done by fCheckInputType, which needs FormChek.js to work           **
//*       Don't forget to include FormChek.js before inputTextWithOnChange   **
//*                                                                          **
//*       Checked types:                                                     **
//*       number, positiveNumber, notNullInt, int, positiveInt, year         **
//*       dateMM/DD/YYYY, percent, quarter, positive1decimalFloat, stEmail   **
//*       -> other types are assumed to be custom regular expression         **
//*                                                                          **
//*****************************************************************************
//*                                                                          **
//* MODIFICATIONS:                                                           **
//*                                                                          **
//* Version  Date         Author  Comment                                    **
//*                                                                          **
//* 1.0         Dec 1999  MV      Original version                           **
//* 1.01     11 Feb 2000  MV      Add positive1decimalFloat type             **
//*                               and default to regExp                      **
//*                               piFunctionCall now needs "top." prefixe    **
//* 1.02     15 Feb 2000  MV      piFunctionCall optionnal parameter         **
//* 1.03     11 Oct 2000  MV      fInputTextWithOnChange piDisplayZeroValue  **
//* 1.04     27 Feb 2001  MV      Added positiveNotNullInt                   **
//* 1.05     27 Nov 2001  MV      fInputTextWithOnChange piNoScreenModif     **
//* 1.06     28 Nov 2001  MV      Debug: use fFilterStringQuot               **
//* 1.07     19 Feb 2002  MV      Added stEmail type                         **
//* 1.08     02 Jul 2002  MV      years must be within [1970 - 2099]         **
//* 1.2      05 Dec 2002  MV      Added fInputPcsDate and dateDDMMMYYYY      **
//* 1.3      21 Jan 2003  MV      Add fCheckRollback, fSetInputTextValue     **
//* 1.31     21 Feb 2003  MV      fSetInputTextValue launch onChange code    **
//*                                                                          **
//* FILE **********************************************************************

//*************
//* CONSTANTS *
//*************
var reDate = /^\d\d\/\d\d\/\d\d\d\d$/;
var reDateUS = /^\d\d\/\d\d\/\d\d\d\d$/;
var reSiret = /^(\d){14}$/;
var reCnuf = /^(\d){5,8}$/;

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: isDateValid                                                        **
//* GOAL: renvoie true si (year, month, day) forme une date valide           **
//*                                                                          **
//***************************************************************** FUNCTION **
function isDateValid(year, month, day)
{
  if (! isDate(year, month, day))
  {
    return false;
  }
  else
  {
    // year in [1970 - 2099]
    if (year < 1970 || year > 2099)
    {
      alert('Année invalide : "' + year + '". L\'année doit être comprise entre [1970 - 2099].');
      return false;
    }
  }
  return true;

} // isDateValid

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fConvertJJMMAAAAToDate                                             **
//* GOAL: Converti la chaine date (Ex: 25/02/1974) et renvoie un objet Date  **
//*                                                                          **
//***************************************************************** FUNCTION **
function fConvertJJMMAAAAToDate(piDateText)
{
  if (piDateText && piDateText != '')
  {
    day =   piDateText.slice(0,2);
    month = piDateText.slice(3,5);  
    year =  piDateText.slice(6,10);

    if (isDateValid(year, month, day))
      return new Date(year, month-1, day);
    else
      alert('Date invalide: "' + piDateText + '".');
  }
} // fConvertJJMMAAAAToDate

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fCheckInputType                                                    **
//* GOAL: checks that piInputField is from piType type. Warns user if not.   **
//*       piAlertString is the optionnal warn message that is printed.       **
//*                                                                          **
//***************************************************************** FUNCTION **
function fCheckInputType(piInputField, piType, piAlertString)
{
  var alertString=''; // Optional warning string

  if (piAlertString)
    alertString = piAlertString;

  switch (piType)
  {
    case '' :
      break;

    case 'notnullstr':
	if (piInputField.value==''){
		alert('Vous devez entrer une valeur : '+ piInputField.value + alertString);
		piInputField.focus();
		return false;
	}
	break;

    case 'number' :
      if (piInputField.value.length)
	    {
        var fv = parseFloat(piInputField.value, 10);
        if (isNaN(fv))
	      {
          alert('Vous devez entrer une nombre dans ce champ et utiliser le \'.\' pour les nombres à virgule: "'+ piInputField.value + '".' + alertString);
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
        else
        {
          if (piInputField.value != fv)
          {
            alert('Vous devez utiliser le \'.\' pour les nombres à virgule: "'+ piInputField.value + '".' + alertString);
          }
          piInputField.value = fv;
        }
      }
      break;

    case 'positiveNumber' :
      if (piInputField.value.length)
	    {
        if (! isFloat(piInputField.value))
	      {
          alert('Vous devez entrer une nombre positif dans ce champ et utiliser le \'.\' pour les nombres à virgule: "'+ piInputField.value + '"');
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
        else
        {
          piInputField.value = parseFloat(piInputField.value, 10);
        }
      }
      break;

    case 'notNullInt' :
      if (String(parseInt(piInputField.value, 10)) != piInputField.value )
	    {
        alert('Vous devez entrer un entier non nul: "' + piInputField.value + '"');
        piInputField.value = '0';
        return false;
      }
      else
      {
        piInputField.value = parseInt(piInputField.value, 10);
      }
      break;

    case 'int' :
      if (piInputField.value.length)
	    {
	      if (!isSignedInteger(piInputField.value))
        {
          alert('Vous devez entrer un entier : "' + piInputField.value + '"');
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
        else
        {
          piInputField.value = parseInt(piInputField.value, 10);
        }
      }
      break;

    case 'positiveInt' :
      if (piInputField.value.length)
	    {
	      // integer >= 0
        if (!isNonnegativeInteger(piInputField.value))
        {
          if (piAlertString)
            alert(alertString);
          else
            alert('Vous devez entrer un entier positif: "' + piInputField.value + '".');
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
        else
        {
          piInputField.value = parseInt(piInputField.value, 10);
        }
      }
      break;

    case 'positiveNotNullInt' :
      if (piInputField.value.length)
	    {
	      // integer > 0
        if (!isPositiveInteger(piInputField.value)) 
        {
          if (piAlertString)
            alert(alertString);
          else
            alert('Vous devez entrer un entier > 0: "' + piInputField.value + '".');
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
        else
        {
          piInputField.value = parseInt(piInputField.value, 10);  
        }
      }
      break;

    case 'year' :
      if (piInputField.value.length)
	    {
        var y = parseInt(piInputField.value, 10);
        if (String(y) != piInputField.value || y < 1970 || y > 2099)
	      {
          alert('Invalid year : "' + piInputField.value + '". Please enter an integer within [1970 - 2099] range.');
          piInputField.value = '';
          return false;
        }
      }
      break;

    case 'date' :
      theDate = piInputField.value;
      if (theDate.length)
      {
        if (! reDate.test(theDate))
	{
          alert('Format de date invalide: "' + theDate + '". Veuillez entrer une date au format (JJ/MM/AAAA).'+ alertString);
          piInputField.value = '';
          return false;
        }
        else
        {
          if (!fConvertJJMMAAAAToDate(theDate))
          {
            piInputField.value = '';
            return false;
          }
        }
      }
      break;

    case 'dateMM/DD/YYYY' :
      theDate = piInputField.value;
      if (theDate.length)
	    {
        if (! reDateUS.test(theDate))
	      {
          alert('Invalid date format : "' + theDate + '". Please enter a date in this format(MM/DD/YYYY).');
          piInputField.value = '';
          return false;
        }
        else
        {
          if (!fConvertMMDDYYYYToDate(theDate))
          {
            piInputField.value = '';
            return false;
          }
        }
      }
      break;

    case 'dateDDMMMYYYY' :
      theDate = piInputField.value;
      if (theDate.length)
	    {
        if (isDateDDMMMYYYY(theDate, true))
        {
          if (fConvertDDMMMYYYYToDate(theDate))
            break;
        }
        piInputField.value = '';
        return false;
      }
    break;

    case 'pcsDate' :
      theDate = piInputField.value;
      if (theDate.length)
	    {
        var upr = theDate.toUpperCase();
        if (upr != theDate)
        {
          theDate = upr;
          piInputField.value = theDate;
        }
        
        var d = fConvertStringToPcsDate(theDate);
        if (d)
        {
          if (reDateUS.test(theDate))
            piInputField.value = fConvertDateToDDMMMYYYY(d);
          break;
        }
        piInputField.value = '';
        return false;
      }
    break;

    case 'percent' :
      if (piInputField.value.length)
	    {
        if (isNaN(parseFloat(piInputField.value, 10)) )
	      {
          alert('Vous devez saisir un pourcentage entre [0..100]');
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
        else
        {
          if ((parseFloat(piInputField.value, 10) > 100) ||
              (parseFloat(piInputField.value, 10) < 0))
	        {
            alert('Veuillez saisir un pourcentage entre [0..100]\nPar exemple: 12.5');
            piInputField.value = '';
            piInputField.focus();
            return false;
          }
          else
          {
            piInputField.value = parseFloat(piInputField.value, 10);
          }
        }
      }
      break;

    case 'quarter' :
      val = piInputField.value;
      if (val.length)
	    {
        reQuarter = /^[1-9]\d\d\dQ[1-4]$/;
        if (! reQuarter.test(val))
	      {
          alert('Invalid Quarter format : "' + val + '". Please enter a quarter in this format: "YYYYQn" (where n is in [1-4]).');
          piInputField.value = '';
          return false;
        }
      }
      break;

    case 'positive1decimalFloat' :
      val = piInputField.value;
      if (val.length)
	    {
        rePositive1decimalFloat = /^(\d)+(\.)?(\d)*$/;
        if (! rePositive1decimalFloat.test(val))
	      {
          if (piAlertString)
            alertString = piAlertString;
          else
            alertString = '\nVeuillez saisir un nombre décimal valide. Exemple: 12 ou bien 3.14';
          alert('Nombre invalide : "' + val + '". ' + alertString);
          piInputField.value = '';
          return false;
        }
      }
      break;

    case 'email' :
      val = piInputField.value;
      if (val.length)
	    {
        if (!isEmail(val))
	      {
          if (piAlertString)
            alertString = piAlertString;
          else
            alertString = 'Veuillez entrer une adresse mail valide. (Ex: jacques.durand@societe.com)';
          alert('Email incorrect: "' + val + '". ' + alertString);
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
      }
      break;
      
    case 'urlHttp' :
      val = piInputField.value;
      if (val.length)
	    {
        if (!isUrlHttp(val))
	      {
          if (piAlertString)
            alertString = piAlertString;
          else
            alertString = 'Veuillez entrer une addresse web valide. (Ex: www.ingenicat.fr)';
          alert('Adresse web incorrecte: "' + val + '". ' + alertString);
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
      }
      break;

    case 'tel' :
      val = piInputField.value;
      if (val.length)
	    {
        if (!isInternationalPhoneNumber(val) || val.length < 9)
	      {
          if (piAlertString)
            alertString = piAlertString;
          else
            alertString = 'Veuillez entrer un numéro sans espaces ni points. 10 chiffres pour la France (Ex: 0476709495)';
          alert('Numéro invalide: "' + val + '". ' + alertString);
          piInputField.value = '';
          piInputField.focus();
          return false;
        }
      }
      break;
      
    case 'siret' :
      val = piInputField.value;
      if (val.length)
	    {
        if (! reSiret.test(val))
	      {
          alert('Numéro de SIRET invalide : "' + val + '".\nVeuillez entrer un numéro composé de 14 chiffres sans espaces');
          piInputField.value = '';
          return false;
        }
      }
      break;
      
    case 'cnuf' :
      val = piInputField.value;
      if (val.length)
	    {
        if (! reCnuf.test(val))
	      {
          alert('CNUF invalide : "' + val + '".\nVeuillez entrer un numéro composé de 5 à 8 chiffres sans espaces');
          piInputField.value = '';
          return false;
        }
      }
      break;

    default :
      val = piInputField.value;
      if (val.length)
	    {
        re = new RegExp(piType);
        if (! re.test(val))
	      {
          if (confirm('Ce texte n\'est pas conforme, il va être effacé : "' + val + '". ' + alertString))
					{
	          piInputField.value = '';
					}
					piInputField.focus();
          return false;
        }
      }
      break;
  }
  return true;
}


//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fCheckNombre                                                       **
//* GOAL: vérifie que piInputField est un nombre conforme                    **
//*       piDecimales :   nb de décimales après la virgule                   **
//*       piMin :         valeur minimum                                     **
//*       piMac :         valeur maximum                                     **
//*       piAlertString : message de warning en cas de non conformité        **
//*                                                                          **
//***************************************************************** FUNCTION **
function fCheckNombre(piInputField, piDecimales, piMin, piMax, piAlertString)
{
  var alertString=''; // Optional warning string
	var conforme = true;

  if (piAlertString)
    alertString = piAlertString;

	if (piInputField.value.length)
	{
		var fv = parseFloat(piInputField.value, 10);
		if (isNaN(fv))
		{
			alert('Vous devez entrer une nombre dans ce champ et utiliser le \'.\' pour les nombres à virgule: "'+ piInputField.value + '".' + alertString);
			fv = '';
			piInputField.value = fv;
			conforme = false;
		}
		else
		{
			if (piInputField.value != fv)
			{
				alert('Vous devez utiliser le \'.\' pour les nombres à virgule: "'+ piInputField.value + '".' + alertString);
				piInputField.value = fv;
				conforme = false;
			}

			if (piMin != '')
			{
				if (fv < piMin)
				{
					alert('La valeur minimum est '+piMin);
					fv = piMin;
					conforme = false;
				}
			}

			if (piMax != '')
			{
				if (fv > piMax)
				{
					alert('La valeur maximum est '+piMax);
					fv = piMax;
					conforme = false;
				}
			}
		}

		if (piDecimales != '' && fv != '')
		{
			fv = fFormatAtDecimal(fv, piDecimales);
		}

    if (piInputField.value != fv)
		{
			piInputField.value = fv;
		}
	}

	if (conforme)
	{
		return true;
	}
	else
	{
		piInputField.focus();
		return false;
	}
}

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fInputTextWithOnChange                                             **
//* GOAL: print a FORM INPUT item, with onChange JS handler that checks type.**
//*       Optionnal piAlertString is alerted if check type fails             **
//*                                                                          **
//***************************************************************** FUNCTION **
function fInputTextWithOnChange(piType, piSize, piMaxLen, piName, piValue, piFunctionCall, piAlertString, piDisplayZeroValue, piNoScreenModif)
{
	var ret;
  if (piType == 'number' || piType == 'int' || piType == 'positiveNumber')
  {
    FloatValue = parseFloat(piValue);
    if (! piDisplayZeroValue && FloatValue == 0)
		{
	    piValue='';
		}
  }

	ret='<INPUT TYPE="TEXT" SIZE="' + piSize + '" MAXLENGTH="' + piMaxLen + '" NAME="' + piName + '" VALUE="' + fFilterStringQuot(piValue) + '" OnChange="';
  if (piNoScreenModif == undefined || !piNoScreenModif)
  {
    ret += 'top.setScreenModif(true);';
  }
  
  if (piAlertString && piAlertString != '')
	{
    ret+=' top.fCheckInputType(this, \'' + piType + '\', \'' + piAlertString + '\');';
	}
  else
	{
    ret+=' top.fCheckInputType(this, \'' + piType + '\');';
	}

  if (piFunctionCall && piFunctionCall != '')
	{
    ret+= ' ' + piFunctionCall + ';';
	}

	ret+='">';
  return ret;
}

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fInputPcsDate                                                      **
//* GOAL: return code for a FORM INPUT used to input PCS standard date       **
//*                                                                          **
//***************************************************************** FUNCTION **
function fInputPcsDate(piName, piValue, piFunctionCall, piAlertString, piNoScreenModif)
{
	var ret;
  var dateString = '';

  // convert piValue into ddmmmyyyy format if needed
  if (piValue && piValue != '')
  {
    dateString = piValue;
    if (!isDateDDMMMYYYY(dateString))
    {
      var d = fConvertStringToPcsDate(dateString);
      if (d)
      {
        dateString = fConvertDateToDDMMMYYYY(d);
      }
    }
  }
  
	ret='<INPUT TYPE="TEXT" SIZE="10" MAXLENGTH="10" NAME="' + piName + '" VALUE="' + dateString + '" OnChange="';
  if (piNoScreenModif == undefined || !piNoScreenModif)
  {
    ret += 'top.setScreenModif(true);';
  }
  
  if (piAlertString && piAlertString != '')
	{
    ret+=' top.fCheckInputType(this, \'pcsDate\', \'' + piAlertString + '\');';
	}
  else
	{
    ret+=' top.fCheckInputType(this, \'pcsDate\');';
	}

  if (piFunctionCall && piFunctionCall != '')
	{
    ret+= ' ' + piFunctionCall + ';';
	}

  ret+='" onFocus="top.getCalendarFor(this)">';

  return ret;

} // fInputPcsDate

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: _fGetRollbackInput                                                 **
//* GOAL: Private function to return piInputField's Rollback input           **
//*       Return undefined if none                                           **
//*                                                                          **
//***************************************************************** FUNCTION **
function _fGetRollbackInput(piInputField)
{
  var hidRollbackName = 'hid_'+ piInputField.name + '_rollback'; // format printed in cHtmlRollbackableInput.cpp
  var hidRollback = piInputField.form.elements[hidRollbackName];

  return hidRollback;

} // _fGetRollbackInput

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fCheckRollback                                                     **
//* GOAL: If linked input value if invalid, rollback to previous value       **
//*       If you use this, use fSetInputTextValue to change this field value **
//*                                                                          **
//***************************************************************** FUNCTION **
function fCheckRollback(piInputField, piType, piAlertString)
{
  var hidRollback = _fGetRollbackInput(piInputField);

  if (fCheckInputType(piInputField, piType, piAlertString))
  {
    if (hidRollback)
    {
      hidRollback.value = piInputField.value;
    }
    setScreenModif(true);
  }
  else
  {
    if (hidRollback)
    {
      piInputField.value = hidRollback.value;
    }
    else
    {
      setScreenModif(true);
    }
  }
} // fCheckRollback

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: fSetInputTextValue                                                 **
//* GOAL: Set piInputField's value and update its Rollback input             **
//*                                                                          **
//***************************************************************** FUNCTION **
function fSetInputTextValue(piInputField, value)
{
  piInputField.value = value;
  setScreenModif(true);

  var hidRollback = _fGetRollbackInput(piInputField);
  if (hidRollback)
  {
    hidRollback.value = piInputField.value;
  }

  // launch onChange code if any
  if (piInputField.onchange)
    piInputField.onchange();

} // fSetInputTextValue

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: isNumberKey                                                        **
//* GOAL: Renvoi true si la touche frappée est numérique                     **
//*                                                                          **
//***************************************************************** FUNCTION **
function isNumberKey(evt)
{
   var charCode = (evt.which) ? evt.which : event.keyCode
   if (charCode > 31 && (charCode < 48 || charCode > 57))
      return false;

   return true;

}

//* FUNCTION ******************************************************************
//*                                                                          **
//* NAME: isDecimalKey                                                        **
//* GOAL: Renvoi true si la touche frappée est numérique ou décimale                     **
//*                                                                          **
//***************************************************************** FUNCTION **
function isDecimalKey(evt)
{
   var charCode = (evt.which) ? evt.which : event.keyCode
   if (charCode > 31 && (charCode < 46 || charCode == 47 || charCode > 57))
      return false;

   return true;

}
