/*
   global.js
   ----------------------------
   Funzioni di utilita' comuni.
*/


/* Imposta il messaggio della status bar */
function setStatusBar(msg) {
  window.status = msg;
  return true;
}


/* Resetta il messaggio della status bar */
function resetStatusBar() {
  window.status = "";
  return true;
}


/*
   Ritorna se il carattere (in codifica ASCII) passato come parametro
   e' tra quelli speciali (meta-caratteri).
*/
function isMetaKey(event) {
   return (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey);
}


/*
   Ritorna se il carattere (in codifica ASCII) passato come parametro
   e' una freccia direzionale.
*/
function isArrowKey(event) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isMetaKey(event) && code >= 37 && code <= 40)
     return true;

   return false;
}


/*
   Controllo semantico.
   Verifica che una stringa rappresenti un intero [-]?[0-9]+.
   Ritorna true se il valore e' numerico, false altrimenti.
*/
function isInteger(value,
                   zeroAdmitted) {
   if (value.search(/^[\-]?\d+$/) == -1)
      return false;

   if (!zeroAdmitted && Number(value) == 0)
      return false;

   return true;
}


/*
   Controllo semantico.
   Verifica che una stringa rappresenti un intero positivo [0-9]+.
   Ritorna true se il valore e' numerico, false altrimenti.
*/
function isPositiveInteger(value,
                           zeroAdmitted) {
   if (value.search(/^\d+$/) == -1)
      return false;

   if (!zeroAdmitted && Number(value) == 0)
      return false;

   return true;
}


/*
   Controllo semantico.
   Verifica che l'indirizzo e-mail specificato sia valido.
   Ritorna true se l'indirizzo e' valido, false altrimenti.
*/
function isValidEmailAddress(address) {
  var emailRE = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;

  if (trim(address).length == "")
    return false;

  if (!emailRE.test(address))
    return false;

  return true;
}


/*
   Listener per evento onKeyPress.
   Controllo sintattico, non semantico.
   Consente la sola immissione di lettere minuscole [a-z].
   In caso contrario, l'evento viene annullato.
*/
function requestLowercaseLetter(event) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isArrowKey(event) && code >= 32 &&
       (code < 65 || code > 90)) { /* a-z */
      cancelEvent(event);
   }

   return;
}


/*
   Listener per evento onKeyPress.
   Controllo sintattico, non semantico.
   Consente la sola immissione di lettere maiuscole [A-Z].
   In caso contrario, l'evento viene annullato.
*/
function requestUppercaseLetter(event) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isArrowKey(event) && code >= 32 &&
       (code < 97 || code > 122)) {
      cancelEvent(event);
   }

   return;
}


/*
   Listener per evento onKeyPress.
   Controllo sintattico, non semantico.
   Consente la sola immissione di lettere [a-zA-Z].
   In caso contrario, l'evento viene annullato.
*/
function requestLetter(event) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isArrowKey(event) && code >= 32 &&
       !((code >= 65 && code <= 90) || (code >= 97 && code <= 122))) {
      cancelEvent(event);
   }

   return;
}


/*
   Listener per evento onKeyPress.
   Controllo sintattico, non semantico.
   Consente la sola immissione di cifre intere positive [0-9].
   In caso contrario, l'evento viene annullato.
*/
function requestDigit(event) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isArrowKey(event) && code >= 32 &&
       (code < 48 || code > 57)) {
      cancelEvent(event);
   }

   return;
}


/*
   Listener per evento onKeyPress.
   Controllo sintattico, non semantico.
   Consente la sola immissione di cifre intere positive [0-9]
   o lettere [a-zA-Z] (eventualmente anche il simbolo di underscore).
   In caso contrario, l'evento viene annullato.
*/
function requestDigitOrLetter(event,
                              acceptUnderscore) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isArrowKey(event) && code >= 32 &&
       !((code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122)) &&
      (acceptUnderscore && code != 95)) {
      cancelEvent(event);
   }

   return;
}


/*
   Listener per evento onKeyPress.
   Controllo sintattico, non semantico.
   Consente la sola immissione di date [0-9][-./].
   In caso contrario, l'evento viene annullato.
*/
function requestDateChar(event) {
   if (!event)
      var event = window.event;

   if (event.keyCode)
      code = event.keyCode;
   else if (event.which)
      code = event.which;

   if (!isArrowKey(event) && code >= 32 &&
       (code < 45 || code > 57)) {
      cancelEvent(event);
   }

   return;
}


