/****************************************************************************************
================================================================================
                               www.gruppotesi.com
================================================================================
$RCSfile: acropolis.js,v $
$Revision: 1.27 $
$Date: 2009/02/06 11:29:26 $
$Author: u0112 $
$Name:  $

Gestione javascript progetto acropolis

  > Routine di inizializzazione del menu in testa alle pagine
  > Routine javascript necessarie al buon funzionamento del sito
  
  

Rev:
  20090128 - edoardo.galvagno@gruppotesi.com
  correzione funzione ControllaDomande() per funzionamento in FF

  20090121 - edoardo.galvagno@gruppotesi.com
  spostamento funzione Nome_orig() dalle pagine che la utilizzano
  (Allegati.cfm, DatiEcm.cfm, upload_documenti.cfm)
  
  20081002 - edoardo.galvagno@gruppotesi.com
  aggiunto metodo testaCoda() agli Array
  
  20070926 - anna.servetti@gruppotesi.com
  variata CheckData per controllo separatore
  
  20070925 - edoardo.galvagno@gruppotesi.com
  aggiunta funzione String.toFirstLetterUpperCase()

  20070921 - edoardo.galvagno@gruppotesi.com
  corretta function alternanza righe tabella per preservare classi gia' presenti

  20070910 - anna.servetti@gruppotesi.com
  aggiunta function toCamelCase
  
  20070606 - anna.servetti@gruppotesi.com
  creazione function goToPage
  
  20070606 - anna.servetti@gruppotesi.com
  creazione function ShowSafeStr
  
  20061024 - edoardo.galvagno@gruppotesi.com
  aggiunti ad inizializzaPagina() gli elenchi degli atti di PSISS06
  
  20061010 - anna.servetti@gruppotesi.com
  variate function ControllaDomande e ControllaRisposte per implementazione 
  controllo univocità attributi
  
  20061005 - anna.servetti@gruppotesi.com
  variata classe per gestione alternanza colori su elenco questionari con dettaglio schede
  
  20060928 - anna.servetti@gruppotesi.com
  aggiunta classe SetVisibleObj
  
  20060223 - edoardo.galvagno@gruppotesi.com
  corretta visualizzazione pagina selezionata in menu
  
  20060209 - anna.servetti@gruppotesi.com
  creazione function initHiddenCheckBox
  
  20060208 - anna.servetti@gruppotesi.com
  variata function ControllaRisposte
  
  20060206 - anna.servetti@gruppotesi.com
  aggiunta function controlNumber e function per il controllo di domande/risposte
  
  20060110 - edoardo.galvagno@gruppotesi.com
  aggiunta tabella di elenco elencoquestionari per alternanza righe
  ed elimianta funzione alternaRigaTabellaTre sostituita dalla
  piu' generica alternaRigaTabellaSpecifico che permette di specificare
  in argomento il numero di righe di passo
  
  20050913 - edoardo.galvagno@gruppotesi.com
  aggiunta tabella di elenco gestione_domandequest per alternanza righe
  
  20050415 - edoardo.galvagno@gruppotesi.com
  aggiunta ad inizializzaPagina() la gestione della pagina di indice eventi
  
  20050318 - edoardo.galvagno@gruppotesi.com
  aggiunta funzione alternaRigaTabellaPassoAutomatico() per alternare i colori
  delle righe di una tabella di elenco a seconda del rowspan specificato
  nella prima cella di ogni riga (permette di avere gruppi comuni di righe non fisso)
  
  20050315 - edoardo.galvagno@gruppotesi.com
  aggiunta funzione alternaRigaTabellaTre() per alternare le righe della tabella ogni 3
  
  20050112 - anna.servetti@gruppotesi.com
  modificate impostazioni finestra 'status' aperta da function popupWindow
  
  20041217 - anna.servetti@gruppotesi.com
  aggiunta showNumber
  
  20041217 - edoardo.galvagno@gruppotesi.com
  cambiata modalità di aggancio delle funzioni all'onload del body della pagina
  
  20041216 - anna.servetti@gruppotesi.com
  aggiunta function IsEmail
  
  20041215 - anna.servetti@gruppotesi.com
  aggiunta function di controllo codice fiscale e trim
  
  20041201 - edoardo.galvagno@gruppotesi.com

 ****************************************************************************************/

/****************************************************************************************
                      SEZIONE PER CARICAMENTO DATI BROWSER
 ****************************************************************************************/
// ricava versione del browser
var isOp=(navigator.userAgent.toLowerCase().indexOf('opera') !=-1)?true:false;
var isOp5=(isOp && navigator.userAgent.toLowerCase().indexOf('5') !=-1)?true:false;
var nome=(navigator.appName=="Microsoft Internet Explorer")?true:false;
var wt=nome?(navigator.appVersion.split(';').toString().split(" ").toString().split(',')[4] ):null;
var isie5=((wt)>=5 && nome)?true:false;
var isie4=((wt <5 && wt >=4) && nome)?true:false;
var isNS4=(document.layers)?true:false;
var isNS6=document.getElementById && (navigator.appName=="Netscape")?true:false;
var isIE4=document.all?true:false;
var isIE5=document.getElementById && (navigator.appName=="Microsoft Internet Explorer")?true:false;
/****************************************************************************************/


/****************************************************************************************
                              SEZIONE PER MENU PAGINA
 ****************************************************************************************/
// Function: inizializzaMenu
// 
// Aggiunge gli eventi a IE per poter mostrare il secondo livello di menu.
// 
// Parameters:
// 
//     unMenu - Nome del menu da inizializzare.
// 
function inizializzaMenu(unMenu) {
  if (document.getElementById && document.createElement) {
    navRoot = document.getElementById(unMenu);
    
    for (var i = 0; i < navRoot.childNodes.length; i++) {
      node = navRoot.childNodes[i];
      if (node.nodeName == "LI") {
        // se sono in IE gli aggiungo il codice per cambiare le classi, non serve con moz/kon
        if (document.all) {
          node.onmouseover = function() { this.className += " over"; }
          node.onmouseout = function() { this.className = this.className.replace(" over", ""); }
        }
        
        sottoMenu = node.getElementsByTagName("ul");
        if (sottoMenu.length > 0) {
          sottoMenu[0].onmouseover = function () { this.parentNode.getElementsByTagName("a")[0].className += " selezionato"; }
          sottoMenu[0].onmouseout = function () { this.parentNode.getElementsByTagName("a")[0].className = this.parentNode.getElementsByTagName("a")[0].className.replace("selezionato", "").replace(" ", ""); }
        }
      }
    }
  }
}

// Function: evidenziaSezioneMenu
// 
// Aggiunge la classe "sezione" al link nel menu corrispondente alla pagina in cui sono.
// 
// Parameters:
// 
//     unMenu - Nome del menu da inizializzare.
// 
function evidenziaSezioneMenu(unMenu) {
  // 1. ottengo il nome della pagina
  var nomePagina = window.document.location;
  //var pagina = window.document.location.toString();
  // var nomePagina = window.document.location.toString().match(/(\w*).cfm/)[0];
//alert(nomePagina);
  // 2. cerco a quale degli elementi <a> nel menu è corrispondente
  iLink = document.getElementById(unMenu).getElementsByTagName("a");
  for (var i = 0; i < iLink.length; i++) { if (iLink[i].href == nomePagina) break; }

  // 3. dall'<a> trovato risalgo all'<a> padre
  // 4. e gli assegno la classe sezione per colorarlo diversamente con l'eccezione del 
  //link alla home page che rimane come definita
  if (i != iLink.length) {
    if (iLink[i].href.search(/index.cfm/i) == -1) {
      // le notizie sono al primo e non al secondo livello, devo evidenziare lui e non suo padre
      if (iLink[i].href.search(/notizie.cfm/i) == -1) {
        iLink[i].parentNode.parentNode.parentNode.getElementsByTagName("a")[0].className = "sezione";
      } else {
        iLink[i].className = "sezione";
      }
    }
  }
}

// Function: evidenziaSezioneMenuFunzioni
// 
// Aggiunge la classe "sezione" al link nel menu corrispondente alla pagina in cui sono.
// Per il menu delle funzioni è diversa
// 
// Parameters:
// 
//     unMenu - Nome del menu da inizializzare.
// 
function evidenziaSezioneMenuFunzioni(unMenu) {
  // 1. ottengo _solo_ il nome della pagina e gli prependo a_ per gli id
  var nomePagina = "a_" + window.document.location.toString().match(/(\w*).cfm/)[1];

  // 2. cerco a quale degli elementi <a> nel menu è corrispondente
  iLink = document.getElementById(unMenu).getElementsByTagName("a");
  for (var i = 0; i < iLink.length; i++) { if (iLink[i].id == nomePagina) break; }

  // 3. dall'<a> trovato risalgo all'<a> padre
  // 4. e gli assegno la classe sezione per colorarlo diversamente con l'eccezione del 
  //link alla home page che rimane come definita
  if (i != iLink.length) { iLink[i].className += " sezione"; }
}

// Function: disabilitaLinkMenu
// 
// Azzera tutti i link nella barra dei menu.
// 
// Parameters:
// 
//     unMenu - Nome del menu da inizializzare.
// 
function disabilitaLinkMenu(unMenu) {
  iLink = document.getElementById(unMenu).getElementsByTagName("a");
  for (var i = 0; i < iLink.length; i++) {
     // annullo i link
    iLink[i].href = "javascript:void 0;";
    // e li disabilito graficamente
    iLink[i].className += " disabilitato";
  }
}

/**
 * popupWindow()
 *
 * apertura url in nuova finestra
 *
 *
 * @parameter url     : (required) url da caricare
 * @parameter winName : (required) nome nuova finestra
 * @parameter type    : (optional) tipo di finestra
 *                      modal   : finestra ridimensionabile senza toolbar,menu,history,
 *                                directories,location
 *                      fixed   : modal + no scrollbar + no resizable
 * @parameter width   : (optional) larghezza nuova finestra
 * @parameter height  : (optional) altezza nuova finestra
 * @parameter top     : (optional) posizionamento verticale nuova finestra
 * @parameter left    : (optional) posizionamento orizzontale nuova finestra
 *
 *
 * @return : 
 *
 *
 * @Revision     : 20050112 - anna.servetti@gruppotesi.com
 *                 modificate impostazioni finestra 'status'
 *
 *                 20040716 - paolo.olocco.jr@gruppotesi.com
 *                 modifica finestra type modal con scrollbar
 *
 *                 20040301 - gualtiero.sappa@gruppotesi.com
 *                 calcolo coordinate per centrare  la finestra
 *
 * @author       : 20031024 - gualtiero.sappa@gruppotesi.com
 */

