/* Verifica.js
 *
 * Contiene funzioni di verifica sulla corretta formattazione
 * dei campi e di confronto tra valori.
 *
 * Ci sono funzioni per i seguenti tipi di dato:
 * - currency
 * - decimal
 * - date
 * - time
 * - month
 * - interi
 * - null
 * - email
 * - codiceFiscale
 * 
 * Per quasi tutti i tipi di dati esistono 4 funzioni. Chiamando xxx il tipo
 * di dato generico abbiamo:
 * - xxxOnBlur(valore)         richiamato sull'evento onBlur, verifica se il
 *                             valore passato è formattato correttamente e
 *                             in caso contrario apre un alert per segnalare
 *                             l'errore; per la verifica vera e propria usa
 *                             verificaXxx()
 * - verificaXxx(valore)       verifica se il valore passato è formattato 
 *                             correttamente e in caso contrario ritorna null;
 *                             se non si verifica un errore ritorna una stringa
 *                             normalizzata che rappresenta il valore
 * - confrontaXxxOnBlur(val1,val2,msg)    verifica se val1 > val2 e in tal caso 
 *                             visualizza il messaggio msg tramite un alert;
 *                             per il confronto vero e proprio usa confrontaXxx
 * - confrontaXxx(val1, val2)  confronta val1 con val2 e ritorna 1, 0 o -1 a
 *                             seconda del risultato
 * Per il tipo speciale "null" esistono solo le funzioni isNullOnBlur e isNull 
 * (controllo con e senza alert), mentre i tipi month, email e codiceFiscale 
 * non hanno le funzioni di confronto.
 * Si noti che verificaCodiceFiscale ritorna null se NON c'è errore (altrimenti
 * ritorna la stringa d'errore).
 */

/************/
/* CURRENCY */
/************/

// currencyOnBlur: verifica se il valore passato contiene un currency corretto
// e se non lo contiene visualizza un alert di errore
// (se non si desidera l'alert usare verificaCurrency)
function currencyOnBlur(obj) {
  var newVal;

  if (obj.value == "") return "";

  newVal = verificaCurrency(obj.value);
  if (newVal == null) {
    alert ("Importo non valido");
    obj.focus();
    return null;
  } else {
    obj.value = newVal;
    return newVal;
  }
}

// verificaCurrency: verifica se il valore passato contiene un currency corretto
// e in caso contrario ritorna null
function verificaCurrency(valore) {
  var newValore;

  re = /[EUR]/g
  valore = valore.replace (re, "");
 
  newValore = verificaDecimal(valore);
  if (newValore == null) {
    return null;
  } else {
    return newValore + " EUR";
  }
}

// confrontaCurrencyOnBlur:  visualizza un alert col messaggio se obj1 > obj2
// (per il confronto usa confrontaCurrency)
function confrontaCurrencyOnBlur(obj1, obj2, messaggio) {
  if ( (obj1.value != "") && (obj2.value != "") )
    if (confrontaCurrency(obj1.value, obj2.value) > 0) {
      alert (messaggio);
      return null;
    }
}

// confrontaCurrency: confronta i 2 argomenti e ritorna 1, 0 o -1
function confrontaCurrency(inCurrency1, inCurrency2) {
  var currency1;
  var currency2;

  re = /[EUR]/g
  inCurrency1 = inCurrency1.replace (re, "");
  inCurrency2 = inCurrency2.replace (re, "");

  return confrontaDecimal(inCurrency1, inCurrency2);
}

/***********/
/* DECIMAL */
/***********/

// decimalOnBlur: verifica se il valore passato contiene un numero decimale 
// corretto e se non lo contiene visualizza un alert di errore
// (se non si desidera l'alert usare verificaDecimal)
function decimalOnBlur(obj) {
  var newVal;

  if (obj.value == "") return "";
 
  newVal = verificaDecimal(obj.value);
  if (newVal == null) {
    alert ("Numero non valido");
    obj.focus();
    return null;
  } else {
    obj.value = newVal;
    return newVal;
  }
}