/*
  Formatta una data secondo il formato DD/MM/YYYY.
*/
function formatDateAsDDMMYYYY(date) {
   /* Se data non specificata si ritorna */
   if (date == null)
      return date;

   /* Suddivisione campi data */
   var fields = new Array();
   fields[0] = new String(date.getDate());
   fields[1] = new String(date.getMonth() + 1);
   fields[2] = new String(date.getFullYear());

   /* Normalizzazione giorno */
   if (fields[0].length == 1)
      fields[0] = "0" + fields[0];

   /* Normalizzazione mese */
   if (fields[1].length == 1)
      fields[1] = "0" + fields[1];

   /* Merge campi */
   return fields.join("/");
}


/*
   Confronto tra due date.
   Ritorna -1 se la prima data e' minore della seconda;
            0 se le due date sono uguali;
            1 se la prima data e' maggiore della seconda.
   Il parametro compareTime indica se considerare anche
   l'orario in fase di confronto.
*/
function compareDate(date1,
                     date2,
                     compareTime) {
   var dapp1, dapp2 = null;

   if (compareTime) {
     dapp1 = new Date(date1.getFullYear() ,date1.getMonth(), date1.getDate(), date1.getHours(), date1.getMinutes(), date1.getSeconds(), date1.getMilliseconds());
     dapp2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(), date2.getHours(), date2.getMinutes(), date2.getSeconds(), date2.getMilliseconds());
   } else {
     dapp1 = new Date(date1.getFullYear() ,date1.getMonth(), date1.getDate(), 0, 0, 0, 0);
     dapp2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(), 0, 0, 0, 0);
   }

   if (dapp1.getTime() < dapp2.getTime())
      return -1;

   if (dapp1.getTime() > dapp2.getTime())
      return 1;

   return 0;
}


/*
   Confronto tra due orari (in formato HH:MM).
   Ritorna -1 se il primo orario e' minore del secondo;
            0 se i due orari sono uguali;
            1 se il primo orario e' maggiore del secondo.
*/
function compareTime(time1,
                     time2) {
   var tapp1 = new Date(0, 0, 0, Number(time1.substr(0, 2)), Number(time1.substr(3, 2)), 0, 0);
   var tapp2 = new Date(0, 0, 0, Number(time2.substr(0, 2)), Number(time2.substr(3, 2)), 0, 0);

   if (tapp1.getTime() < tapp2.getTime())
      return -1;

   if (tapp1.getTime() > tapp2.getTime())
      return 1;

   return 0;
}


/*
   Ricerca in una SELECT l'eventuale OPTION con valore pari a VALUE.
   Restituisce l'indice della OPTION con valore pari a VALUE
   oppure -1 se questa non esiste.
*/
function searchSelectOptionByValue(select,
                                   value) {
   for (var i = 0; i < select.options.length; i++)
      if (select.options[i].value == value)
         return i;

   return -1;
}


/*
   Aggiunge la OPTION passata come parametro alla SELECT specificata.
   Si rende necessario ricorrere a questa funzione in quanto IE si
   comporta diversamente dagli altri browser, non riuscendo a gestire
   correttamente l'istruzione appendChild().
*/
function addOptionToSelect(select,
                           option) {
   try {
      select.add(option, null);
   } catch(ex) {
      select.add(option);
   }
}


/*
   Converte il valore di un campo in lettere maiuscole,
   rimuovendo eventuali blanks finali.
*/
function fieldToUpper(field) {
   field.value = trim(field.value.toUpperCase());
}


/*
   Converte il valore di un campo in lettere minuscole,
   rimuovendo eventuali blanks finali.
*/
function fieldToLower(field) {
   field.value = trim(field.value.toLowerCase());
}


/*
   Converte il valore di un campo in lettere minuscole
   ad eccezione dell'iniziale che viene resa maiuscola,
   rimuovendo eventuali blanks finali.
*/
function fieldToCapitalize(field) {
   if (field.value.length <= 1)
      field.value = trim(field.value.toUpperCase());
   else
      field.value = trim(field.value.substr(0, 1).toUpperCase() + field.value.substr(1).toLowerCase());
}