function popupWindow(url, winName, type, width, height, top, left) {
  var opzioniFinestra = "";
  var ah = window.screen.availHeight;
  var aw = window.screen.availWidth;
  
  //20040301 - gualtiero.sappa@gruppotesi.com
  //calcolo coordinate per centrare  la finestra
  if (!left) {var left = (aw/2) - (width/2);}
  if (!top) {var top = (ah/2) - (height/2);}
  
  //costruzione opzioni visualizzazione finestra
  if (width) {opzioniFinestra += ',width=' + width}
  if (height) {opzioniFinestra += ',height=' + height}
  if (top) {opzioniFinestra += ',top=' + top}
  if (left) {opzioniFinestra += ',left=' + left}
  if (!type) {type=''}
  
  //applicazione type finestra
  switch (type.toLowerCase()) {
    case "modal": 
      //20040716 - paolo.olocco.jr@gruppotesi.com
      opzioniFinestra += 'toolbar=no,location=no,directories=no,' +
                        'status=yes,menubar=no,resizable=yes,copyhistory=no,scrollbars=yes'
      break;
    case "fixed": 
      opzioniFinestra += 'toolbar=no,location=no,directories=no,' +
                        'status=no,menubar=no,resizable=no,copyhistory=no,scrollbars=no'
      break;
    case "status": 
      opzioniFinestra += 'toolbar=no,location=no,directories=no,' +
                        'status=yes,menubar=no,resizable=yes,copyhistory=no,scrollbars=yes'
      break;
  }
  
  //elimino virgola iniziale nelle opzioniFinestra
  if (opzioniFinestra.substr(0,1)==',') {
    opzioniFinestra = opzioniFinestra.substr(1);
  }
  
  //apertura nuova finestra
  window.open(url, winName, opzioniFinestra);
}

// Function: inizializzaPagina
// 
// Invocata al caricamento di ogni pagina per inizializzare i menu.
// 
function inizializzaPagina() {
  if (document.getElementById("menu")) {
    inizializzaMenu("menu");
    evidenziaSezioneMenu("menu");
  }

  if (document.getElementById("menu_funzioni")) {
    inizializzaMenu("funzioni");
    evidenziaSezioneMenuFunzioni("funzioni");
  }
  
  if (document.getElementById("Elenco")) {
    alternaRigaTabella("Elenco");
  }
  
  if (document.getElementById("ElencoAzioni")) {
    alternaRigaTabellaSpecifico("ElencoAzioni", 3);
  }

  if (document.getElementById("ElencoPercorsi")) {
    alternaRigaTabellaPassoAutomatico("ElencoPercorsi");
  }

  if (document.getElementById("ElencoMenu")) {
    alternaRigaTabellaPassoAutomatico("ElencoMenu");
  }
  
  if (document.getElementById("ElencoDomandeQuest")) {
    alternaRigaTabellaPassoAutomatico("ElencoDomandeQuest");
  }
  
  if (document.getElementById("ElencoQuestionari")) {
    //20061005 - anna.servetti@gruppotesi.com
    //alternaRigaTabellaSpecifico("ElencoQuestionari", 2);
    alternaRigaTabella("ElencoQuestionari");
  }

  /* 20061024 - edoardo.galvagno@gruppotesi.com */
  /* aggiunte tabelle per PSISS06, atti */
  if (document.getElementById("Elenco_1")) { alternaRigaTabella("Elenco_1"); }
  if (document.getElementById("Elenco_2")) { alternaRigaTabella("Elenco_2"); }
  if (document.getElementById("Elenco_3")) { alternaRigaTabella("Elenco_3"); }
  if (document.getElementById("Elenco_4")) { alternaRigaTabella("Elenco_4"); }
  if (document.getElementById("Elenco_5")) { alternaRigaTabella("Elenco_5"); }

  /* per le liste contenute nella pagina di indice degli eventi */
  if (document.getElementById("elenco_eventi_incorso")) { inizializzaMenu("elenco_eventi_incorso"); }
  if (document.getElementById("elenco_eventi_archiviati")) { inizializzaMenu("elenco_eventi_archiviati"); }
}

// Function: alternaRigaTabella
// 
// Alterna i colori nelle righe di una tabella.
// 
// Parameters:
// 
//     unaTabella - tabella cui alternare le righe.
// 
function alternaRigaTabella(unaTabella) {
  if (document.getElementById(unaTabella)) {
    var bodyTabella = document.getElementById(unaTabella).getElementsByTagName("tbody");
  
    var righe = bodyTabella[0].getElementsByTagName("tr");
    
    var pari = false;
    // nel loop mi fermo alla penultima riga, l'ultima non deve avere classe colorata
    for (var i = 0; i < (righe.length - 1); i++) {
      // alert(righe[i].firstChild.getAttribute('colSpan'));
      classeEsistente = righe[i].className + " ";
      righe[i].className = pari ? classeEsistente + "riga_pari" : classeEsistente + "riga_dispari";
      pari = !pari;
    }
  }
}

// Function: alternaRigaTabellaSpecifico
// 
// Alterna i colori nelle righe di una tabella, per quante righe specificate.
// 
// Parameters:
// 
//     unaTabella - tabella cui alternare le righe.
//    numRighe   - ogni quante righe alternare
// 
function alternaRigaTabellaSpecifico(unaTabella, numrighe) {
  if (document.getElementById(unaTabella)) {
    var bodyTabella = document.getElementById(unaTabella).getElementsByTagName("tbody");
  
    var righe = bodyTabella[0].getElementsByTagName("tr");
    
    var pari = false;
    
    var passo = numrighe;
    var p = 0;
    
    // nel loop mi fermo alla penultima riga, l'ultima non deve avere classe colorata
    for (var i = 0; i < (righe.length - 1); i++) {
      // alert(righe[i].firstChild.getAttribute('colSpan'));
      righe[i].className = pari ? "riga_pari" : "riga_dispari";
      p++;
      if (p == passo) {
        p = 0;
        pari = !pari;
      }
    }
  }
}

// Function: alternaRigaTabellaPassoAutomatico
// 
// Alterna i colori nelle righe di una tabella, a seconda del rowspan della prima cella.
// 
// Parameters:
// 
//     unaTabella - tabella cui alternare le righe.
// 
function alternaRigaTabellaPassoAutomatico(unaTabella) {
  if (document.getElementById(unaTabella)) {
    var bodyTabella = document.getElementById(unaTabella).getElementsByTagName("tbody");
  
    var righe = bodyTabella[0].getElementsByTagName("tr");
    
    var pari = false;
    
    // il passo è determinato dal rowspan definito sulla prima cella della tabella
    var passo = righe[0].getElementsByTagName("td")[0].rowSpan;
    var p = 0;
    
    // nel loop mi fermo alla penultima riga, l'ultima non deve avere classe colorata
    for (var i = 0; i < (righe.length - 1); i++) {
      if (p >= passo) {
        passo = righe[i].getElementsByTagName("td")[0].rowSpan;
        p = 0;
        pari = !pari;
      }
      righe[i].className = pari ? "riga_pari" : "riga_dispari";
      p++;
      /* alert(p + " --- " + passo); */
    }
  }
}

// aggancio l'inizializzazione dei menu al caricamento della pagina
window.onload = inizializzaPagina;
/****************************************************************************************/

/**
 * goToPage()
 *
 * javascript per richiamo pagina in href
 *
 *
 * @parameter page : (required) page name
 * @parameter param : (required) list param
 *
 *
 * @return : riferimento all'oggetto browser indipendente
 *
 *
 * @Revision     : 20070606 - anna.servetti@gruppotesi.com
 *
 * @author       : 20070606 - anna.servetti@gruppotesi.com
 */
function goToPage (page, param) {
  return page + "?" + param;
}



/****************************************************************************************
                        FUNCTION DI UTILIZZO NELL'APPLICAZIONE
 ****************************************************************************************/
/*===============================================================================
                                  OGGETTI INPUT
  ===============================================================================*/

/**
 * oggetto()
 *
 * restituisce l'oggetto cercandolo prima per nome poi per ID, browser indipendente
 *
 *
 * @parameter obj     : (required) oggetto o nome oggetto da puntare
 * @parameter target  : (required) target di ricerca dell'oggetto
 *                        _parent : documento padre
 *                        _self   : documento corrente
 *                        _top    : documento padre di una gerarchia
 *                        _opener : documento di apertura finestra corrente
 *                        default : documento nel frame denominato target
 *
 *
 * @return : riferimento all'oggetto browser indipendente
 *
 *
 * @Revision     : 20031111 - gualtiero.sappa@gruppotesi.com
 *
 *                 20031111 - gualtiero.sappa@gruppotesi.com
 *                   gestione ID oggetto in mancanza del name (Attenzione!!! Nonostante 
 *                   alcuni browser permettano l'inserimento di ID uguali per più oggetti 
 *                   della pagina le funzioni javascript utilizzate considerano sempre 
 *                   il PRIMO oggetto con l'ID specificato)
 * 
 *                 20031006 - paolo.olocco.jr@gruppotesi.com
 *                   gestione tipo parametro obj:
 *                   1) stringa ==>   utilizzo obj come nome oggetto
 *                   2) array    ==>  ricavo il nome oggetto dal nome del primo elemento 
 *                                   (per gestire anche array creati senza costructor 
 *                                    Array() ==> es: radio button)
 *                   3) oggetto ==>  utilizzo obj.name come nome oggetto (caso default)
 *
 * @author       : edoardo.galvagno@gruppotesi.com
 */

function oggetto(obj,target) {

  // gestione target oggetto
  var sTarget = "";
  if (target) {
    switch (target) {
      case "_parent": sTarget = "parent."; break;
      case "_self": break;
      case "_top": sTarget = "top."; break;
      case "_opener": sTarget = "window.opener."; break;
      case "": sTarget = ""; break;
      default: sTarget = target + "."; break;
    }
  }
  
  // 20031006 - paolo.olocco.jr@gruppotesi.com
  // ricerca nome oggetto
  if (typeof obj == "string") {objname = obj;}
  else {
    if (!obj.length) {
      //20031111 - gualtiero.sappa@gruppotesi.com
      if (obj.name) {objname = obj.name;}
      else {objname = obj.id;}
    }
    else {objname = obj[0].name;}
  }

  //puntamento oggetto (browser indipendente)
  // 20050111 - edoardo.galvagno@gruppotesi.com
  // NON VA BENE COSI' PERCHE' DA' WARNING LO STESSO LI ESEGUE COMUNQUE TUTTI E DUE
  // sObjNS6 = eval(sTarget+"document.getElementById(objname)");
  // sObjDef = eval(sTarget+"document.all(objname)");
  //alert(sObjDef.name);

  // 20050111 - edoardo.galvagno@gruppotesi.com
  return (isNS4 ? document.layers[obj] : isNS6 ? eval(sTarget+"document.getElementById(objname)") : eval(sTarget+"document.all(objname)"));
  // return (isNS4 ? document.layers[obj] : isNS6 ? sObjNS6 : sObjDef);
  //return (isNS4 ? document.layers[obj] : isNS6 ? document.getElementById(obj) : document.all(obj));
}

/*
==================================================================
function: AggiornaCampiDaWork()

ribalta il valore dei campi di work (modificabili) sui corrispondenti campi hidden.
I campi di work hanno nome uguale al campo hidden + suffisso 'Work'.

args : -


return: -


Rev : 
      20040526 - gualtiero.sappa@gruppotesi.com
      Creazione                              

==================================================================      
*/
function AggiornaCampiDaWork(objForm) {
  if (!objForm.length) {
    AggiornaCampoDaWork(objForm.elements.name);
  }
  else {
    for (var i=0; i<objForm.elements.length; i++) {
      AggiornaCampoDaWork(objForm.elements[i].name);
    } 
  }
}