// verificaDecimal: verifica se il valore passato contiene un numero decimale 
// corretto e in caso contrario ritorna null
function verificaDecimal(valore) {
  var newValore;

  re = /[. ]/g
  valore = valore.replace (re, "");
  re = /[,]/g
  valore = valore.replace (re, ".");
 
  if (!isNaN(parseFloat(valore))) {
    valore = Math.round(parseFloat(valore) * 100) + "";
  
    newValore=""
    for (i=valore.length,j=0; i>0; i--, j++) {
      if (j==2) newValore = "," + newValore;
      else if (((j-2)%3) == 0) 
        newValore = (valore.substr(i-1,1) == "-" ? "" : ".") + newValore;
      newValore = valore.substr(i-1,1) + newValore
    }
  
    for (; newValore.length<4;) {
      if (newValore.length==2) newValore = "," + newValore 
      newValore = 0 + newValore
    }  
    return newValore;
  }
  else {
    return null;
  } 
}

// confrontaDecimalOnBlur: visualizza un alert col messaggio se obj1 > obj2
// (per il confronto usa confrontaDecimal)
function confrontaDecimalOnBlur(obj1, obj2, messaggio) {
  if ( (obj1.value != "") && (obj2.value != "") )
   if (confrontaDecimal(obj1.value, obj2.value) > 0) {
    alert (messaggio);
    return null;
   }
}

// confrontaDecimal: confronta i 2 argomenti e ritorna 1, 0 o -1
function confrontaDecimal(inDecimal1, inDecimal2) {
  var decimal1;
  var decimal2;

  re = /[. ]/g
  inDecimal1 = inDecimal1.replace (re, "");
  inDecimal2 = inDecimal2.replace (re, "");
 
  re = /[,]/g
  inDecimal1 = inDecimal1.replace (re, ".");
  inDecimal2 = inDecimal2.replace (re, ".");

  decimal1 = parseFloat(inDecimal1);
  decimal2 = parseFloat(inDecimal2);
 
  if (decimal1 > decimal2) return 1;
  else if (decimal1 == decimal2) return 0;
  else return -1;
}

/********/
/* DATE */
/********/

// dateOnBlur: verifica se il valore passato contiene una data corretta
// e in caso contrario visualizza un alert di errore
// (se non si desidera l'alert usare verificaData)
function dateOnBlur(obj) {
  var newVal;

  if (obj.value == "") return "";
 
  newVal = verificaDate(obj.value);
  if (newVal == null) {
    alert ("Data non valida");
    obj.focus();
    return null;
  } else {
    obj.value = newVal;
    return newVal;
  }
}

// verificaDate: verifica se il valore passato contiene una data corretta
// e in caso contrario ritorna null
function verificaDate(valore) {
  var g, m, a, d;
 
  re = /[ ]/g;
  valore = valore.replace (re, "");
 
  if (valore.length == 6) {
    g = valore.substr(0,2);
    m = valore.substr(2,2);
    a = (new Date().getFullYear() + " ").substr(0,2) + valore.substr(4,2);
  } else if (valore.length == 8) {
    g = valore.substr(0,2);
    m = valore.substr(2,2);
    a = valore.substr(4,4);
  } else if (valore.length == 10) {
    g = valore.substr(0,2);
    m = valore.substr(3,2);
    a = valore.substr(6,4);
  }
   
  d = new Date(a, m-1, g);
  if ((d.getFullYear() == a) && (d.getMonth() == (m-1)) && (d.getDate() == g)) {
    a = d.getFullYear();
    m = (d.getMonth() < 9) ? "0" + (d.getMonth() + 1) : (d.getMonth() + 1);
    g = (d.getDate() <= 9) ? "0" + d.getDate() : d.getDate();
    return g + "/" + m + "/" + a;
  } else {
    return null;
  }
}

// confrontaDateOnBlur: visualizza un alert col messaggio se obj1 > obj2
// (per il confronto usa confrontaDate)
function confrontaDateOnBlur(obj1, obj2, messaggio) {
  if ( (obj1.value != "") && (obj2.value != "") )
    if (confrontaDate(obj1.value, obj2.value) > 0) {
      alert (messaggio);
      return null;
    }
}

// confrontaDate: confronta i 2 argomenti e ritorna 1, 0 o -1
function confrontaDate(inData1, inData2) {
  var data1;
  var data2;
 
  data1 = new Date(inData1.substr(6, 4), inData1.substr(3, 2), inData1.substr(0, 2))
  data2 = new Date(inData2.substr(6, 4), inData2.substr(3, 2), inData2.substr(0, 2))
 
  if (data1 > data2) return 1;
  else if (data1 == data2) return 0;
  else return -1;
}