/*
   Elimina i blanks iniziali e finali da una stringa.
*/
function trim(text) {
   return text.replace(/^\s+|\s+$/, "");
}


/*
   Elimina i blanks iniziali da una stringa.
*/
function ltrim(text) {
   return text.replace(/^\s+/, "");
}


/*
   Elimina i blanks finali da una stringa.
*/
function rtrim(text) {
   return text.replace(/\s+$/, "");
}


/*
   Elimina eventuali blanks finali da una stringa,
   compresi eventuali caratteri &nbsp; (notazione ISO-8859-1).
*/
function trimHTML(text) {
   return text.replace(/[\x20,\xa0]+$/, "");
}


/*
   Ritorna la prima stringa se non nulla (o vuota),
   altrimenti la seconda (anche se nulla o vuota).
*/
function coalesce(firstString,
                  secondString) {
   if (firstString == null || firstString == undefined || firstString == "")
      return secondString;

   return firstString;
}


/*
   Appende a destra di una stringa il carattere specificato
   fino al raggiungimento della lunghezza desiderata
*/
function padStringRight(toPad,
                        pad,
                        length) {
   /*
      Se la stringa ha lunghezza >= della lunghezza desiderata
      la si ritorna semplicemente
   */
   if (toPad != null && toPad.length >= length)
      return toPad;

   var sBuf = (toPad == null ? "" : toPad);

   for (var i = sBuf.length + 1; i++ <= length; sBuf += pad);

   return sBuf;
}


/*
   Inserisce a sinistra di una stringa il carattere specificato
   fino al raggiungimento della lunghezza desiderata
*/
function padStringLeft(toPad,
                       pad,
                       length) {
   /*
      Se la stringa ha lunghezza >= della lunghezza desiderata
      la si ritorna semplicemente
   */
   if (toPad != null && toPad.length >= length)
      return toPad;

   var sBuf = (toPad == null ? "" : toPad);

   for (var i = sBuf.length + 1; i++ <= length; sBuf = pad + sBuf);

   return sBuf;
}


/*
   Converte la stringa in lettere maiuscole, rimuovendo
   eventuali blanks finali.
*/
function toUpper(text) {
   return trim(text.toUpperCase());
}


/*
   Converte la stringa in lettere minuscole, rimuovendo
   eventuali blanks finali.
*/
function toLower(text) {
   return trim(text.toLowerCase());
}


/*
   Converte la stringa in lettere minuscole ad eccezione
   dell'iniziale che viene resa maiuscola, rimuovendo
   eventuali blanks finali.
*/
function toCapitalize(text) {
   if (text.length <= 1)
      return trim(text.toUpperCase());
   else
      return trim(text.substr(0, 1).toUpperCase() + text.substr(1).toLowerCase());
}


/*
   Abbrevia una stringa che superi una lunghezza specificata.
   Ritorna la stringa abbreviata (...) o la stringa originale se
   tale da non eccedere la lunghezza specificata come parametro.
*/
function shortenString(text, maxLength) {
   if (text == null || maxLength == null)
      return text;

   if (text.length > maxLength)
      return text.substr(0, maxLength) + '\u2026';

   return text;
}


/*
   Converte eventuali ritorni a capo (\r, \n, \r\n) presenti nel testo
   nei corrispondenti tag html <br>.
*/
function decodeBR(textToDecode) {
  textToDecode = textToDecode.replace(/(\x0D\x0A)/g, "<br>");
  textToDecode = textToDecode.replace(/[\x0D\x0A]/g, "<br>");
  textToDecode = textToDecode.replace(/(\u2029\u2028)/g, "<br>");
  textToDecode = textToDecode.replace(/[\u2029\u2028]/g, "<br>");

  return textToDecode;
}


/*
  Converte eventuali tag html <br> presenti nel testo
  nel corrispondente \n.
*/
function encodeBR(textToEncode) {
  textToEncode = textToEncode.replace(/(<br>)/g, "\n");
  textToEncode = textToEncode.replace(/(<br\/>)/g, "\n");

  return textToEncode;
}


/* Cancellazione evento corrente */
function cancelEvent(event) {
  if (event.preventDefault)   // NS
     event.preventDefault();
  else                        // IE
     event.keyCode = 0;
}


/* Cancellazione propagazione evento corrente */
function cancelPropagation(event) {
  event.cancelBubble = true;
  event.returnValue = false;
}