//Routine di aggiornamento singolo campo hidden da campo di work
//Il campo di work viene utilizzato dal lato client, al momento del submit aggiorna i
//campi effettivi (letti via form dal lato server)
function AggiornaCampoDaWork(nomeCampo) {
  if (oggetto(nomeCampo+'Work') != null) {
    oggetto(nomeCampo).value=oggetto(nomeCampo+'Work').value;
  }
}

/**
 * AbilitaInput()
 *
 * abilita/disabilita input
 *
 *
 * @parameter obj         : (required) nome oggetto o variabile oggetto
 * @parameter flagEnabled : (optional) valore abilitazione input (true/false)
 *
 *
 * @return : -
 *
 *
 * @Revision     : 20031110 - gualtiero.sappa@gruppotesi.com
 *
 *
 * @author       : gualtiero.sappa@gruppotesi.com
 */
function AbilitaInput(obj,flagEnabled) {
  oggetto(obj).disabled=!flagEnabled;
}

/**
 * IsEnabled()
 *
 * controlla se l'oggetto è abilitato
 *
 *
 * @parameter obj         : (required) nome oggetto o variabile oggetto
 *
 *
 * @return : abilitazione oggetto (true/false)
 *
 *
 * @Revision     : 20031111 - gualtiero.sappa@gruppotesi.com
 *
 *
 * @author       : 
 */
function IsEnabled(obj) {
  return !oggetto(obj).disabled;
}

/**
 * IsVisible()
 *
 * controlla visibilità oggetto
 *
 *
 * @parameter obj         : (required) nome oggetto o variabile oggetto
 *
 *
 * @return : visibilità oggetto (true/false)
 *
 *
 * @Revision     : 20031111 - gualtiero.sappa@gruppotesi.com
 *
 *
 * @author       : 
 */
function IsVisible(obj) {
  return !(oggetto(obj).style.display=='none');
}

/**
 * SetVisibleObj()
 *
 * visualizza/nasconde input
 *
 *
 * @parameter obj         : (required) nome oggetto o variabile oggetto
 * @parameter flagVisible : (optional) valore visibilità input (true/false)
 *
 *
 * @return : -
 *
 *
 * @Revision     : 20060928 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : gualtiero.sappa@gruppotesi.com
 */
//Mostra/nasconde obj
function SetVisibleObj(obj,flagVisible) {
  if (!flagVisible) { oggetto(obj).style.display = 'none'; }
  else { oggetto(obj).style.display = ''; }
}

/*===============================================================================
                               OGGETTI CHECKBOX / RADIO
  ===============================================================================*/

//Funzione x controllo selezione check
function IsChecked(nome_check) {
  var ac = oggetto(nome_check);
  if (!ac.disabled) {
    return ac.checked;
  }
}

//Funzione x la selezione/deselezione di un gruppo di check
function SelezionaCheck(nome_check, valcheck, index) {
  // controlliamo ac:
  // se non è definito: non ci sono check
  // se è definito: controlliamo la length dell'array:
  // - se non è definita c'è un solo elemento e quindi ac non è array
  // - se è definita ce ne sono diversi
  // controlla che il check non sia disabilitato:
  // in quel caso non lo varia
  // se è definito index: indice del check da selezionare
  
  // ac è l'array che contiene i check
  var ac = oggetto(nome_check);
  if (ac) {
    if (ac.length) {
      if (SelezionaCheck.arguments[2] == null) {
        for (i = 0; i < ac.length; i++) {
          if (!ac[i].disabled) ac[i].checked = valcheck;
        }
      }
      else {
        if (!ac[index].disabled) ac[index].checked = valcheck;
      }
    } else {
      if (!ac.disabled) ac.checked = valcheck;
    }
  }
}

//Funzione che scambia il valore di un gruppo di check
function ScambiaValoreCheck(nome_check, index) {
  // controlliamo ac:
  // se non è definito: non ci sono check
  // se è definito: controlliamo la length dell'array:
  // - se non è definita c'è un solo elemento e quindi ac non è array
  // - se è definita ce ne sono diversi
  // controlla che il check non sia disabilitato:
  // in quel caso non lo varia
  // se è definito index: indice del check da selezionare
  
  // ac è l'array che contiene i check
  //var ac = eval("document.all." + nome_check);
  var ac = oggetto(nome_check);
  if (ac) {
    if (ac.length) {
      if (ScambiaValoreCheck.arguments[2] == null) {
        for (i = 0; i < ac.length; i++) {
          if (!ac[i].disabled) ac[i].checked = !ac[i].checked;
        }
      }
      else {
        if (!ac[index].disabled) ac[index].checked = !ac[index].checked;
      }
    } else {
      if (!ac.disabled) ac.checked = !ac.checked;
    }
  }
}

/**
 * initHiddenCheckBox
 *
 * all'onClick del checkBox, salva il valore del check in un campo hidden
 *
 *
 * @parameter campoHidden : nome del campo hidden (il nome del checkBox verrà ricavato 
 *                          accodando 'View')
 * @parameter valNonChk : valore da impostare nel campo hidden se il checkBox non è sel.
 *
 *
 * @return : 
 *
 *
 * @Revision     : 20060209 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : 20060209 - anna.servetti@gruppotesi.com
 */
function initHiddenCheckBox(campoHidden,valNonChk) {
  var checkBox = campoHidden + "View";
  
  if (oggetto(checkBox).checked) {
    oggetto(campoHidden).value=oggetto(checkBox).value;
  } 
  else {
    oggetto(campoHidden).value=valNonChk;
  }
}

/*===============================================================================
                                 OGGETTI SELECT (COMBO)
  ===============================================================================*/

// Funzione x la popolazione di una select
// 20030915 - paolo.olocco.jr@gruppotesi.com
// eliminato parametro defselected non necessario (il default seleted della combo
// corrisponde sempre al valore selezionato)
//function PopulateSelect(name,optblank,selez,ArrayValue,ArrayDesc,defselected,ArrayColor) {
function PopulateSelect(name,optblank,selez,ArrayValue,ArrayDesc,ArrayColor) {

  //--------------------------------------------------------------------------------
  //                       INIZIALIZZAZIONE DEFAULT PARAMETRI
  //--------------------------------------------------------------------------------

  iniz = 0;
  var numVoci = ArrayValue.length;
  // 20030915 - paolo.olocco.jr@gruppotesi.com
  // tolto inizializzazione parametro defselected
  //var defselez = "no";
  //gestione valore di default selected
  //if (PopulateSelect.arguments[5] != null) {
  //  defselez = defselected;
  //}
  
  //20040303 - gualtiero.sappa@gruppotesi.com
  //imposta default per parametri
  if (PopulateSelect.arguments[1] == null) {optblank=true;}
  if (optblank.toString().toLowerCase() == "yes") {optblank=true;}
  if (optblank.toString().toLowerCase() == "no") {optblank=false;}
  
  if (selez == null) {selez='';}
  if (ArrayValue == null) {ArrayValue=new Array();}
  if (ArrayDesc == null) {ArrayDesc=new Array();}

  // 20030805 - gualtiero.sappa@gruppotesi.com
  //gestione valore di default per array classi
  flgOptColor=false;
  // 20030915 - paolo.olocco.jr@gruppotesi.com
  // in seguito all'eliminazione del parametro defselected, questo parametro si trova
  // nella posizione 5 dell'array
  //if (PopulateSelect.arguments[6] != null) {flgOptColor="yes";}
  if (PopulateSelect.arguments[5] != null) {flgOptColor=true;}
  
  // 20030716 - gualtiero.sappa@gruppotesi.com
  // gestione array dei valori vuoto: in questo caso viene sempre inserita una voce vuota
  if (ArrayValue.length==0) {
    optblank=true;
  }
  
  //--------------------------------------------------------------------------------
  //                           GESTIONE OPTION BLANK 
  //--------------------------------------------------------------------------------
  
  //Test x aggiunta voce vuota
  if (optblank) {
    var opt = document.createElement("option");
    opt.value = "";
    //Visualizza descrizione vuota
    if (optblank) {
      opt.text  = "";
    }
    //Visualizza testo passato alla routine
    else {
      opt.text  = optblank;
    }
    oggetto(name).options.add(opt,0);
    iniz = iniz + 1;
  }
  
  //--------------------------------------------------------------------------------
  //                         GESTIONE PROPRIETA OPTION 
  //--------------------------------------------------------------------------------

  //ciclo di caricamento voci della combo
  for (i=0;i<numVoci;i++) {
    var opt = document.createElement("option");
    opt.value = ArrayValue[i];
    opt.text  = ArrayDesc[i];

    //-------------- INSERIMENTO OPTION ---------------
    oggetto(name).options.add(opt,i+iniz);
    
    //----------------- COLORE OPTION -----------------
    if (flgOptColor) {opt.style.color = ArrayColor[i];}
    
    // 20030915 - paolo.olocco.jr@gruppotesi.com
    // spostata gestione scelta del default selected: viene sempre inizializzato
    // con il valore selected
    //--------------- DEFAULT SELECTED ----------------
    //20030618 - gualtiero.sappa@gruppotesi.com
    //commentata selezione unica, inserita selezione multipla
    //if ((opt.value == selez) && (defselez == "yes"))
    //if (isArray(selez)) {
    //  if ((SearchArrayValue(selez,opt.value)) && (defselez == "yes")) {
    //    opt.defaultSelected = true;
    //  }
    //}
    //else {
    //  if ((opt.value == selez) && (defselez == "yes")) {
    //    opt.defaultSelected = true;
    //  }
    //}
    //alert(opt.value + '-->' + SearchArrayValue(selez,opt.value));
    
    //------------------- SELECTED --------------------
    //20030618 - gualtiero.sappa@gruppotesi.com
    //commentata selezione unica, inserita selezione multipla
    //if (opt.value == selez) { opt.selected = true;}
    //alert(isArray(selez));
    if (isArray(selez)) {

      if (SearchArrayValue(selez,opt.value)) {
        // 20030915 - paolo.olocco.jr@gruppotesi.com
        // default selected = valore selected
        opt.defaultSelected = true;
        opt.selected = true;
      }
    }
    else {
      if (opt.value == selez) {
        // 20030915 - paolo.olocco.jr@gruppotesi.com
        // default selected = valore selected
        opt.defaultSelected = true;
        opt.selected = true;
      }
    }
  }
  
  //alert(oggetto(name).selectedItem);
  //alert(showObjProperties(oggetto(name)));
  //
  //alert(oggetto(name).selectedIndex);
  //<!--- 20050131 - anna.servetti@gruppotesi.com --->
  //se non ho valore selezionato imposto il primo (per combo multiple con optBlank)
  if (oggetto(name).selectedIndex < 0) {
    //alert('aaa');
    oggetto(name).options[0].selected = true;
  }
  
  //alert(oggetto(name).selected);

  //--------------------------------------------------------------------------------
  //                           GESTIONE BROWSER 
  //--------------------------------------------------------------------------------
  //per risolvere problema visualizzazione combo :
  //su Explorer 5.0 se la combo ha un solo elemento visualizza un primo elemento blank
  //impostando il focus il problema non si presenta
  oggetto(name).selected = oggetto(name).selectedIndex;
  return;
}

