// ----------------------------------------------------------------------
// Javascript form validation routines.
// Author: Stephen Poley
//
// AT CUSTOM 20080602 - Impaginazione
//           20080712 - funzione validateDate e validateTime per le date e orari
//           20100215 - Icone
//
// Simple routines to quickly pick up obvious typos.
// All validation routines return true if executed by an older browser:
// in this case validation must be left to the server.
//
// Update Jun 2005: discovered that reason IE wasn't setting focus was
// due to an IE timing bug. Added 0.1 sec delay to fix.
//
// Update Oct 2005: minor tidy-up: unused parameter removed
//
// Update Jun 2006: minor improvements to variable names and layout
// ----------------------------------------------------------------------

var nbsp = 160;		// non-breaking space char
var node_text = 3;	// DOM text node-type
var emptyString = /^\s*$/ ;
var global_valfield;	// retain valfield for timer thread

var icon_error = '/img/IconError.png';
var icon_warning = '/img/IconWarning.png';
var icon_info = '/img/IconInfo.png';
var icon_help = '/img/IconHelp.png';

// --------------------------------------------
//                  trim
// Trim leading/trailing whitespace off string
// --------------------------------------------

function trim(str)
{
  return str.replace(/^\s+|\s+$/g, '');
}


// --------------------------------------------
//                  setfocus
// Delayed focus setting to get around IE bug
// --------------------------------------------

function setFocusDelayed()
{
  // aggiunto un controllo: i radio button arrivano come undefined e danno errore
  if (global_valfield.type!=undefined && global_valfield.type!='hidden') {global_valfield.focus();}
}

function setfocus(valfield)
{
  // save valfield in global variable so value retained when routine exits
  global_valfield = valfield;
  setTimeout( 'setFocusDelayed()', 100 );
}


// --------------------------------------------
//                  msg
// Display warn/error message in HTML element.
// commonCheck routine must have previously been called
// --------------------------------------------

function msg(fld,     // id of element to display message in
             msgtype, // class to give element ("warn" or "error")
             message) // string to display
{
  // setting an empty string can give problems if later set to a 
  // non-empty string, so ensure a space present. (For Mozilla and Opera one could 
  // simply use a space, but IE demands something more, like a non-breaking space.)
  var dispmessage;
//  if (msgtype=="error") 
//    {dispmessage = "<img src='"+icon_error+"' />";}    
//  else {if (msgtype=="warn") 
//    {dispmessage = "<img src='"+icon_warning+"' />";}
//  else
//    {dispmessage = "<img src='"+icon_warning+"' />";}
//  }
    
  if (emptyString.test(message)) 
    dispmessage = String.fromCharCode(nbsp);    
  else  
    dispmessage = message;

  var elem = document.getElementById(fld);
  elem.firstChild.nodeValue = " "+dispmessage;  
  //innerHTML = " "+dispmessage;  
  
  elem.className = msgtype;   // set the CSS class to adjust appearance of message
}

// --------------------------------------------
//            commonCheck
// Common code for all validation routines to:
// (a) check for older / less-equipped browsers
// (b) check if empty fields are required
// Returns true (validation passed), 
//         false (validation failed) or 
//         proceed (don't know yet)
// --------------------------------------------

var proceed = 2;  

function commonCheck(valfield,   // element to be validated
                     infofield,  // id of element to receive info/error msg
                     required)   // true if required
{
  if (!document.getElementById) 
    return true;  // not available on this browser - leave validation to the server
  var elem = document.getElementById(infofield);
  if (!elem.firstChild) return true;  // not available on this browser 
  if (elem.firstChild.nodeType != node_text) return true;  // infofield is wrong type of node  

  if (valfield.value==undefined || emptyString.test(valfield.value)) {
    if (required) {
      msg (infofield, "error", "Campo obbligatorio");  
      setfocus(valfield);
      return false;
    }
    else {
      msg (infofield, "warn", "");   // OK
      return true;  
    }
  }
  return proceed;
}

// --------------------------------------------
//            validatePresent
// Validate if something has been entered
// Returns true if so 
// --------------------------------------------