/********/
/* TIME */
/********/

// timeOnBlur: verifica se il valore passato contiene un'ora corretta
// e in caso contrario visualizza un alert di errore
function timeOnBlur(obj) {
  var ore;
  var minuti;
 
  if (obj.value == "") return "";

  switch (obj.value.length) {
  case 4:
    ore = obj.value.substr(0,2) * 1;
    minuti = obj.value.substr(2,2) * 1;
    break;
  
  case 5:
    ore = obj.value.substr(0,2) * 1;
    minuti = obj.value.substr(3,2) * 1;
  }

  if (isNaN(ore) || isNaN(minuti) || ore < 0 || ore > 23 || minuti < 0 || minuti > 59) {
    alert ("Ora non valida. Formato ammesso 'hh:mm'!");
    obj.focus();
  } else {
    obj.value = (ore < 10 ? "0" + ore : ore) + ":" + (minuti < 10 ? "0" + minuti : minuti)
  }
}

// verificaTime: non implementato

// confrontaTimeOnBlur e confrontaTime non implementati

/********/
/* MESI */
/********/

// monthOnBlur: verifica se il valore passato contiene un mese (mmyy o mm/yyyy)
// e in caso contrario visualizza un alert di errore
// (se non si desidera l'alert usare verificaMonth)
function monthOnBlur(obj) {
  var newVal;

  if (obj.value == "") return "";
 
  newVal = verificaMonth(obj.value);
  if (newVal == null) {
    alert ("Mese non valido");
    obj.focus();
    return null;
  } else {
    obj.value = newVal;
    return newVal;
  }
}

// verificaMonth: verifica se il valore passato contiene un mese (mmyy o mm/yyyy)
// e in caso contrario ritorna null
function verificaMonth(valore) {
  var g, m, a, d;
 
  re = /[ ]/g;
  valore = valore.replace (re, "");
 
  if (valore.length == 4) {
    m = valore.substr(0,2);
    a = (new Date().getFullYear() + " ").substr(0,2) + valore.substr(2,2);
  } else if (valore.length == 7) {
    m = valore.substr(0,2);
    a = valore.substr(3,4);
  }
   
  d = new Date(a, m-1, 1);

  // Ritorna il mese normalizzato (mm/yyyy)
  if ((d.getFullYear() == a) && (d.getMonth() == (m-1)) && (d.getDate() == 1)) {
    a = d.getFullYear();
    m = (d.getMonth() < 9) ? "0" + (d.getMonth() + 1) : (d.getMonth() + 1);
   
    return m + "/" + a;
  } else {
    return null;
  }
}

// confrontaMonthOnBlur: visualizza un alert col messaggio se obj1 > obj2
// (per il confronto usa confrontaMonth)
function confrontaMonthOnBlur(obj1, obj2, messaggio) {
  if ( (obj1.value != "") && (obj2.value != "") )
    if (confrontaMonth(obj1.value, obj2.value) > 0) {
      alert (messaggio);
      return null;
    }
}

// confrontaMonth: confronta i 2 argomenti e ritorna 1, 0 o -1
function confrontaMonth(inMonth1, inMonth2) {
  var month1;
  var month2;
 
  month1 = new Date(inMonth1.substr(6, 4), inMonth1.substr(3, 2), "01")
  month2 = new Date(inMonth2.substr(6, 4), inMonth2.substr(3, 2), "01")
 
  if (month1 > month2) return 1;
  else if (month1 == month2) return 0;
  else return -1;
}

/**********/
/* INTERI */
/**********/

// integerOnBlur: verifica se il valore passato contiene un intero corretto
// e in caso contrario visualizza un alert di errore
// (se non si desidera l'alert usare verificaInteger)
function integerOnBlur(obj) {
 var newVal;

 if (obj.value == "") return "";
 
 newVal = verificaInteger(obj.value);
 if (newVal == null) {
  alert ("Numero non valido");
  obj.focus();
  return null;
 } else {
  obj.value = newVal;
  return newVal+1;
 }
}

// verificaInteger: verifica se il valore passato contiene un intero corretto
// e in caso contrario ritorna null
function verificaInteger (valore) {
 if (!isNaN(parseInt(valore))) {
  return parseInt(valore);
 }
 else {
  return null;
 } 
}