// Funzione x la pulizia di una select
function ClearSelect(name,optblank) {
  //20041201 - anna.servetti@gruppotesi.com
  //imposta default per parametri
  if (ClearSelect.arguments[1] == null) {optblank=true;}
  if (optblank.toString().toLowerCase() == "yes") {optblank=true;}
  if (optblank.toString().toLowerCase() == "no") {optblank=false;}

  // 20050111 - edoardo.galvagno@gruppotesi.com
  // var numVoci = eval("document.all."+name+".options.length")
  var numVoci = document.getElementById(name).options.length;
  // 20041203 - edoardo.galvagno@gruppotesi.com
  // for (i=0;i<numVoci;i++) {
    //eval("document.all."+name+".options.remove(0)");
    // queesto era già meglio
    // document.getElementById(name).remove(0);
  // }
  document.getElementById(name).options.length = 0;
  //<!--- 20041201 - anna.servetti@gruppotesi.com --->
  if (optblank) {
    var opt = document.createElement("option");
    opt.value = "";
    //Visualizza descrizione vuota
    //if (optblank) {
      opt.text  = "";
    //}
    //Visualizza testo passato alla routine
    //else {
      //opt.text  = optblank;
    //}
    // 20070912 - edoardo.galvagno@gruppotesi.com
    // eval("document.all."+name+".options.add(opt,0)");
    document.getElementById(name).options.add(opt, 0);
  }
  return;
}

/*===============================================================================
                            Routine gestione array
  ===============================================================================*/

/**
 * SearchArrayValue()
 *
 * Funzione di ricerca valore in un Array
 *
 * @parameter array       : (required) array su cui effettuare la ricerca
 * @parameter value        : (required) elemento da ricercare nell'array
 * @parameter returnIndex : (optional) se indicato è richiesto l'indice del valore in ritorno
 * @parameter fieldSearch : (optional) se l'array passato è un array di object, questo 
 *                          parametro indica il nome del campo dell'oggetto in cui ricercare 
 *                          l'elemento
 *
 * @return : true/l'indice dell'elemento cercato, false/-1 se non trovato
 *
 * @revision :  20041029 - anna.servetti@gruppotesi.com
 *              aggiunta gestione parametro returnIndex
 *
 *              20040702 - luca.portanova@gruppotesi.com
 *              modifica per controllo tipo di input dell'array
 *
 *              20040315 - anna.servetti@gruppotesi.com
 *
 * @author : 
 */
function SearchArrayValue(array,value,returnIndex,fieldSearch) {
  
  var search_array = array;
  // controllo per verificare se bisogna trasformare l'array senza constructor
  if (array.constructor==null) {
    search_array = Array(1);
    if (array.length) {
      for (var i=0;i<array.length;i++) {
        search_array[i] = array[i].value;
      }
    } else {
      search_array[0] = array.value;
    }
  }
  
  //20041029 - anna.servetti@gruppotesi.com
  // se devo effettuare la ricerca su un campo particolare carico un nuovo array
  if (fieldSearch != null) {
    var arrayTmp = new Array(0);
    for (var i=0;i<search_array.length;i++) {
      arrayTmp[i] = eval('search_array['+i+'].'+fieldSearch);
    }
    //ricarico l'array nella struttura originaria su cui verrà effettuato il loop
    search_array = new Array(0);
    search_array = arrayTmp;
  }
  
  // effettuo la ricerca sull'array
  for (var i=0;i<search_array.length;i++) {
    if (search_array[i]==value) {
      //20041029 - anna.servetti@gruppotesi.com
      // controllo se è richiesto l'indice
      if (returnIndex) {
        return i;
      }
      return true;
    }
  }
  
  //20041029 - anna.servetti@gruppotesi.com
  // controllo se è richiesto l'indice
  if (returnIndex) {
    return -1;
  }
  return false;
}

// 20031006 - paolo.olocco.jr@gruppotesi.com
// modifica per gestione di array creati anche senza constructor Array() (es. radio button)
// Funzione che testa se l'oggetto obj è un array
function isArray(obj) {

  // OBJECT
  if (typeof obj=="object") {
      // array creati con Array()
      if (obj.constructor!=null) {
          if (obj.constructor.toString().indexOf("Array")==-1) { return false; }
          else { return true; }
      }
      // array senza constructor (es. radio button)
      else {
          if (obj.length==null) { return false; }
          else { return true; }
      }
  }
  // OTHERS
  else {
    return false;
  }

}

/**
 * printArray()
 *
 * PER DEBUG: fa l'output di un array
 *
 *
 * @parameter array                : (required) l'array da stampare
 * @parameter title                : eventuale titolo della finestra
 * @parameter start                : eventuale primo elemento da stampare
 * @parameter end                  : eventuale ultimo elemento da stampare
 *
 *
 * @return : -
 *
 *
 * @Revision     : 20040212 - gualtiero.sappa@gruppotesi.com
 *
 *
 * @author       : 20040212 - gualtiero.sappa@gruppotesi.com
 */
function printArray(array, title, start, end) {
  var stringa = "";
  if (!title) { title = "print array" }
  if (!start) { start = 0 }
  if (!end) { end = array.length }
  stringa = title + "\n\n";
  for (var i = start; i <= end; i++) {
    stringa = stringa + "pos=" + i + "->" + array[i] + "\n";
  }
  alert(stringa);
}
/****************************************************************************************/

/****************************************************************************************/
/**                           CONTROLLO CAMPI SPECIALI                                  */
/****************************************************************************************/
/** 
  * IsCodFisc()
  *
  * Check if a string is a valid Italian Fiscal Code (Codice Fiscale) 
  *  
  * @param codFisc    The Fiscal Code to be checked. 
  * @return Returns a boolean value.  
  *
  * @author anna.servetti@gruppotesi.com
  * @version 1, 20041213
  */
function IsCodFisc(codFisc) {  
  var re = /^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$/;
  Codice=trim(codFisc.toUpperCase());
  return re.test(Codice);
}

/**
 * Tests passed value to see if it is a valid e-mail address
 * 
 * @param str    The string to check. (Required)
 *
 * @return Returns a boolean. 
 *
 * @Revision     : 20041216 - anna.servetti@gruppotesi.com
 *
 * @author       : 20041216 - anna.servetti@gruppotesi.com
 */
function IsEmail(str) {
  //var re = /^['_a-z0-9-]+(\.['_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*\.(([a-z]{2,3})|(aero|coop|info|museum|name))$/;
  var re = /^([a-z0-9_\.\-])+@(([a-z0-9\-\.]{2,})+)+\.([a-z0-9]{2,})+$/;
  mail=trim(str.toLowerCase());
  return re.test(mail);
}
/****************************************************************************************/

/**
 * trim()
 *
 * Funzione di trim
 *
 *
 * @parameter inputString          : (required) stringa da trimmare
 * @parameter tipoTrim             : eventuale tipo di trim da effettuare
 *
 *
 * @return : string trimmata
 *
 *
 * @Revision     : 20041213 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : 20041213 - anna.servetti@gruppotesi.com
 */
function trim(inputString,tipoTrim) {

  if (trim.arguments[1]      ==  null  || 
     (tipoTrim.toUpperCase() != "LEFT" && 
      tipoTrim.toUpperCase() != "RIGHT")) {
    tipoTrim = "";
  }

  //se il parametro non è una stringa lo ritorna così com'è
  if (typeof inputString != "string") { return inputString; }
  
  var retValue = inputString;

  // LEFT TRIM
  if (tipoTrim.toUpperCase() == "LEFT" || tipoTrim.toUpperCase() == "") {
    var ch = retValue.substring(0, 1);
    while (ch == " ") { //cerca spazi ad inizio stringa
       retValue = retValue.substring(1, retValue.length);
       ch = retValue.substring(0, 1);
    }
  }
  
  // RIGHT TRIM
  if (tipoTrim.toUpperCase() == "RIGHT" || tipoTrim.toUpperCase() == "") {
    ch = retValue.substring(retValue.length-1, retValue.length);
    while (ch == " ") { //cerca spazi a fine stringa
       retValue = retValue.substring(0, retValue.length-1);
       ch = retValue.substring(retValue.length-1, retValue.length);
    }
  }

  return retValue; 

}

/**
 * showNumber()
 *
 * formatta il valore in input con il numero di decimali indicato
 *
 *
 * @parameter number       : (required) valore da formattare
 * @parameter decimalPos   : (required) numero cifre decimali
 * @parameter defaultValue : (optional) valore di default
 * @parameter allowZero    : (optional) flag permetti valore nullo (yes/no)
 *
 *
 * @return : valore formattato
 *
 *
 * @Revision     :  20040324 - anna.servetti@gruppotesi.com
 *
 *                  20031222 - gualtiero.sappa@gruppotesi.com
 *
 *                   20031111 - gualtiero.sappa@gruppotesi.com
 *                  gestione numeri negativi e aggiornamento documentazione
 *
 * @author       : paolo.olocco@gruppotesi.com
 */
function showNumber(number,decimalPos,defaultValue,allowZero) {
  var def = 0;                //valore di default
  var zero = "no";            //flag valore 0 consentito
  var firstChar = "";          //primo carattere del number
  var stringDecimal = "";      //number in formato string
  var stringInteger = "";      //number in formato string
  var stringNumber = "";      //number in formato string
  var sepThousand = "";        //separatore migliaia
  var tmpNumber = "";          //temporaneo per manipolazione number
  
  
  //inizializza valore di default (se non passato come argomento)
  if (defaultValue) { def = defaultValue.toString();}
  
  //inizializza flag gestione valore 0 (se non passato come argomento)
  if (allowZero) { zero = "yes";}
  
  //sostituzione "." con ","
  re = /,/gi;
  tmpNumber = number.toString().replace(re,".");
  
  //===============================================================================
  //    gestione valore NON numerico
  //===============================================================================
  if (isNaN(tmpNumber)) {
    if (zero == "yes") { 
      return (showNumber(def,decimalPos,def));
    }
    else {
      if (def != 0) {  return (showNumber(def,decimalPos));}
      else {return (showNumber(0,decimalPos));}
    }
  }
  //===============================================================================
  //    gestione valore numerico
  //===============================================================================
  else {

    if (decimalPos > 0){                //trattamento numero con cifre decimali
      //shift a sinistra del numero
      tmpNumber = Math.round(tmpNumber * Math.pow(10,decimalPos));
      //estrazione parte decimale (approssimata)
      decimalPart = "" + (tmpNumber % Math.pow(10,decimalPos) + Math.pow(10,decimalPos));
      //estrazione parte intera
      tmpNumber /= Math.pow(10,decimalPos);
      integerPart = Math.floor(tmpNumber);
      stringDecimal =  "." + decimalPart.substr(1,decimalPos);
    }
    else {                              //trattamento numero intero
      integerPart = Math.round(number);
    }

    //costruzione sottostringhe decimali e interi
    //stringDecimal =  "." + decimalPart.substr(1,decimalPos);
    stringInteger =  integerPart;
    
    //gestione separatore di migliaia
    tmpNumber = integerPart;
    tmpStringInteger = "";
    while (tmpNumber > 999){
      tmp = "" + ((tmpNumber % 1000) + 1000);
      tmp = tmp.substr(1,3);
      tmpStringInteger = sepThousand + tmp + tmpStringInteger;
      tmpNumber = Math.floor(tmpNumber/1000);
    }
    tmpStringInteger = tmpNumber + tmpStringInteger;
    stringInteger = tmpStringInteger;
    
    //costruzione stringa finale
    stringNumber = stringInteger + stringDecimal
    
    //restituzione numero formattato
    if (parseFloat(stringNumber) == 0 && zero == "yes") {
      return (showNumber(def,decimalPos,def));
      }
    else {
      return (stringNumber);
    }
  }
}