function validatePresent(valfield,   // element to be validated
                         infofield ) // id of element to receive info/error msg
{
  var stat = commonCheck (valfield, infofield, true);
  if (stat != proceed) return stat;

  msg (infofield, "warn", "");  
  return true;
}

// --------------------------------------------
//               validateEmail
// Validate if e-mail address
// Returns true if so (and also if could not be executed because of old browser)
// --------------------------------------------

function validateEmail(valfield,   // element to be validated
                       infofield,  // id of element to receive info/error msg
                       required)   // true if required
{
  var stat = commonCheck (valfield, infofield, required);
  if (stat != proceed) return stat;

  var tfld = trim(valfield.value);  // value of field with whitespace trimmed off
  var email = /^[^@]+@[^@.]+\.[^@]*\w\w$/  ;
  if (!email.test(tfld)) {
    msg (infofield, "error", "ERRORE: indirizzo e-mail non valido");
    setfocus(valfield);
    return false;
  }

  var email2 = /^[A-Za-z][\w.-]+@\w[\w.-]+\.[\w.-]*[A-Za-z][A-Za-z]$/  ;
  if (!email2.test(tfld)) 
    msg (infofield, "warn", "Indirizzo e-mail insolito, controllare se è corretto");
  else
    msg (infofield, "warn", "");
  return true;
}


// --------------------------------------------
//            validateTelnr
// Validate telephone number
// Returns true if so (and also if could not be executed because of old browser)
// Permits spaces, hyphens, brackets and leading +
// --------------------------------------------

function validateTelnr(valfield,   // element to be validated
                       infofield,  // id of element to receive info/error msg
                       required)   // true if required
{
  var stat = commonCheck (valfield, infofield, required);
  if (stat != proceed) return stat;

  var tfld = trim(valfield.value);  // value of field with whitespace trimmed off
  var telnr = /^\+?[0-9 ()-]+[0-9]$/  ;
  if (!telnr.test(tfld)) {
    msg (infofield, "error", "ERRORE: nel campo sono presenti caratteri errati (ammessi solo cifre, spazi, parentesi, trattini)");
    setfocus(valfield);
    return false;
  }

  var numdigits = 0;
  for (var j=0; j<tfld.length; j++)
    if (tfld.charAt(j)>='0' && tfld.charAt(j)<='9') numdigits++;

  if (numdigits<6) {
    msg (infofield, "error", "ERRORE: " + numdigits + " cifre, campo troppo corto");
    setfocus(valfield);
    return false;
  }

  if (numdigits>14)
    msg (infofield, "warn", numdigits + " cifre - verificare se è corretto");
  else { 
    if (numdigits<10)
      msg (infofield, "warn", "Solo " + numdigits + " cifre - verificare se è corretto");
    else
      msg (infofield, "warn", "");
  }
  return true;
}

// --------------------------------------------
//             validateAge
// Validate person's age
// Returns true if OK 
// --------------------------------------------

function validateAge(valfield,   // element to be validated
                     infofield,  // id of element to receive info/error msg
                     required)   // true if required
{
  var stat = commonCheck (valfield, infofield, required);
  if (stat != proceed) return stat;

  var tfld = trim(valfield.value);
  var ageRE = /^[0-9]{1,3}$/
  if (!ageRE.test(tfld)) {
    msg (infofield, "error", "ERRORE: età non valida");
    setfocus(valfield);
    return false;
  }

  if (tfld>=200) {
    msg (infofield, "error", "ERRORE: età non valida");
    setfocus(valfield);
    return false;
  }

  if (tfld>110) msg (infofield, "warn", "Più vecchio di 110 anni: verificare se corretto");
  else {
    if (tfld<7) msg (infofield, "warn", "Troppo giovane?");
    else        msg (infofield, "warn", "");
  }
  return true;
}