// confrontaIntegerOnBlur: visualizza un alert col messaggio se obj1 > obj2
// (per il confronto usa confrontaInteger)
function confrontaIntegerOnBlur(obj1, obj2, messaggio) {
  if ( (obj1.value != "") && (obj2.value != "") )
   if (confrontaInteger(obj1.value, obj2.value) > 0) {
    alert (messaggio);
    return null;
   }
}

// confrontaInteger: confronta i 2 argomenti e ritorna 1, 0 o -1
function confrontaInteger(inInteger1, inInteger2) {
 var integer1;
 var integer2;

 integer1 = parseInt(inInteger1);
 integer2 = parseInt(inInteger2);
 
 if (integer1 > integer2) return 1;
 else if (integer1 == integer2) return 0;
 else return -1;
}

/********/
/* NULL */
/********/

// isNull
function isNull(obj) {
  return obj.value == "";  
}

// onBlur isNull
function isNullOnBlur(obj, messaggio) {
 if (obj.value == "") {
  alert (messaggio == null ? "Campo obbligatorio" : messaggio);
  return null;
 } else {
  return obj.value;
 }
}

/*********/
/* EMAIL */
/*********/

// emailOnBlur: verifica se il valore passato contiene un'email corretta
// e in caso contrario visualizza un alert di errore
// P.S.: controlla solo se la stringa contiene il carattere @
// P.S. 2: se non si desidera l'alert usare verificaEmail
function emailOnBlur(obj) {
  if (obj.value == "") return;
  if (verificaEmail(obj)==null) {
    alert("Il campo E-mail deve contenere il carattere @");
    return;
  }
}

// verificaEmail: verifica se il valore passato contiene un'email corretta
// e in caso contrario ritorna null
// P.S.: controlla solo se la stringa contiene il carattere @
function verificaEmail(obj) {
  if (obj.value == "") return null;
  if (obj.value.indexOf("@") < 0)
     return null;
  else return obj.value;
}

/******************/
/* CODICE FISCALE */
/******************/

// codiceFiscaleOnBlur: verifica se il valore passato contiene un codice fiscale
// corretto e in caso contrario visualizza un alert di errore
// (se non si desidera l'alert usare verificaCodiceFiscale)
function codiceFiscaleOnBlur(obj) {
  if (obj.value == "") return "";
  var err = verificaCodiceFiscale(obj);
  if (err != "" && err != null) alert ("Codice fiscale errato:\n" + err);
  return err;
}

// verificaCodiceFiscale: verifica se il valore passato contiene un codice
// fiscale corretto; se tutto va bene ritorna null, altrimenti ritorna un
// messaggio d'errore (ritorna "" se obj="")
function verificaCodiceFiscale (obj) {
  var translate1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var translate2 = "9999999999AAAAAAAAAAAAAAAAAAAAAAAAAA";
  var mappa = "AAAAAA99A99A99XA"
  var err = "";
  var i = 0;

  if (obj.value == "") return "";

  obj.value = obj.value.toUpperCase();
  if (obj.value.length != mappa.length)
    err = "Il codice fiscale deve essere di 16 caratteri";
  else {
    for (i=0; i<mappa.length; i++) {
      if (mappa.charAt(i) == "X") continue;

      if ( (j = translate1.indexOf(obj.value.charAt(i))) == -1 ) {
        err = "Il carattere evidenziato non e' un carattere ammesso: " + obj.value.substr(0,i) + "  -->" + obj.value.charAt(i) + "<--  " + obj.value.substr(i+1) + "";
        break;
      }

      if ((mappa.charAt(i) == "A") && (translate2.charAt(j) != "A")) {
        err = "Il carattere evidenziato dovrebbe essere una lettera: " + obj.value.substr(0,i) + "  -->" + obj.value.charAt(i) + "<--  " + obj.value.substr(i+1) + "";
        break;
      }

      if ((mappa.charAt(i) == "9") && (translate2.charAt(j) != "9")) {
        err = "Il carattere evidenziato dovrebbe essere un numero: " + obj.value.substr(0,i) + "  -->" + obj.value.charAt(i) + "<--  " + obj.value.substr(i+1) + "";
        break;
      }
    }
  }

  if (err != "")
    return err;
  else return null;
}