/**
 * controlNumber
 *
 * function di controllo inserimento valore numerico
 *
 *
 * @parameter campo : oggetto di cui andare a controllare il valore
 * @parameter lblError : frase da visualizzare a viedo in caso di errore
 *
 *
 * @return : 
 *
 *
 * @Revision     : 20060206 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : 20060206 - anna.servetti@gruppotesi.com
 */
function controlNumber(campo,lblError){
  var number = campo.value;
  if (number != '') {
    if (isNaN(number)) {
      alert(lblError);
      oggetto(campo).focus();
    }
  }
}

function addZeros(value, len) {
	var i;

	value = "" + value;

	if (value.length < len) {
		for (i=0; i<(len-value.length); i++)
			value = "0" + value;
	}

	return value;
}

/*****************************************************************************************
   Routine per la gestione dei caratteri NON ammessi in digitazione
 ****************************************************************************************/
function ShowSafeStr(string) {
   //--------------------------------------------------------------------------
   // Riceve una stringa e la restituisce ripulita dai caratteri NON compresi
   // nella RegExp
   //--------------------------------------------------------------------------
   //Espressione = new RegExp("[^ !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~A-Za-z0-9]","g");
   Espressione = new RegExp("[^ 0-9A-Za-z_-]","g");
   newstr=string.replace(Espressione,"");
   return (newstr);
}

// Funzione x il controllo della data tramite funzione CF (cfinput)
// 20031022 - paolo.olocco.jr@gruppotesi.com
function CheckData(obj, error, msgErr, optional, defaultvalue) {
  
  //di default non restituisce messaggi di errore
  if (CheckData.arguments[1] == null) { var error = false; }
  //imposta messaggio di errore di default
  if (CheckData.arguments[2] == null) { var msgErr = 'Data Errata.'; }
  //di default il campo è opzionale
  if (CheckData.arguments[3] == null) { var optional = true; }
  // 20031022 - paolo.olocco.jr@gruppotesi.com
  //ripristino blank come valore di default
  if (CheckData.arguments[4] == null) { var defaultvalue = ''; }
  
  // data non valida:
  // 1) formato non corretto
  // 2) richiesta, ma non indicata
  if ((_CF_checkeurodate(obj.value)==false) || (obj.value=='' && optional == false)) {
    if (error==true) {
      alert(msgErr);
      oggetto(obj.name).select();
      oggetto(obj.name).focus();
    }
    else {
      // 20031022 - paolo.olocco.jr@gruppotesi.com
      //oggetto(obj.name).value = '';
      oggetto(obj.name).value = defaultvalue;
    }
  }
  else {
    datamin = oggetto(obj.name).value;
    if (datamin!="") {
      pos1 = datamin.indexOf("/");
      pos2 = datamin.lastIndexOf("/");
      pos = 0;
      
      //20070926 - anna.servetti@gruppotesi.com
      //controllo esistenza separatori, errore se non trovati
      if ((pos1 < 0) || (pos2 < 0)) {
        alert(msgErr);
        oggetto(obj.name).select();
        oggetto(obj.name).focus();
      }
      else {    
        //formattazione giorno
        giorno = "00" + datamin.substring(pos,pos1);
        dd = giorno.substr(giorno.length-2);
        
        //formattazione mese
        mese = "00" + eval(datamin.substring(pos1+1,pos2));
        mm = mese.substr(mese.length-2);
        
        //formattazione anno
        //completa l'anno in base all'anno corrente
        var oggi = new Date();
        pos = datamin.length;
        anno = datamin.substring(pos2+1,pos);
        yyyy = oggi.getYear();
        yyyy = yyyy.toString();
        lenAnno = (anno.length);      //lunghezza anno inserito
        lenPrefisso = (4 - lenAnno); //numero di cifre da anteporre all'anno inserito
        yyyy = yyyy.substr(0,lenPrefisso)+anno;
        
        //costruzione data formattata
        data = dd+"/"+mm+"/"+yyyy;
        oggetto(obj.name).value = data;
      }
    }
  }
}

/**
 * showObjProperties()
 *
 * ritorna la lista delle proprietà di un dato oggetto
 * (è banale ma non ci ricordiamo mai className!)
 *
 *
 * @parameter obj                : (required) oggetto di cui leggere le proprietà
 *
 *
 * @return : stringa formattata pronta da stampare con tutte le prop/valori
 *
 *
 * @Revision     : 20040129 - edoardo.galvagno@gruppotesi.com
 *
 *
 * @author       : 20040129 - edoardo.galvagno@gruppotesi.com
 */
function showObjProperties(obj) {
  var o = oggetto(obj);
  var t = o.name + "\n\n";
  //var count = 1;
  for (name in eval(o)) {
    //if (count > 80) {
    t += name + " --- (";
    t += eval("o." + name) + ")\n";
    //}
    //count = count + 1;
  }
  return t;
}

/**
 * SetVisibleObj()
 *
 * visualizza/nasconde input
 *
 *
 * @parameter obj         : (required) nome oggetto o variabile oggetto
 * @parameter flagVisible : (optional) valore visibilità input (true/false)
 *
 *
 * @return : -
 *
 *
 * @Revision     : 20031110 - gualtiero.sappa@gruppotesi.com
 *
 *
 * @author       : gualtiero.sappa@gruppotesi.com
 */
//Mostra/nasconde obj
function SetVisibleObj(obj,flagVisible) {
  if (!flagVisible) { oggetto(obj).style.display = 'none'; }
  else { oggetto(obj).style.display = ''; }
}

/**
 * toCamelCase()
 *
 * implementa lettera maiuscola nella formattazione del testo
 *
 *
 * @parameter text : (required) testo da convertire
 * @parameter scope : (optional) target su cui effettuare l'implementazione
 *                    ONE (default) cambia solo la lettera della prima parola
 *                    ALL cambia tutte la prima lettera a tutte le parole
 *
 *
 * @return : la stringa formattata
 *
 *
 * @Revision     : 
 *
 *
 * @author       : 20070910 - anna.servetti@gruppotesi.com
 */
function toCamelCase(text,scope) {
  //var testo = trim(document.getElementById(campo).value);
  var start = 0;
  var end = 0;
  var lastindex = 0;
  var parola = '';
  var parolaFinale = '';
  var finale = '';
  // 20050628 - paolo.olocco.jr@gruppotesi.com
  var a_special_char = new Array(" ","'");
  text = text.toLowerCase();
  //20070910 - anna.servetti@gruppotesi.com
  var oneWord = true;
  if ((toCamelCase.arguments[1] != null) || (toCamelCase.arguments[1] == 'ALL')) {oneWord = false;}

  // effettuo l'operazione solo se il campo è stato riempito
  if (text != '') {
    for (idx=0;idx<a_special_char.length;idx++) {
      start = 0;
      finale = '';
      //end = text.indexOf(" ");
      end = text.indexOf(a_special_char[idx]);
      if ((end == -1) || (oneWord)) {
        // non ho spazi: imposto il case corretto sulla parola passata
        iniziale = text.substring(0,1);
        resto = text.substring(1,text.length);
        finale = iniziale.toUpperCase() + resto;
        if (oneWord) {break};
      }
      else {
        //effettuo un loop alla ricerca di tutti gli spazi
        while (end != -1) {
          //end = text.indexOf(" ",start);
          end = text.indexOf(a_special_char[idx],start);
          lastindex = end;
          if (end == -1) {
            lastindex = text.length;
          }
          //estrazione parola
          parola = text.substring(start,lastindex);
          //escludo gli spazi di troppo tra le parole
          if (parola != '') {
            //imposto il "case" corretto
            iniziale = trim(parola.substring(0,1));
            resto = trim(parola.substring(1,parola.length));
            parolaFinale = iniziale.toUpperCase() + resto;
            //salvo la parola col nuovo case
            if (end != -1) {
              finale = finale + trim(parolaFinale) + a_special_char[idx];
            } else {
              finale = finale + trim(parolaFinale);
            }
          }
          start = lastindex+1;
        }
      }
      text = finale;
    }
    //oggetto(campo).value = trim(finale);
    return trim(finale);
  }
  return text;
}

/**
 * String.toFirstLetterUpperCase()
 *
 * Estende l'oggetto String con funzione che mette in maiuscolo SOLO
 * la prima lettera della stringa stessa
 *
 * @parameter  : none
 *
 * @return : la stringa formattata
 *
 * @Revision     : 
 *
 * @author       : 20070925 - edoardo.galvagno@gruppotesi.com
 */
String.prototype.toFirstLetterUpperCase = function () {
  return this.substr(0, 1).toUpperCase() + this.substr(1);
}

/****************************************************************************************/
/**                           CONTROLLI PER QUESTIONARI                                 */
/****************************************************************************************/
/**
 * ControllaDomande
 *
 * effettua il controllo di obbligatorietà e di validità delle risposte date
 *
 * @parameter nDomande: numero di domande presenti nella pagina
 * @parameter ctrlObbl: richiesto controllo obbligatorietà domande
 * @parameter ctrlVal: richiesto controllo validità risposte
 * @parameter stringErrorGen: frase di errore generica, a cui accodare la domanda errata
 * @parameter stringErrorSpec: frase di errore specifica, da accodare alla domanda errata
 * @parameter stringErrorSomma: frase di errore per somma non raggiunta
 * @parameter stringErrorUnivoc: frase di errore per attributi non univoci
 *
 * @return : false se risulta errato il controllo su obbligatorietà o validità di una domanda
 *
 *
 * @Revision     : 20061010 - anna.servetti@gruppotesi.com
 *                 implementazione controllo univocità attributi, controllo 
 *                 obbligatorietà solo se richiesto
 *
 *
 * @author       : 20060206 - anna.servetti@gruppotesi.com
 */