function validateDate(valfield,   // element to be validated
                     infofield,  // id of element to receive info/error msg
                     required)   // true if required
{
var checkstr = "0123456789";
var DateField = valfield;
var Datevalue = "";
var DateTemp = "";
var seperator = "/";
var day;
var month;
var year;
var leap = 0;
var err = 0;
var i;

  var stat = commonCheck (valfield, infofield, required);
  if (stat != proceed) return stat;

   err = 0;
   DateValue = DateField.value;
   /* Delete all chars except 0..9 */
   for (i = 0; i < DateValue.length; i++) {
	  if (checkstr.indexOf(DateValue.substr(i,1)) >= 0) {
	     DateTemp = DateTemp + DateValue.substr(i,1);
	  }
   }
   DateValue = DateTemp;
   /* Always change date to 8 digits - string*/
   /* if year is entered as 2-digit / always assume 20xx */
   if (DateValue.length == 6) {
      DateValue = DateValue.substr(0,4) + '20' + DateValue.substr(4,2); }
   if (DateValue.length != 8) {
      err = 19;}
   /* year is wrong if year = 0000 */
   year = DateValue.substr(4,4);
   if (year == 0) {
      err = 20;
   }
   /* Validation of month*/
   month = DateValue.substr(2,2);
   if ((month < 1) || (month > 12)) {
      err = 21;
   }
   /* Validation of day*/
   day = DateValue.substr(0,2);
   if (day < 1) {
     err = 22;
   }
   /* Validation leap-year / february / day */
   if ((year % 4 == 0) || (year % 100 == 0) || (year % 400 == 0)) {
      leap = 1;
   }
   if ((month == 2) && (leap == 1) && (day > 29)) {
      err = 23;
   }
   if ((month == 2) && (leap != 1) && (day > 28)) {
      err = 24;
   }
   /* Validation of other months */
   if ((day > 31) && ((month == "01") || (month == "03") || (month == "05") || (month == "07") || (month == "08") || (month == "10") || (month == "12"))) {
      err = 25;
   }
   if ((day > 30) && ((month == "04") || (month == "06") || (month == "09") || (month == "11"))) {
      err = 26;
   }
   /* if 00 ist entered, no error, deleting the entry */
   if ((day == 0) && (month == 0) && (year == 00)) {
      err = 0; day = ""; month = ""; year = ""; seperator = "";
   }
   /* if no error, write the completed date to Input-Field (e.g. 13.12.2001) */
   if (err == 0) {
      DateField.value = day + seperator + month + seperator + year;
      msg (infofield, "warn", "")
      return true;
   }
   /* Error-message if err != 0 */
   else {
	    msg (infofield, "error", "ERRORE: data non valida");
	    setfocus(valfield);
	    return false;
		}
}

function validateTime(valfield,   // element to be validated
                     infofield,  // id of element to receive info/error msg
                     required)   // true if required
{
var checkstr = "0123456789";
var TimeField = valfield;
var TimeValue = "";
var TimeTemp = "";
var seperator = ":";
var hour;
var minute;
var second;
var ampm;
var err = 0;
var i;

  var stat = commonCheck (valfield, infofield, required);
  if (stat != proceed) return stat;

   err = 0;
   TimeValue = TimeField.value;
   
var timePat = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;

var matchArray = TimeValue.match(timePat);
if (matchArray == null) {
    msg (infofield, "error", "ERRORE: ora non valida (HH:MM [AM|PM])");
    setfocus(valfield);
    return false;
  }
hour = matchArray[1];
minute = matchArray[2];
second = matchArray[4];
ampm = matchArray[6];

if (second=="") { second = null; }
if (ampm=="") { ampm = null; }

if (hour < 0  || hour > 23) {
    msg (infofield, "error", "ERRORE: ora non valida (indicare 00-23)");
    setfocus(valfield);
    return false;
  }
if (minute<0 || minute > 59) {
    msg (infofield, "error", "ERRORE: minuti non validi (indicare 00-59)");
    setfocus(valfield);
    return false;
  }
if (second != null && (second < 0 || second > 59)) {
    msg (infofield, "error", "ERRORE: secondi non validi (indicare 00-59)");
    setfocus(valfield);
    return false;
  }

if (ampm != null) {
	if (ampm=="pm" || ampm=="PM") {
		TimeField.value = (parseInt(hour)+12) + seperator + minute;
	}
	else {
		TimeField.value = hour + seperator + minute;
	} 
}
msg (infofield, "warn", "");
return true;
}