function ControllaDomande (nDomande, ctrlObbl, ctrlVal, stringErrorGen, stringErrorSpec, stringErrorSomma, stringErrorUnivoc) {
  var ret_value = false;
  var idx = -1;
  var stringError = "";
  var specialChar = "&amp;S&amp;";
  var univocValue = false;
  var cod_err = 0;
  
  if (nDomande>0) {
    var domanda = "";
    var codDomanda = "";

    /*********************************************************
      LOOP DI CONTROLLO DOMANDE
    **********************************************************/
    if (nDomande>1) {
      // ELENCO DOMANDE: SCORRO E CONTROLLO UNA X UNA
      for (idx = 0; idx < nDomande; idx++) {
        // 20090128 - edoardo.galvagno@gruppotesi.com
        // correzione per errore in FF
        if (!oggetto('IdDomanda')) {
          domanda = oggetto('IdDomanda_' + (idx + 1)).value;
        } else {
          domanda = oggetto('IdDomanda')[idx].value;
        }
        codDomanda = oggetto("cod_d"+domanda).value;
        oggetto("domanda_" + codDomanda).className = "domanda";
        tipodomanda = oggetto("tipoDom_d"+domanda).value;
        sommaliberi = oggetto("sommaLib_d"+domanda).value;
        richUnivocita = (oggetto("univocAttr_d"+domanda).value.toUpperCase() == "Y") && ctrlVal;
        
        // 20061010 - anna.servetti@gruppotesi.com
        //ret_value = ControllaRisposte(domanda, tipodomanda, sommaliberi);
        cod_err = ControllaRisposte(domanda, tipodomanda, sommaliberi, richUnivocita);
        
        if ((ctrlObbl || ctrlVal) && (cod_err > 0)) {
          //ERRORE NELLA COMPILAZIONE: ESCO E AVVERTO l'UTENTE
          break;
        }
      }
    } 
    else {
      // UNA SOLA DOMANDA INSERITA: LA CONTROLLO DIRETTAMENTE
      // 20090128 - edoardo.galvagno@gruppotesi.com
      // correzione per errore in FF
      if (!oggetto('IdDomanda')) {
        domanda = oggetto('IdDomanda_1').value;
      } else {
        domanda = oggetto('IdDomanda').value;
      }
      codDomanda = oggetto("cod_d"+domanda).value;
      tipodomanda = oggetto("tipoDom_d"+domanda).value;
      sommaliberi = oggetto("sommaLib_d"+domanda).value;
      richUnivocita = (oggetto("univocAttr_d"+domanda).value.toUpperCase() == "Y") && ctrlVal;
      cod_err = ControllaRisposte(domanda, tipodomanda, sommaliberi, richUnivocita);
    }
    
    //20061010 - anna.servetti@gruppotesi.com
    /*********************************************************
      CONTROLLI OBBLIGATORIETA' 
    **********************************************************/
    if (ctrlObbl) {
      if (cod_err == 1) {
        stringError = stringErrorSpec;
        if (idx < nDomande) {
          stringError = stringErrorGen + codDomanda + '\n';
          stringError = stringError + stringErrorSpec;
        }
      }
    }

    /*********************************************************
      CONTROLLI VALIDITA' 
    **********************************************************/
    if (ctrlVal) {
      // CONTROLLO SOMMA
      if (cod_err == 2) {
        //20061010 - anna.servetti@gruppotesi.com
        //sostituisco il carattere speciale con il codice della domanda
        //stringError = stringErrorSomma + codDomanda + " deve essere "+ sommaliberi;
        stringError = stringErrorSomma + sommaliberi;
        stringError = stringError.replace(specialChar,codDomanda);
      }
      
      // CONTROLLO UNIVOCITA'
      if (cod_err == 3) {
        stringError = stringErrorUnivoc.replace(specialChar,codDomanda);
      }
    }
    
    // AZZERO CODICE ERRORE SE:
    // - non controllo obbligatorietà anche se ho errore obbligatorietà (codice 1)
    // - non controllo validità ma ho errore somma non corretta (codice 2) o univocità non presente (codice 3)
    if ((!ctrlObbl && (cod_err == 1)) ||
        (!ctrlVal  && ((cod_err == 2) || (cod_err == 2)))) {
      cod_err = 0;
    }

    if (cod_err == 0) {
      ret_value = true;
    }
    else {
      alert(stringError);
      ret_value = false;
      oggetto("domanda_" + codDomanda).className = oggetto("domanda_" + codDomanda).className + " problema";
    }
    return ret_value;
  }
  return true;
}

/**
 * ControllaRisposte
 *
 * Controllo obbligatorietà risposte.
 * GESTIONE 3 CASI OBBLIGATORIETA' :
 *  1 - NESSUNA : procedo senza controllare
 *  2 - UNA : controllo che ci sia almeno 1 selezione + ATTRIBUTO VALORIZZATO (se esistente)
 *  3 - TUTTE : controllo che siano tutte selezionate + ATTRIBUTO VALORIZZATO (se esistente)
 *
 *
 * @parameter iddom: id domanda di cui effettuare il controllo di obbligatorietà
 * @parameter tipodom: tipo di domanda (a risposta multipla -checkbox- o singola -radiobutton-
 * @parameter somma: se valorizzata, la somma degli attributi liberi deve coincidere con 
 *                   quella passata
 * @parameter univoc: se true gli attributi devono essere univoci
 *
 *
 * @return : 0 -> nessun errore
 *           1 -> errore generato da controlli obbligatorietà
 *           2 -> errore somma richiesta non raggiunta
 *           3 -> errore univocità risposte non presente
 *
 *
 * @Revision     :  20061010 - anna.servetti@gruppotesi.com
 *                  implementazione codice errore di ritorno e controlli di univocità
 *                  attributi
 *                  
 *                  20060208 - anna.servetti@gruppotesi.com
 *                  correzione errore risposta facoltativa non data
 *
 * @author       : 20060206 - anna.servetti@gruppotesi.com
 */
function ControllaRisposte (iddom, tipodom, somma, univoc) {
  var isError = false;
  var codError = 0;
  var sommaSelected = 0;
  var rispData = false;
  var univoca = false;
  // caricamento nome variabili per codice domanda inserito
  var id_risp = 'risp_d'+iddom+'View';
  var obbl_dom = 'obbl_d'+iddom;
  var nomeCampoValAttr = 'attr_risp_d'+iddom+'_';
  var nomeCampoTipoAttr = 'tipoAttr_risp_d'+iddom+'_';
  var tipoObbl = oggetto(obbl_dom).value;
  //variabili per dati risposta
  var checked = true;
  var progrRisp = -1;
  var tipoAttr = "";
  var valAttr = "";
  var arrayAttr = new Array(1);
  
  // SE ESISTE PIU' DI UNA RISPOSTA DEVO EFFETTUARE I CONTROLLI SU UN ARRAY
  // 20090128 - edoardo.galvagno@gruppotesi.com
  // correzione per FF
  if (!oggetto(id_risp)) {
    var nRisposte = document.getElementsByName(id_risp).length;
  } else {
    var nRisposte = oggetto(id_risp).length;
  }
  
  /* if (oggetto(id_risp).length) { */
  if (nRisposte > 1) {
    univoca = true;
    /* var nRisposte = oggetto(id_risp).length; */
    
    /**************************************
      1) NESSUNA RISPOSTA OBBLIGATORIA
    ***************************************/
    // controllo solo l'eventuale inserimento dell'attributo per le voci selezionate
    if (tipoObbl == 'F') {
      for (var idx = 0; idx < nRisposte; idx++) {
        // caricamento dati risposta
        // 20090128 - edoardo.galvagno@gruppotesi.com
        // correzione per FF
        if (!oggetto(id_risp)) {
          checked = oggetto(id_risp + '_' + (idx + 1)).checked;
          progrRisp = oggetto(id_risp + '_' + (idx + 1)).value;
        } else  {
          checked = oggetto(id_risp)[idx].checked;
          progrRisp = oggetto(id_risp)[idx].value;
        }
        valAttr = oggetto(nomeCampoValAttr + progrRisp).value;
        tipoAttr = oggetto(nomeCampoTipoAttr + progrRisp).value;
        if (checked) {
          rispData = true;
          sommaSelected = parseFloat(sommaSelected) + parseFloat(valAttr);
        }
        isError = !controlDomandaNessunaObbl(checked,progrRisp,valAttr,tipoAttr);
        
        // RISPOSTA SELEZIONATA + ATTRIBUTO NON VALORIZZATO: ERRORE
        if (isError) {
          codError = 1;
        }
        else {
          if (valAttr != '') {
            if (SearchArrayValue(arrayAttr,valAttr)) {
              univoca = false;
            }
            else {
              arrayAttr.push(valAttr);
            }
          }
        }
      }
    }
    else {
      /**************************************
        2) UNA RISPOSTA OBBLIGATORIA
      ***************************************/
      // devo avere almeno una risposta data,se presente l'attributo deve essere valorizzato
      if (tipoObbl == 'U') {
        for (var idx = 0; idx < nRisposte; idx++) {
          // caricamento dati risposta
          // 20090128 - edoardo.galvagno@gruppotesi.com
          // correzione per FF
          if (!oggetto(id_risp)) {
            checked = oggetto(id_risp + '_' + (idx + 1)).checked;
            progrRisp = oggetto(id_risp + '_' + (idx + 1)).value;
          } else  {
            checked = oggetto(id_risp)[idx].checked;
            progrRisp = oggetto(id_risp)[idx].value;
          }
          valAttr = oggetto(nomeCampoValAttr + progrRisp).value;
          tipoAttr = oggetto(nomeCampoTipoAttr + progrRisp).value;
          if (checked) {
            rispData = true;
            sommaSelected = parseFloat(sommaSelected) + parseFloat(valAttr);
          }
          isError = !controlDomandaUnaObbl(checked,tipoAttr,valAttr);
          
          
          // RISPOSTA SELEZIONATA + ATTRIBUTO NON VALORIZZATO: ERRORE
          if (isError) {
            codError = 1;
          }
          else {
            if (valAttr != '') {
              if (SearchArrayValue(arrayAttr,valAttr)) {
                univoca = false;
              }
              else {
                arrayAttr.push(valAttr);
              }
            }
          }
        }
        
        // NESSUNA RISPOSTA SELEZIONATA: ERRORE
        if (!rispData) {
          isError = true;
          codError = 1;
        }
      }
      
      /**************************************
        3) TUTTE RISPOSTE OBBLIGATORIE
      ***************************************/
      // devo avere tutte le risposta selezionate,se presente l'attributo deve essere valorizzato
      else {
        for (var idx = 0; idx < nRisposte; idx++) {
          // caricamento dati risposta
          // 20090128 - edoardo.galvagno@gruppotesi.com
          // correzione per FF
          if (!oggetto(id_risp)) {
            checked = oggetto(id_risp + '_' + (idx + 1)).checked;
            progrRisp = oggetto(id_risp + '_' + (idx + 1)).value;
          } else  {
            checked = oggetto(id_risp)[idx].checked;
            progrRisp = oggetto(id_risp)[idx].value;
          }
          valAttr = oggetto(nomeCampoValAttr + progrRisp).value;
          tipoAttr = oggetto(nomeCampoTipoAttr + progrRisp).value;
          if (checked) {
            rispData = true;
            sommaSelected = parseFloat(sommaSelected) + parseFloat(valAttr);
          }
          isError = !controlDomandaTutteObbl(checked,tipoAttr,valAttr);
          
          // RISPOSTA NON SELEZIONATA: ERRORE
          if (isError) {
            codError = 1;
          }
          else {
            if (valAttr != '') {
              if (SearchArrayValue(arrayAttr,valAttr)) {
                univoca = false;
              }
              else {
                arrayAttr.push(valAttr);
              }
            }
          }
        }
      }
    }
  }
  else {
    // CONTROLLO DOMANDA CON RISPOSTA SINGOLA
    // caricamento dati risposta
    // 20090128 - edoardo.galvagno@gruppotesi.com
    // correzione per FF
    if (!oggetto(id_risp)) {
      checked = oggetto(id_risp + '_1').checked;
      progrRisp = oggetto(id_risp + '_1').value;
    } else  {
      checked = oggetto(id_risp).checked;
      progrRisp = oggetto(id_risp).value;
    }
    
    valAttr = oggetto(nomeCampoValAttr + progrRisp).value;
    tipoAttr = oggetto(nomeCampoTipoAttr + progrRisp).value;
    univoca = true; // RISPOSTA UNICA : UNIVOCITA' CERTA

    if (checked) {
      rispData = true;
      sommaSelected = parseFloat(sommaSelected) + parseFloat(valAttr);
    }

    /**************************************
      1) NESSUNA RISPOSTA OBBLIGATORIA
    ***************************************/
    // controllo solo l'eventuale inserimento dell'attributo per le voci selezionate
    if (tipoObbl == 'F') {
      isError = !controlDomandaNessunaObbl(checked,progrRisp,valAttr,tipoAttr);
    }
    else {
      /**************************************
        2) UNA RISPOSTA OBBLIGATORIA
      ***************************************/
      // devo avere almeno una risposta data, se presente l'attributo deve essere valorizzato
      if (tipoObbl == 'U') {
        // caricamento dati risposta
        isError = !controlDomandaUnaObbl(checked,tipoAttr,valAttr);
        // non ci sono errori, ma non è stato selezionato nulla: errore
        if (!isError) {
          isError = !checked;
        }
      }

      /**************************************
        3) TUTTE RISPOSTE OBBLIGATORIE
      ***************************************/
      // devo avere tutte le risposta selezionate,se presente l'attributo deve essere valorizzato
      else {
        isError = !controlDomandaTutteObbl(checked,tipoAttr,valAttr);
      }
    }
    if (isError) {
      codError = 1;
    }
  }
  
  /*********************************
    CONTROLLO SOMMA
  **********************************/
  if (!isError) {
    if (rispData && somma > 0) {
      if (somma != sommaSelected) {
        isError = true;
        codError = 2;
      }
    }
  }
  
  /*********************************
    CONTROLLO UNIVOCITA'
  **********************************/
  if (!isError) {
    if (univoc) {
      // CONTROLLO FLAG
      if (!univoca) {
        isError = true;
        codError = 3;
      }
    }
  }

  return codError;
}