function validateRadio(valfield,   // element to be validated
                       infofield,  // id of element to receive info/error msg
                       required)   // true if required
{
  //var stat = commonCheck (valfield, infofield, required);
  //if (stat != proceed) return stat;

    var cnt = -1;
    for (var i=valfield.length-1; i > -1; i--) {
        if (valfield[i].checked) {cnt = i; i = -1;}
    }
    if (cnt > -1) 
    	{
		msg (infofield, "warn", "");
	    return true;
	    }
    else 
	    {
	    msg (infofield, "error", "Selezionare un'opzione");
	    setfocus(valfield);
	    return false;
	  }

}

// --------------------------------------------
//            validateTelnr
// Validate telephone number
// Returns true if so (and also if could not be executed because of old browser)
// Permits spaces, hyphens, brackets and leading +
// --------------------------------------------

function validateNumeric(valfield,   // element to be validated
                       infofield,  // id of element to receive info/error msg
                       required,minlen,maxlen,minval,maxval)   // true if required
{
  var stat = commonCheck (valfield, infofield, required);
  if (stat != proceed) return stat;

  var tfld = trim(valfield.value);  // value of field with whitespace trimmed off
  if (!isNumeric(tfld)) {
    msg (infofield, "error", "ERRORE: nel campo sono presenti caratteri errati (sono ammesse solo cifre)");
    setfocus(valfield);
    return false;
  }

  if ((minlen!=0 || maxlen!=0) && !isBetween(tfld.length,minlen,maxlen)) {
    msg (infofield, "error", "ERRORE: campo di lunghezza non consentita");
    setfocus(valfield);
    return false;
  }

  if ((minval!=0 || maxval!=0) && !isBetween(tfld,minval,maxval)) {
    msg (infofield, "error", "ERRORE: valore campo non consentito");
    setfocus(valfield);
    return false;
  }

	msg (infofield, "warn", "");
	return true;
}


function isEmpty(str){
  return (str == null) || (str.length == 0);
}
// returns true if the string is a valid email
function isEmail(str){
  if(isEmpty(str)) return false;
  var re = /^[^\s()<>@,;:\/]+@\w[\w\.-]+\.[a-z]{2,}$/i
  return re.test(str);
}
// returns true if the string only contains characters A-Z or a-z
function isAlpha(str){
  var re = /[^a-zA-Z]/g
  if (re.test(str)) return false;
  return true;
}
// returns true if the string only contains characters 0-9
function isNumeric(str){
  var re = /[\D]/g
  if (re.test(str)) return false;
  return true;
}
// returns true if the string only contains characters A-Z, a-z or 0-9
function isAlphaNumeric(str){
  var re = /[^a-zA-Z0-9]/g
  if (re.test(str)) return false;
  return true;
}
// returns true if the string's length equals "len"
function isLength(str, len){
  return str.length == len;
}
// returns true if the string's length is between "min" and "max"
function isLengthBetween(str, min, max){
  return (str.length >= min)&&(str.length <= max);
}
// returns true if the value is between "min" and "max"
function isBetween(val, min, max){
  return (val >= min)&&(val <= max);
}
// returns true if "str1" is the same as the "str2"
function isMatch(str1, str2){
  return str1 == str2;
}
// returns true if the string contains only whitespace
// cannot check a password type input for whitespace
function isWhitespace(str){ // NOT USED IN FORM VALIDATION
  var re = /[\S]/g
  if (re.test(str)) return false;
  return true;
}
// removes any whitespace from the string and returns the result
// the value of "replacement" will be used to replace the whitespace (optional)
function stripWhitespace(str, replacement){// NOT USED IN FORM VALIDATION
  if (replacement == null) replacement = '';
  var result = str;
  var re = /\s/g
  if(str.search(re) != -1){
    result = str.replace(re, replacement);
  }
  return result;
}