/**
 * controlDomandaNessunaObbl
 *
 * controllo se è stato risposto correttamente ad una domanda con nessuna risposta 
 * obbligatoria (se è stato selezionata una risposta con attributo devo inserirlo, 
 * altrimenti posso procedere)
 *
 *
 * @parameter checked: stato della risposta: se true è stata selezionata
 * @parameter tipoAttr: tipo attributo assegnato alla risposta che sto controllando
 * @parameter valAttr: valore dell'attributo inserito
 *
 *
 * @return : false se la risposta è stata selezionata ma l'attributo (se richiesto) non
 *           è valorizzato
 *
 *
 * @Revision     : 20060206 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : 20060206 - anna.servetti@gruppotesi.com
 */
function controlDomandaNessunaObbl (checked, tipoAttr, valAttr) {
  var ret_value = true;
  //SE LA RISPOSTA NON E' STATA SELEZIONATA POSSO PROCEDERE
  if (checked) {
    //E' OBBLIGATORIO INSERIRE UN VALORE NELL'ATTRIBUTO SE ESISTENTE
    if (tipoAttr != 'N') {
      if (valAttr == '')  {
        ret_value = false;
      }
    }
  }
  return ret_value;
}

/**
 * controlDomandaUnaObbl
 *
 * controllo se è stato risposto correttamente ad una domanda con una sola/almeno una 
 * risposta obbligatoria (se non è stata selezionata solo una/almeno una risposta 
 * restituisce errore, se la domanda scelta ha l'attributo richiesto ma è vuoto
 * restituisce errore)
 *
 *
 * @parameter checked: stato della risposta: se true è stata selezionata
 * @parameter tipoAttr: tipo attributo assegnato alla risposta che sto controllando
 * @parameter valAttr: valore dell'attributo inserito
 *
 *
 * @return : false se la risposta è stata selezionata ma l'attributo (se richiesto) non
 *           è valorizzato
 *
 *
 * @Revision     : 20060206 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : 20060206 - anna.servetti@gruppotesi.com
 */
function controlDomandaUnaObbl (checked, tipoAttr, valAttr) {
  var ret_value = true;
  
  // EFFETTUO IL CONTROLLO SE LA RISPOSTA E' STATA SELEZIONATA
  if (checked) {
    // attributo NON RICHIESTO : PROCEDO
    if (tipoAttr == 'N') {
      ret_value = true;
    }
    // attributo RICHIESTO : CONTROLLO VALORE
    else {
      // valore NON INSERITO : ERRORE
      if (valAttr == '')  {
        ret_value = false;
      }
      // valore INSERITO : PROCEDO
      else {
        ret_value = true;
      }
    }
  }
  return ret_value;
}

/**
 * controlDomandaTutteObbl
 *
 * controllo se è stato risposto correttamente ad una domanda con tutte le risposte 
 * obbligatorie (tutte le domande devono essere selezionate, e se richiesto deve essere 
 * valorizzato l'attributo)
 *
 *
 * @parameter checked: stato della risposta: se true è stata selezionata
 * @parameter tipoAttr: tipo attributo assegnato alla risposta che sto controllando
 * @parameter valAttr: valore dell'attributo inserito
 *
 *
 * @return : false se la risposta non è stata selezionata oppure se è stata selezionata ma 
 *           l'attributo (se richiesto) non è valorizzato
 *
 *
 * @Revision     : 20060206 - anna.servetti@gruppotesi.com
 *
 *
 * @author       : 20060206 - anna.servetti@gruppotesi.com
 */
function controlDomandaTutteObbl (checked, tipoAttr, valAttr) {
  var ret_value = true;
  
  // CONTROLLO SE LA VOCE E' STATA SELEZIONATA
  if (checked) {
    // attributo NON RICHIESTO : PROCEDO
    if (tipoAttr == 'N') {
      ret_value = true;
    }
    // attributo RICHIESTO : CONTROLLO VALORE
    else {
      // valore NON INSERITO : ERRORE
      if (valAttr == '')  {
        ret_value = false;
      }
      // valore INSERITO : PROCEDO
      else {
        ret_value = true;
      }
    }
  }
  else {
    // voce non selezionata : ERRORE
    ret_value = false;
  }
  return ret_value;
}


/*****************************************************************************************
  Routine gestione stringa parametri
 ****************************************************************************************/
/*
<!---
==================================================================
function: updateParamValue()

data la stringa di parametri in formato : 
"List=WsParam1,WsParam2,WsParamN&c1=WsValue1&c2=WsValue2&c3=WsValueN"
oppure
"WsParam1,WsParam2,WsParamN&c1=WsValue1&c2=WsValue2&c3=WsValueN"
effettua la ricerca del nome del parametro sostituendo il corrispondente valore

args :
      listParam
      lista parametri iniziale
      
      arrayParamName
      array contenente nomi dei parametri di cui aggiornare il valore

      arrayParamValueNew
      array contenente i nuovi valori da sostituire nella stringa


return: la lista dei parametri nel formato di input con i valori aggiornati.
        Se uno o più parametri passati non sono presenti nella stringa, il valore 
        non viene aggiornato.
        N.B. Il prefisso "List=" viene restituito solamente se presente nella stringa
             in input

Rev :
      20061114 - paolo.olocco.jr@gruppotesi.com
      aggiunta escape() per il valore del parametro

      20060313 - paolo.olocco.jr@gruppotesi.com
      gestito caso con lista parametri iniziale vuota

      20060221 - emanuele.sogno@gruppotesi.com
      nel caso esista nome parametro lista su lista in input deve essere ripristinato
      sulla lista in output
  
      20050803 - anna.servetti@gruppotesi.com
      correzione errore sintassi
      
      20050407 - anna.servetti@gruppotesi.com
      Creazione

==================================================================
--->
*/
function updateParamValue(listParam,arrayParamName,arrayParamValueNew) {
  var stringaParam = listParam;
  
  /********************************************************************************
    FASE 1: SPACCHETTO LA LISTA CREANDO 2 ARRAY PARALLELI
  *********************************************************************************/
  //per prima cosa cerco la chiave "List=":se riportata devo escluderla
  var listKey = listParam.indexOf("List=");
  if (listKey >= 0) {
    stringaParam = listParam.substring(5,listParam.length);
  }
  //20060313 - paolo.olocco.jr@gruppotesi.com
  if (stringaParam.length==0) {
    return stringaParam;
  }
  
  //separo chiavi e valori
  var sep = stringaParam.indexOf("&");
  var paramKey = stringaParam.substring(0,sep);
  //20050803 - anna.servetti@gruppotesi.com
  var paramVal = stringaParam.substring(sep+1,stringaParam.length);

  //creo 2 array paralleli per chiavi e valori
  var arrayKey = new Array(1);
  var arrayVal = new Array(1);
  var idxStartKey = 0;
  var idxEndKey   = paramKey.indexOf(",");
  var idxStartVal = 0;
  var idxEndVal   = paramVal.indexOf("&");
  var idxArray   = 0;
  var chiave = "";
  var uguale = "";
  var valore = "";
  // loop alla ricerca della virgola usata come separatore
  while (idxEndKey > 0) {
    chiave = paramKey.substring(idxStartKey,idxEndKey);
    uguale = paramVal.indexOf("=",idxStartVal);
    valore = paramVal.substring(uguale+1,idxEndVal);

    //carico negli array i valori recuperati
    arrayKey[idxArray] = chiave;
    arrayVal[idxArray] = valore;
    
    //ricalcolo gli indici
    idxStartKey = idxEndKey+1;
    idxEndKey   = paramKey.indexOf(",",idxStartKey);
    idxStartVal = idxEndVal+1;
    idxEndVal   = paramVal.indexOf("&",idxStartVal);
    idxArray++;
  }
  // al termine mi rimane da salvare l'ultimo campo
  chiave = paramKey.substring(idxStartKey,paramKey.length);
  uguale = paramVal.indexOf("=",idxStartVal);
  valore = paramVal.substring(uguale+1,paramVal.length);
  arrayKey[idxArray] = chiave;
  arrayVal[idxArray] = valore;

  /********************************************************************************
    FASE 2: SOSTITUISCO I VALORI
  *********************************************************************************/
  var numChange = arrayParamName.length;
  var findKey = -1;
  for (var ind=0;ind<numChange;ind++) {
    //recupero l'indice in cui la chiave è salvata
    var findKey = SearchArrayValue(arrayKey,arrayParamName[ind],true);
    if (findKey != -1) {
      //20061114 - paolo.olocco.jr@gruppotesi.com
      arrayVal[findKey] = escape(arrayParamValueNew[ind]);
    }
  }

  /********************************************************************************
    FASE 3: RICONCATENO I DATI IN UNA LISTA FINALE
  *********************************************************************************/
  var numKey = arrayKey.length;
  var newListKey = arrayKey[0];
  var newListVal = "&c1=" + arrayVal[0];
  //scorrendo l'array delle chiavi riconcateno la situazione aggiornata in una nuova 
  //stringa di parametri
  for (ind=1;ind<numKey;ind++) {
    newListKey = newListKey + "," + arrayKey[ind];
    newListVal = newListVal + "&c" + (ind+1) + "=" + arrayVal[ind];
  }
  var listFinale = newListKey + newListVal;
  //20060221 - emanuele.sogno@gruppotesi.com
  //nel caso esista nome parametro lista su lista in input deve essere ripristinato
  //sulla lista in output
  if (listKey >= 0) {
    listFinale = "List=" + listFinale;
  }
  return listFinale;
}

/*
<!---
==================================================================
function: addParamValue()

data la stringa di parametri in formato : 
"List=WsParam1,WsParam2,WsParamN&c1=WsValue1&c2=WsValue2&c3=WsValueN"
oppure
"WsParam1,WsParam2,WsParamN&c1=WsValue1&c2=WsValue2&c3=WsValueN"
appende il nome del parametro e il valore corrispondente

args :
      listParam
      lista parametri iniziale
      
      arrayParamName
      array contenente nomi dei parametri da accodare

      arrayParamValueNew
      array contenente i valori da aggiungere nella stringa


return: 
      la lista dei parametri con i valori accodati nel formato standard.
      Se uno o più parametri passati sono già presenti nella stringa, il valore 
      non viene accodato
      N.B. Il prefisso "List=" viene restituito solamente se presente nella stringa
           in input

Rev :
      20061114 - paolo.olocco.jr@gruppotesi.com
      aggiunta escape() per il valore del parametro

      20060221 - emanuele.sogno@gruppotesi.com
      nel caso esista nome parametro lista su lista in input deve essere ripristinato
      sulla lista in output
      
      20051028 - anna.servetti@gruppotesi.com
      Creazione

==================================================================
--->
*/
function addParamValue(listParam,arrayParamName,arrayParamValue) {
  var stringaParam = listParam;
  
  /********************************************************************************
    FASE 1: SPACCHETTO LA LISTA CREANDO 2 ARRAY PARALLELI
  *********************************************************************************/
  var listKey = listParam.indexOf("List=");
  if (listKey >= 0) {
    stringaParam = listParam.substring(5,listParam.length);
  }
  
  //separo chiavi e valori
  var sep = stringaParam.indexOf("&");
  var paramKey = stringaParam.substring(0,sep);
  var paramVal = stringaParam.substring(sep+1,stringaParam.length);

  //creo 2 array paralleli per chiavi e valori
  var arrayKey = new Array(1);
  var arrayVal = new Array(1);
  var idxStartKey = 0;
  var idxEndKey   = paramKey.indexOf(",");
  var idxStartVal = 0;
  var idxEndVal   = paramVal.indexOf("&");
  var idxArray   = 0;
  var chiave = "";
  var uguale = "";
  var valore = "";
  // loop alla ricerca della virgola usata come separatore
  while (idxEndKey > 0) {
    chiave = paramKey.substring(idxStartKey,idxEndKey);
    uguale = paramVal.indexOf("=",idxStartVal);
    valore = paramVal.substring(uguale+1,idxEndVal);

    //carico negli array i valori recuperati
    arrayKey[idxArray] = chiave;
    arrayVal[idxArray] = valore;
    
    //ricalcolo gli indici
    idxStartKey = idxEndKey+1;
    idxEndKey   = paramKey.indexOf(",",idxStartKey);
    idxStartVal = idxEndVal+1;
    idxEndVal   = paramVal.indexOf("&",idxStartVal);
    idxArray++;
  }
  // al termine mi rimane da salvare l'ultimo campo
  //20060313 - paolo.olocco.jr@gruppotesi.com
  if (stringaParam.length > 0) {
    chiave = paramKey.substring(idxStartKey,paramKey.length);
    uguale = paramVal.indexOf("=",idxStartVal);
    valore = paramVal.substring(uguale+1,paramVal.length);
    arrayKey[idxArray] = chiave;
    arrayVal[idxArray] = valore;
    idxArray++;
  }

  /********************************************************************************
    FASE 2: ACCODO CHIAVE / VALORE
  *********************************************************************************/
  var numChange = arrayParamName.length;
  var findKey = -1;
  for (var ind=0;ind<numChange;ind++) {
    //controllo se la chiave è già presente
    var findKey = SearchArrayValue(arrayKey,arrayParamName[ind],true);
    if (findKey == -1) {
      // ACCODO LA CHIAVE
      //20060313 - paolo.olocco.jr@gruppotesi.com
      //arrayKey.push(arrayParamName[ind]);
      arrayKey[idxArray] = arrayParamName[ind];
      // ACCODO IL VALORE
      //20060313 - paolo.olocco.jr@gruppotesi.com
      //arrayVal.push(arrayParamValue[ind]);
      //20061114 - paolo.olocco.jr@gruppotesi.com
      arrayVal[idxArray] = escape(arrayParamValue[ind]);
      idxArray++;
    }
    else {
      //parametro già inserito: ne aggiorno il valore
      arrayVal[findKey] = escape(arrayParamValue[ind]);
    }
  }
  //printArray(arrayKey);
  //printArray(arrayVal);
  /********************************************************************************
    FASE 3: RICONCATENO I DATI IN UNA LISTA FINALE
  *********************************************************************************/
  var numKey = arrayKey.length;
  var newListKey = arrayKey[0];
  var newListVal = "&c1=" + arrayVal[0];
  //scorrendo l'array delle chiavi riconcateno la situazione aggiornata in una nuova 
  //stringa di parametri
  for (ind=1;ind<numKey;ind++) {
    newListKey = newListKey + "," + arrayKey[ind];
    newListVal = newListVal + "&c" + (ind+1) + "=" + arrayVal[ind];
  }
  var listFinale = newListKey + newListVal;
  //20060221 - emanuele.sogno@gruppotesi.com
  //nel caso esista nome parametro lista su lista in input deve essere ripristinato
  //sulla lista in output
  if (listKey >= 0) {
    listFinale = "List=" + listFinale;
  }
  return listFinale;
}

/*
<!---
==================================================================
function: searchParamValue()

data la stringa di parametri in formato : 
"List=WsParam1,WsParam2,WsParamN&c1=WsValue1&c2=WsValue2&c3=WsValueN"
oppure
"WsParam1,WsParam2,WsParamN&c1=WsValue1&c2=WsValue2&c3=WsValueN"
effettua la ricerca del nome del parametro restituendone il valore

args :
      listParam
      lista parametri iniziale
      
      ParamName
      nome del parametro di cui cercare il valore

return: valore del parametro

Rev :
  20070718 - edoardo.galvagno@gruppotesi.com
  Creazione partendo dalla updateParamValue()

==================================================================
--->
*/
function searchParamValue(listParam, ParamName) {
  var stringaParam = listParam;
  
  /********************************************************************************
    FASE 1: SPACCHETTO LA LISTA CREANDO 2 ARRAY PARALLELI
  *********************************************************************************/
  //per prima cosa cerco la chiave "List=":se riportata devo escluderla
  var listKey = listParam.indexOf("List=");
  if (listKey >= 0) {
    stringaParam = listParam.substring(5,listParam.length);
  }
  //20060313 - paolo.olocco.jr@gruppotesi.com
  if (stringaParam.length==0) {
    return stringaParam;
  }
  
  //separo chiavi e valori
  var sep = stringaParam.indexOf("&");
  var paramKey = stringaParam.substring(0,sep);
  //20050803 - anna.servetti@gruppotesi.com
  var paramVal = stringaParam.substring(sep+1,stringaParam.length);

  //creo 2 array paralleli per chiavi e valori
  var arrayKey = new Array(1);
  var arrayVal = new Array(1);
  var idxStartKey = 0;
  var idxEndKey   = paramKey.indexOf(",");
  var idxStartVal = 0;
  var idxEndVal   = paramVal.indexOf("&");
  var idxArray   = 0;
  var chiave = "";
  var uguale = "";
  var valore = "";

  // loop alla ricerca della virgola usata come separatore
  while (idxEndKey > 0) {
    chiave = paramKey.substring(idxStartKey,idxEndKey);
    uguale = paramVal.indexOf("=",idxStartVal);
    valore = paramVal.substring(uguale+1,idxEndVal);

    //carico negli array i valori recuperati
    arrayKey[idxArray] = chiave;
    arrayVal[idxArray] = valore;
    
    //ricalcolo gli indici
    idxStartKey = idxEndKey+1;
    idxEndKey   = paramKey.indexOf(",",idxStartKey);
    idxStartVal = idxEndVal+1;
    idxEndVal   = paramVal.indexOf("&",idxStartVal);
    idxArray++;
  }
  // al termine mi rimane da salvare l'ultimo campo
  chiave = paramKey.substring(idxStartKey,paramKey.length);
  uguale = paramVal.indexOf("=",idxStartVal);
  valore = paramVal.substring(uguale+1,paramVal.length);
  arrayKey[idxArray] = chiave;
  arrayVal[idxArray] = valore;

  /********************************************************************************
    FASE 2: CERCO IL VALORE
  *********************************************************************************/
  var findKey = -1;
  //recupero l'indice in cui la chiave è salvata
  var findKey = SearchArrayValue(arrayKey, ParamName, true);
  if (findKey != -1) {
    return arrayVal[findKey];
  }

  return "";
}

/*
<!---
==================================================================
function: testaCoda()

aggiungo un metodo agli Array per spostare un elemento dell'array
dalla prima all'ultima posizione

Rev :
  20081002 - edoardo.galvagno@gruppotesi.com
  Creazione
==================================================================
--->
*/

Array.prototype.testaCoda = function() {
  elem = this.shift();
  this.push(elem);
}

/*
<!---
==================================================================
function: Nome_orig()

per recuperare il nome del file senza il resto del percorso:
si aspetta nella pagina un input di tipo file e id FileUpload
e un input hidden con id FileName in cui mettere il nome ricavato

Rev :
  20090121 - edoardo.galvagno@gruppotesi.com
  Spostamento dalle pagine che la definivano e ne facevano uso
  e correzione per problema separatori da macchine unix/mac
==================================================================
--->
*/
function Nome_orig() {
  var nomeFile = oggetto('FileUpload').value;
  // giro i separatori da '/' a '\' per i file che vengono da unix/mac
  nomeFile = nomeFile.replace(/\//g, '\\');
  if (nomeFile.lastIndexOf("\\") > 0) {
    temp = nomeFile.substring(nomeFile.lastIndexOf("\\") + 1, nomeFile.length);
  } else {
    temp = nomeFile;
  }
  oggetto('FileName').value = temp;
}


Array.prototype.inArray = function(v) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == v) { return true; }
  }
  return false;
}

