/**
*  Raccoglie tutte le domande presenti nella pagina corrente.
*
*  @var array
*/
var domande = new Array();

/**
*  Raccoglie gli id delle opzioni delle domande di tipo associazione e classifica.
*  Mi serve per accedere a queste opzioni, visto che per queste uso delle convenzioni
*  di naming diverse.
*
*  @var array
*/
var opzione = new Array();

/**
*  Raccoglie i valori delle enumerazioni utilizzate.
*  Mi serve per accedere a queste enumerazioni, visto che per queste uso delle convenzioni
*  di naming diverse.
*
*  @var array
*/
var enumerazione = new Array();

/**
*  Questo flag mi dice se devo effettuare i controlli sul form dell'intervista.
*  Per esempio nel caso l'utente clicchi sul pulsante "indietro" questo controllo
*  non dovrà essere effettuato. Oppure sull' "avanti" della
*  pagina di presentazione del questionario.
*
*	@var boolean
*/
var check_actived=true;

/**
*  Raccoglie i messaggi relativi agli errori rilevati al momento del submit del form.
*
*  @var string
*/
var error_msg = new Array();

/**
*	Flag che indica se l'intervista viene conclusa in modo canonico mediante la pressione del pulsante relativo.
*
*	@var boolean
*/
var simula_concludi_intervista = true;

/**
*	Simula la pressione del pulsante "Concludi intervista".
*	E' usato alla fine del questionario sull'unload della pagina, per intercettare
*	quegli utenti che abbandonano il questionario una volta concluso ma non
*	hanno premuto "Concludi intervista".
*/
function SimulaConcludiIntervista()
{
	if (simula_concludi_intervista)
	{
		document.forms["intervista"].elements[_PULSANTE_END_ID].click();
		// Un'alternativa è usare la "confirm", ma sembra meno appropriata.
		alert(messaggi["completamento_automatico_intervista"]);
	}
}

function keyDown(e)
{
    var browserName=navigator.appName.charAt(0);
    var browserVer=parseInt(navigator.appVersion);
    if (browserName=="N" && browserVer >= 4) abilitato=3;
    if (browserName=="M" && browserVer >= 4) abilitato=4;
    // Riconoscimento tasti per Netscape
    if (abilitato==3)
    {
      var nKey=e.which;
    }
    // Riconoscimento tasti per Internet Explorer
    if (abilitato==4)
    {
      var ieKey=event.keyCode;
    }
    // Gestione della pressione del tasto invio
    if ((nKey==13)||(ieKey==13))
    {
      submitForm(this);
    }
}

/**
* Catturo l'evento di pressione di un tasto per aumentare l'accessibilità della pagina
* ponendo delle alternative al semplice utilizzo del mouse.
*
* PER ORA VIENE DISABILITATO PERCHE' CREA UN PO' DI PROBLEMI IN FASE DI COMPILAZIONE.
**/
//document.onkeydown = keyDown;
function submitForm(buttonObj, flagSubmit)
{
  if (check_actived &&
  	  flagSubmit == undefined  &&
      buttonObj.type == "submit")
  {
    customConditionsEvaluation(prepareForValidation, manageValidation);
    return;
  }

  if(checkForm())
  {
    //reset di Domande nascoste.
    checkHiddenDomande();

	window.document.forms["intervista"].elements["cmd"].name = buttonObj.name;

	if (buttonObj.name == _PULSANTE_END_ID) simula_concludi_intervista = false;
	if (buttonObj.name == _PULSANTE_PREV_ID) simula_concludi_intervista = false;

 	window.document.forms["intervista"].submit();
  }
}

function checkForm()
{
  if(!check_actived) return true;
  return checkDomande();
  return true;
}

function checkDomande()
{
  var flag=true;
  //error_msg = "";

  for(i=0; i<domande.length; i++)
  {
    domanda_id = domande[i][0];
    domanda_type = domande[i][1];
    domanda_text = domande[i][2];
    domanda_obj = getDomandaObj(domanda_id, domanda_type);

    if(document.getElementById("D_"+domanda_id).style.display=="block")
    {
      // controllo obbligatorietà
      if(document.forms["intervista"].elements["obbligatoria["+domanda_id+"]"]!=null &&
         document.forms["intervista"].elements["obbligatoria["+domanda_id+"]"].value==1)
        checkDomandaObbligatoria(domanda_obj, domanda_text, domanda_type);

      // controllo opzioni personalizzabili solo per tipi scelta singola e scelta multipla
      if(domanda_type == _DOMANDA_TIPO_SINGOLA ||
        domanda_type == _DOMANDA_TIPO_MULTIPLA ||
        domanda_type == _DOMANDA_TIPO_MATRICE)
        checkOpzionePersonalizzabile(domanda_obj, domanda_id, domanda_text);

      // controllo numero massimo di opzioni selezionabili
      if(domanda_type == _DOMANDA_TIPO_MULTIPLA)
        checkMaxSelezionabili(domanda_obj, domanda_id, domanda_text);
      if(domanda_type == _DOMANDA_TIPO_MATRICE)
        checkMaxSelezionabili(domanda_obj, domanda_id, domanda_text, true);

      // controllo tipi associazione che sia stato selezionato un valore
      // di enumerazione per tutte le opzioni o nessun valore
// PER ORA VIENE COMMENTATO PER NON AVERE QUESTA LIMITAZIONE...
//			if(domanda_type == _DOMANDA_TIPO_ASSOCIAZIONE)
//				checkAssociazione(domanda_obj, domanda_id, domanda_text);

      // controllo tipi classifica che non siano state selezionate due voci uguali
      if(domanda_type == _DOMANDA_TIPO_CLASSIFICA)
        checkClassifica(domanda_obj, domanda_id, domanda_text);

      if(domanda_type == _DOMANDA_TIPO_LIBERO)
        checkFormatoTestoLibero(domanda_obj, domanda_id, domanda_text);
    }
  }

  if(associativeArrayLength(error_msg) == 0) return true;

  openErrorWindow(error_msg);
  return false;
}

/**
*  Aggiunge all'array associativo e multidimensionale dei messagi di errore un nuovo messaggio.
*  Se c'è già un messaggio per la chiave specificata tramite il parametro key,
*  viene aggiunto all'elemento dell'array relativo a quella chiave.
*
*  @param int id_domanda
*  @param string messagge
*/
function addToErrorMsg(id_domanda, messagge, title)
{
  if (error_msg[id_domanda] != null)
  {
    error_msg[id_domanda].push([messagge, title]);
  }
  else
  {
    error_msg[id_domanda] = new Array([messagge, title]);
  }
}

function associativeArrayLength(ar)
{
  var length = 0;
  for (object in ar)
    length++;

  return length;
}

/**
*  In alternativa all'alert box, apre una finestra pop-up e ci scrive i messaggi d'errore.
*
*  @param array err_msg
*/
function openErrorWindow(err_msg)
{
	if (jQuery().dialog)
	{
		// Nuovo comportamento. I messaggi di errore vengono mostrati in una dialog box modale.
		// Viene prima creato il div che sarà la dialog box.
		$('#main_box').after('<div id="dialog_messaggi"></div>');

		var titoli = "";
		var messaggi_errore = "";
		for(id_domanda in err_msg)
		{
			var y=0;
			for(i=0; i<err_msg[id_domanda].length; i++)
			{
				if (err_msg[id_domanda][i][1] != null)
				{
					titoli += "&titoli["+id_domanda+"]["+y+"] = " + err_msg[id_domanda][i][1];
					y++;
				}

				messaggi_errore += "&messaggi["+id_domanda+"]["+i+"] = " + err_msg[id_domanda][i][0];
		   	}
		}

		var data = "questionario_id=" + window.document.forms["intervista"].elements["questionario_id"].value;
		data += "&questionario_lingua=" + window.document.forms["intervista"].elements["questionario_lingua"].value;
		data += titoli + messaggi_errore;

		$.ajax({
		  url: 'messaggi.php',
		  type: 'POST',
		  data: data,
		  success: function(data) {
		  	// L'html restituito da messaggi.php,
		  	// viene scritto nella finsetra di dialogo.
		    $('#dialog_messaggi').dialog({
				autoOpen: true,
				bgiframe: true,
				modal: true,
				width: $("#main_box").innerWidth()-40,
				height: 'auto',
				position: 'center',
				title: messaggi["errori"],
				buttons: {"Ok": function(){
									$(this).dialog("close");
									}
						 },
				open: function(event, ui){
								$(this).html(data);
						    },
				close: function(event, ui){
								error_msg = new Array();
						    }
			});
		  }
		});
	}
	else
	{
		// Vecchio comportamento.
		// Retrocompatibilità con template custom (che non sanno nulla del plugin jquery-ui) già
		// caricati in passato per alcuni clienti.

		var sData = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
		sData += '<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" /></head><body>';
		sData += "<form name='msgform' id='msgform' action='messaggi.php' method='post' enctype='multipart/form-data'>";
		sData += "<input type='hidden' name='questionario_id' value='" + window.document.forms["intervista"].elements["questionario_id"].value + "' />";
		sData += "<input type='hidden' name='questionario_lingua' value='" + window.document.forms["intervista"].elements["questionario_lingua"].value + "' />";
		sData += "<input type='hidden' name='popup_mode' value='1' />";
		for(id_domanda in err_msg)
		{
			for(i=0; i<err_msg[id_domanda].length; i++)
			{
				if (err_msg[id_domanda][i][1] != null)
					sData += "<input type='hidden' name='titoli[" + id_domanda + "][]' value='" + htmlspecialchars(err_msg[id_domanda][i][1], 'ENT_QUOTES') + "' />";

				sData += "<input type='hidden' name='messaggi[" + id_domanda + "][]' value='" + htmlspecialchars(err_msg[id_domanda][i][0], 'ENT_QUOTES') + "' />";
		   	}
		}

		sData += "</form>";
		sData += "<script type='text/javascript'>document.msgform.submit();</script>";
		sData += "</body></html>";
		openWindow=window.open('', 'messaggi', 'width=800, height=400, resizable=1, scrollbars=1');
		openWindow.document.write(sData);
		openWindow.document.close();
	}

	/*var sData = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
	sData += '<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" /></head><body>';
	sData += "<form name='msgform' id='msgform' action='messaggi.php' method='post' enctype='multipart/form-data'>";
	sData += "<input type='hidden' name='questionario_id' value='" + window.document.forms["intervista"].elements["questionario_id"].value + "' />";
	sData += "<input type='hidden' name='questionario_lingua' value='" + window.document.forms["intervista"].elements["questionario_lingua"].value + "' />";
	for(id_domanda in err_msg)
	{
		for(i=0; i<err_msg[id_domanda].length; i++)
		{
			if (err_msg[id_domanda][i][1] != null)
				sData += "<input type='hidden' name='titoli[" + id_domanda + "][]' value='" + htmlspecialchars(err_msg[id_domanda][i][1], 'ENT_QUOTES') + "' />";

			sData += "<input type='hidden' name='messaggi[" + id_domanda + "][]' value='" + htmlspecialchars(err_msg[id_domanda][i][0], 'ENT_QUOTES') + "' />";
	   	}
	}

	sData += "</form>";
	sData += "<script type='text/javascript'>document.msgform.submit();</script>";
	sData += "</body></html>";
	openWindow=window.open('', 'messaggi', 'width=800, height=400, resizable=1, scrollbars=1');
	openWindow.document.write(sData);
	openWindow.document.close();*/

	return false;
}

/**
*  Controlla che, per il tipo di domanda "scelta multipla", non siano stati selezionate più opzioni di
*  quelle determinate dall'amministratore del questionario.
*
*  @param array domanda_obj
*  @param int domanda_id
*  @param string domanda_text
*/
function checkMaxSelezionabili(domanda_obj, domanda_id, domanda_text, per_opzione)
{
  var max_selezionabili = document.forms["intervista"].elements["max_selezionabili["+domanda_id+"]"].value;
  if(max_selezionabili!="" && max_selezionabili!="0")
  {
    var checked;
    if (per_opzione != null)
      checked = new Array();
    else
      checked = 0;

    for(var i=0; i<domanda_obj.length; i++)
    {
      if (per_opzione != null)
      {
        var temp = domanda_obj[i].value.split('_');
        if (checked[temp[0]] == null) checked[temp[0]] = 0;

        var length = domanda_obj[i].length;
        if(length!=null)
        {
          for(var y=0; y<domanda_obj[i].length; y++)
          {
            if(is_selected(domanda_obj[i][y])) checked[temp[0]]++;
          }
        }
        else if(is_selected(domanda_obj[i])) checked[temp[0]]++;
      }
      else if(is_selected(domanda_obj[i])) checked++;
    }

    if (typeof(checked) == "object")
    {
      var flag = false;
      for(i in checked)
      {
        if (checked[i] > max_selezionabili)
        {
          flag = true;
          break;
        }
      }

      if (flag)
      {
        addToErrorMsg(domanda_id, parse(messaggi["errore_max_selezionabili_opzione"], ["num", max_selezionabili]));
        return false;
      }
    }
    else if(checked > max_selezionabili)
    {
      addToErrorMsg(domanda_id, parse(messaggi["errore_max_selezionabili"], ["num", max_selezionabili]));
      return false;
    }
  }

  return true;
}

/**
*  Controlla che per un campo di tipo "associazione" siano state selezionate tutte le opzioni o nessuna.
*
*  @param array domanda_obj
*  @param int domanda_id
*  @param string domanda_text
*/
function checkAssociazione(domanda_obj, domanda_id, domanda_text)
{
  var checked = 0;
  for(var i=0; i<domanda_obj.length; i++)
  {
    // Se la lunghezza dell'elemento HTML corrente è indefinita vuol dire che l'elemento ha una sola opzione
    // e quindi questo tipo di errore è impossibile.
    if (domanda_obj[i].length == null) return true;

    for(var y=0; y<domanda_obj[i].length; y++)
    {
      if(domanda_obj[i][y].checked) checked++;
    }
  }

  if(checked!=0 && checked!=domanda_obj.length)
  {
    addToErrorMsg(domanda_id, messaggi["errore_associazione"]);
    return false;
  }

  return true;
}

/**
*  Controlla che per un campo di tipo "classifica" non siano state selezionati valori uguali per opzioni diverse e
*  che, se è stata selezionata almeno una opzione, nel caso la domanda non sia obbligatoria, siano state selezionate anche le altre.
*
*  @param array domanda_obj
*  @param int domanda_id
*  @param string domanda_text
*/
function checkClassifica(domanda_obj, domanda_id, domanda_text)
{
  var selected = "";

  // Se la lunghezza dell'elemento HTML corrente è indefinita vuol dire che l'elemento ha una sola opzione
  // e quindi questo tipo di errore è impossibile.
  if (domanda_obj.length == null) return true;

  empty_option = 0;
  selected = new Array();
  for(var i=0; i<domanda_obj.length; i++)
  {
    for(var y=0; y<domanda_obj[i].length; y++)
    {
      if(domanda_obj[i][y].selected)
      {
        if(domanda_obj[i][y].value!="")
        {
          temp_array = domanda_obj[i][y].value.split("_");
          if (selected[temp_array[1]] != null)
          {
            addToErrorMsg(domanda_id, messaggi["errore_classifica"]);
            return false;
          }
          selected[temp_array[1]] = temp_array[1];
        }
        else empty_option++;
      }
    }
  }

  if (empty_option > 0 && empty_option < domanda_obj.length)
  {
      addToErrorMsg(domanda_id, messaggi["errore_classifica_opzione_vuota"]);
    return false;
  }

  return true;
}

/**
*  Questa funzione esegue due controlli su di una opzione personalizzabile:
*  1)  verifica che se selezionato il radiobutton o checkbox relativo al
*	   campo di testo della opzione personalizzabile, sia stato riempito anche
*	   il campo di testo relativo a questa opzione, e viceversa.
*  2)  verifica che il formato del testo contenuto nel campo di testo sia dello stesso
*      tipo di quello scelto per la domanda a cui l'opzione appartiene
*
*  @param array domanda_obj
*  @param int domanda_id
*  @param string domanda_text
*/
function checkOpzionePersonalizzabile(domanda_obj, domanda_id, domanda_text){

  var length = get_length(domanda_obj);
  if (length == 1 && !isArray(domanda_obj)) domanda_obj[0] = domanda_obj;

//alert(domanda_text);
  for(var i=0; i < length; i++){

    temp_array = domanda_obj[i].value.split("_");
//alert(temp_array);
    if(document.forms["intervista"].elements["opzioni_personalizzabili["+domanda_id+"]["+temp_array[0]+"]["+temp_array[1]+"]"]!=null){
      var testo = document.forms["intervista"].elements["opzioni_personalizzabili["+domanda_id+"]["+temp_array[0]+"]["+temp_array[1]+"]"].value;
//alert(testo);
      if(testo!="" && !domanda_obj[i].checked)
        addToErrorMsg(domanda_id, parse(messaggi["errore_opzione_personalizzabile1"], ["num", i+1]));

      if(testo=="" && domanda_obj[i].checked)
        addToErrorMsg(domanda_id, parse(messaggi["errore_opzione_personalizzabile2"], ["num", i+1]));

      var formato = _DOMANDA_FORMATO_PREDEFINITO;
      if(document.forms["intervista"].elements["formato["+domanda_id+"]"]!=null)
          formato = document.forms["intervista"].elements["formato["+domanda_id+"]"].value;

      if(testo!="")
        checkFormato(testo, formato, domanda_text);
    }
  }
}

/**
*  Verifica che il valore immesso in un campo di tipo "inserimento libero" sia conforme al formato scelto per questo campo.
*
*  @param array domanda_obj
*  @param int domanda_id
*  @param string domanda_text
*/
function checkFormatoTestoLibero(domanda_obj, domanda_id, domanda_text)
{
  var formato = _DOMANDA_FORMATO_PREDEFINITO;
  if(document.forms["intervista"].elements["formato["+domanda_id+"]"]!=null)
    formato = document.forms["intervista"].elements["formato["+domanda_id+"]"].value;

  if(domanda_obj.value!="")
    checkFormato(domanda_obj.value, formato, domanda_text);
}

/**
*  Controlla solo i formati data e numero. I formati 0(predefinito - singola riga) e 3(multiriga)
*  sono già definiti al momento della creazione del campo. Nel caso di 0 verrà creato un campo html di tipo
*  text; nel caso di 3 verrà creato un campo html di tipo textarea.
*
*  @param string text		  testo il cui formato è da verificare
*  @param int fromato		   formato richiesto per il testo passato dal parametro text
*  @param string domanda_text  etichetta della domanda di cui si sta controllando il formato
*/
function checkFormato(text, format, domanda_text)
{
  format *= 1; // cast numerico del valore copiato in format

  switch(format){
    case _DOMANDA_FORMATO_DATA:
      if(!text.match(/(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])\/(19|20)\d\d/)) addToErrorMsg(domanda_id, messaggi["errore_formato_data"]);
      break;
    case _DOMANDA_FORMATO_NUMERO:
      if(text.match(/^[-+]?(\d*\.)?\d+$/) == null) addToErrorMsg(domanda_id, messaggi["errore_formato_numero"]);
      break;
    default:
      return;
  }
}

/**
*  Verifica che sia stato valorizzato un campo obbligatorio.
*
*  @param array domanda_obj
*  @param int domanda_id
*  @param string domanda_text
*/
function checkDomandaObbligatoria(domanda_obj, domanda_text, domanda_type)
{
  var flag=false;

  switch(domanda_type)
  {
    case _DOMANDA_TIPO_SINGOLA:
    case _DOMANDA_TIPO_MULTIPLA:
      var length = domanda_obj.length;
      if(length!=null)
      {
        for(y=0; y < domanda_obj.length; y++)
        {
          if(is_selected(domanda_obj[y])) flag=true;
        }
      }
      else
      {
        if(is_selected(domanda_obj)) flag=true;
      }

      if(!flag){
        addToErrorMsg(domanda_id, messaggi["obbligatoria"]);
        return false;
      }
      break;

    case _DOMANDA_TIPO_ASSOCIAZIONE:
    case _DOMANDA_TIPO_CLASSIFICA:
      var checked = 0;

      for(var i=0; i<domanda_obj.length; i++)
      {
        var length = domanda_obj[i].length;
        if(length!=null)
        {
          for(var y=0; y<domanda_obj[i].length; y++)
          {
            if(is_selected(domanda_obj[i][y])) checked++;
          }
        }
        else
        {
          if(is_selected(domanda_obj[i])) checked++;
        }
      }

      if(checked!=domanda_obj.length)
      {
        addToErrorMsg(domanda_id, messaggi["obbligatoria"]);
        return false;
      }
      break;

    case _DOMANDA_TIPO_MATRICE:
      // Ogni elemento dice se per l'opzione relativa alla chiave è stata fornita risposta.
      var or = new Array();

      // Si annota se ogni opzione ha ricevuto almeno una risposta (pensando alle checkbox è sufficiente ceccarne una).
      for(var i=0; i<domanda_obj.length; i++)
      {
        var temp = domanda_obj[i].value.split('_');
        if (or[temp[0]] == null) or[temp[0]] = false;

        var length = domanda_obj[i].length;
        if(length!=null)
        {
          for(var y=0; y<domanda_obj[i].length; y++)
          {
            if(is_selected(domanda_obj[i][y])) or[temp[0]] = true;
          }
        }
        else if(is_selected(domanda_obj[i])) or[temp[0]] = true;
      }

      // Criterio di obbligatorietà: ogni opzione (custom o codificata) deve avere ricevuto ALMENO una risposta.
      flag = true;
      for(o in or) flag = flag && or[o];

      if(!flag)
      {
        addToErrorMsg(domanda_id, messaggi["obbligatoria"]);
        return false;
      }
      break;

    case _DOMANDA_TIPO_LIBERO:
      if(domanda_obj.value=="")
      {
        addToErrorMsg(domanda_id, messaggi["obbligatoria"]);
        return false;
      }
      break;
  }

  return true;
}


/**
*  Restituisce una copia dell'elemento del form identificato da id_domanda.
*  Ciò che viene restituito dipende dal tipo di domanda; se la domanda è di tipo scelta
*  singola, scelta multipla o inserimento libero, restituisco un oggetto rappresentante
*  l'elemento html, altrimenti, nel caso di associazione o classifica restituisco un array
*  di elementi html.
*
*  @param int id_domanda
*  @param int domanda_type
*/
function getDomandaObj(id_domanda, domanda_type)
{
  var domanda_obj = null;

  switch(domanda_type){
    case _DOMANDA_TIPO_SINGOLA:
    case _DOMANDA_TIPO_MULTIPLA:
      domanda_obj = document.forms["intervista"].elements["risposte[" + id_domanda + "][]"];
      break;
    case _DOMANDA_TIPO_ASSOCIAZIONE:
    case _DOMANDA_TIPO_CLASSIFICA:
      domanda_obj = new Array();
      for(var i=0; i<opzione.length; i++){
        if(opzione[i][0] == id_domanda){
          //domanda_obj.push(document.forms["intervista"].elements["risposte[" + id_domanda + "]["+opzione[i][1]+"]"]);
          domanda_obj[domanda_obj.length] = document.forms["intervista"].elements["risposte[" + id_domanda + "]["+opzione[i][1]+"]"];
        }
      }
      break;
    case _DOMANDA_TIPO_MATRICE:
      domanda_obj = new Array();
      for(var i=0; i<opzione.length; i++){
        if(opzione[i][0] == id_domanda){
          for(var j=0; j<enumerazione.length; j++){
            if(enumerazione[j][0] == id_domanda){
              domanda_obj[domanda_obj.length] = document.forms["intervista"].elements["risposte[" + id_domanda + "][" + opzione[i][1] + "][" + enumerazione[j][1] + "]"];            
	    }
          }
        }
      }      
      break;
    case _DOMANDA_TIPO_LIBERO:
      domanda_obj = document.forms["intervista"].elements["risposte[" + id_domanda + "][" + _CAMPO_TESTO_LIBERO + "]"];
      break;
  }

  return domanda_obj;

}

/**
*	Viene chiamato al momento della spedizione del form; controlla se ci sono
*   domande non visibili, e se le trova attraverso il metodo resetDomanda(),
*   ripulisce da eventuali risposte date (evidentemente quando erano visibili) a queste domande.
*/
function checkHiddenDomande()
{
  for(var y=0; y<domande.length; y++)
  {
    if (document.forms["intervista"].elements["visualizzazione["+domande[y][0]+"]"]!=null)
    {
      if (document.forms["intervista"].elements["visualizzazione["+domande[y][0]+"]"].value == "none")
      {
        resetDomanda(domande[y][0], domande[y][1]);
      }
    }
  }
}

/**
*  Cancella lo stato della domanda con id_domanda, che è stata nascosta in seguito ad un controllo di visibilità
*
*  @param int id_domanda    id della domanda di cui si vuole cancellare lo stato perchè nascosta
*  @param int domanda_type  tipo della domanda di cui si vuole cancellare lo stato perchè nascosta
*/
function resetDomanda(id_domanda, domanda_type)
{
  var domanda_obj = null;

  domanda_obj = getDomandaObj(id_domanda, domanda_type);

  if(domanda_obj!=null)
  {
    if(domanda_type==_DOMANDA_TIPO_SINGOLA || domanda_type==_DOMANDA_TIPO_MULTIPLA)
    {
      // prima mi occupo di cancellare il valore del campo nascosto che rappresenta questo oggetto
      // e le risposte date ad esso.
      document.forms["intervista"].elements["risposte[" + id_domanda + "]"].value="";
      for(var y=0; y < domanda_obj.length; y++)
      {
        domanda_obj[y].checked=false;
      }
    }
    else if(domanda_type==_DOMANDA_TIPO_ASSOCIAZIONE || domanda_type==_DOMANDA_TIPO_CLASSIFICA)
    {
      // prima mi occupo di cancellare il valore del campo nascosto che rappresenta questo oggetto
      // e le risposte date ad esso.
      document.forms["intervista"].elements["risposte[" + id_domanda + "]"].value="";
      for(var i=0; i<domanda_obj.length; i++)
      {
        for(var y=0; y<domanda_obj[i].length; y++)
        {
          //domanda_obj[i][y].checked=false;
          do_unselected(domanda_obj[i], domanda_obj[i][y], domanda_type);
        }
      }
    }
    else if(domanda_type==_DOMANDA_TIPO_LIBERO)
    {
      document.forms["intervista"].elements["risposte[" + id_domanda + "][" + _CAMPO_TESTO_LIBERO + "]"].value="";
    }
    else if(domanda_type==_DOMANDA_TIPO_MATRICE)
    {
    /* Per la domanda di tipo MATRICE, non è stato inserito nessun controllo, perché sembra che
      di questi controlli sia efficacie solo quello sulla domanda libera.
      Gli altri sembra essere superflui perché probabilmente c'è qualcosa lato server, che
      impedisce il salvataggio delle risposte fornite in domande che sono diventate invisibili.
    */
    }
  }
}

var last_key_up_time = 0;

var key_up_timeout_id = null;

var visibility = new Array();

var custom_conditions = new Array();

/**
*  E' un wrapper della funzione checkVisibility. Usato nel gestore dell'evento keyup dei controlli
*  relativi alle opzioni personalizzate e alle domande testo libero, serve per ridurre al minimo le
*  chiamata a checkVisibility, riducendo in questo modo i tempi di valutazione delle stringhe immesse
*  in questi campi, soprattuto nel caso di chiamata a Web Service.
*
*  @return void
*/
function checkVisibilityWrapper(id_domanda_selected, timeout)
{
	clearTimeout(key_up_timeout_id);

	current_time = new Date();
	current_time = current_time.getTime();

	var diff = (last_key_up_time > 0) ? (current_time - last_key_up_time) : 0;

	last_key_up_time = new Date();
	last_key_up_time = last_key_up_time.getTime();

	timeout = ((timeout == "undefined") ? 750 : timeout);
	if (diff == 0 ||
		diff >= timeout)
	{
		checkVisibility(id_domanda_selected);
	}
	else
		key_up_timeout_id = setTimeout("checkVisibility()", timeout);
}

/**
*  Determina la visibilità di una o più domande in base alle informazioni raccolte nell'array visibility.
*  L'elemento condition in cui di volta in volta viene copiato il valore dell'espressione che
*  si vuole valutare, viene, mano a mano che si procede nel parsing, modificata, fino a che non
*  si giunge ad una espressione i cui placeholder sono stati tutti sostituiti.
*
*  @return void
*/
function checkVisibility(id_domanda_selected)
{
  customConditionsEvaluation(prepareForDomandaVisibility, manageDomandaVisibility);

  if(visibility.length == 0) return;

  for(var i=0; i<visibility.length; i++)
  {
    var condition = visibility[i][1];
//alert("Visibilità domanda: " + visibility[i][0]);
    ciclodomande:
    for(var y=0; y<domande.length; y++)
    {
      var temp_array = new Array();

      if(document.forms["intervista"].elements["risposte["+domande[y][0]+"]"]!=null)
      {
        var id_domanda_on_off	   = visibility[i][0];
        var id_domanda_on_off_type = visibility[i][3];
        var id_domanda			   = domande[y][0];

        // se l'id della domanda la cui opzione ho selezionato corrisponde all'id della
        // domanda la cui visibilità sto determinando passo alla domanda successiva.
        if(id_domanda_on_off != id_domanda_selected)
        {
          if(visibility[i][2].indexOf("%"+id_domanda+"%") > -1)
          {
            var isvisible = is_visible(id_domanda);
            var domanda_type = domande[y][1];
            var domanda_obj  = getDomandaObj(id_domanda, domanda_type);

            if (domanda_obj == null) continue;

            if(domanda_type==_DOMANDA_TIPO_SINGOLA || domanda_type==_DOMANDA_TIPO_MULTIPLA)
            {
//alert("ID Domanda e condizione: " +  id_domanda + " " + condition);
              var cnt = 0;
              var length = get_length(domanda_obj);
              if (length == 1) domanda_obj[0] = domanda_obj;
              cicloopzioni:
              for(var j=0; j<length; j++)
              {
                if(domanda_obj[j].checked || domanda_obj[j].selected ||
                   !isvisible)
                {
                  cnt++;
                  temp_array = domanda_obj[j].value.split("_");
//alert("ID Opzione e condizione: " +  temp_array[0] + " " + condition);
                  condition = parseCondition(condition, id_domanda_on_off, id_domanda_on_off_type, id_domanda, domanda_type, temp_array[0], temp_array[1], isvisible);
                  if(condition=="") continue ciclodomande;
                }
              }

              if(cnt==0) hideDomanda(id_domanda_on_off, id_domanda_on_off_type);
            }
            else if(domanda_type==_DOMANDA_TIPO_ASSOCIAZIONE || domanda_type==_DOMANDA_TIPO_CLASSIFICA || domanda_type==_DOMANDA_TIPO_MATRICE)
            {
//alert("ID Domanda e condizione: " +  id_domanda + " " + condition);
              var cnt = 0;
              cicloopzioni:
//alert(domanda_obj);
              for(var j=0; j<domanda_obj.length; j++){
                var length = get_length(domanda_obj[j]);
                cicloenumerazioni:
                for(var z=0; z < length; z++){

                  if (length == 1)
                    var enum_obj = domanda_obj[j];
                  else
                    var enum_obj = domanda_obj[j][z];

                  if(is_selected(enum_obj) || !isvisible)
                  {
                    cnt++;

                    temp_array = enum_obj.value.split("_");

                    /* Nel caso di MATRICE, l'opzione da cercare è data dall'incrocio "id_opzione, valore_enumerazione",
                      pertanto, viene sostituito l'elemento 0 con il valore corretto.
                    */
                    if (domanda_type==_DOMANDA_TIPO_MATRICE) temp_array[0] = enum_obj.value;

//alert("ID Opzione e condizione: " +  temp_array[0] + " " + condition);
                    condition = parseCondition(condition, id_domanda_on_off, id_domanda_on_off_type, id_domanda, domanda_type,  temp_array[0], temp_array[1], isvisible);
                    if(condition=="") continue ciclodomande;
                  }
                }

                if(cnt==0) hideDomanda(id_domanda_on_off, id_domanda_on_off_type);
              }
            }
          }
        }
      }
      else continue;
    }
  }
}

/**
*	Verifica se una domanda è visibile oppure no, andando a leggere il valore dal campo nascosto "visualizzazione".
*
*	@param int id_domanda
*/
function is_visible(id_domanda)
{
  if (document.forms["intervista"].elements["visualizzazione["+id_domanda+"]"] != null)
    return (document.forms["intervista"].elements["visualizzazione["+id_domanda+"]"].value == "block");

  return true;
}

function get_length(field_obj)
{
  var length = field_obj.length;
  if (length == null) return 1;
  return length;
}

/**
*  Controlla se l'opzione passata tramite il parametro opzione è stato selezionato.
*
*  @param object opzione     istanza di un oggetto Input
*  @return boolean
*/
function is_selected(opzione)
{
  if (opzione.value=='')
    return false;
  else
  {
    if (opzione.type=='radio' || opzione.type=='checkbox')
      return opzione.checked;
    else
      return opzione.selected;
  }
}

/**
*	Deseleziona un opzione di un select, un radiobutton o un checkbox;
*   ho bisogno del tipo di domanda (domanda_type) per determinarlo.
*
*	@param object element_obj
*	@param object opzione
*	@param string domanda_type
*/
function do_unselected(element_obj, opzione, domanda_type)
{
  if (opzione.checked != null)
    opzione.checked = false;
  else if (element_obj[0].selected != null)
    element_obj[0].selected = true;
}

/**
*  Effettua il parsing della stringa con le condizioni (argomento condition) da verificare per determinare
*  la visibilità della domanda riferita da id_domanda_on_off.
*  Viene richiamata all'interno della funzione checkVisibility(), effettuando, per ogni condizione trovata
*  (array visibility), un controllo su ogni risposta ad ogni domanda presente nella pagina.
*  L'id_domanda è la domanda corrente da controllare.
*  Restituisce la stringa con le condizioni già valutate + quelle da valutare.
*
*  @param string condition             l'espressione con le condizioni da verificare
*  @param int id_domanda_on_off        id della domanda la cui visibilità devo verificare
*  @param int id_domanda_on_off_type   tipo della domanda la cui visibilità devo verificare
*  @param int id_domanda			   id della domanda la cui opzione ho selezionato
*  @param int domanda_type			   tipo della domanda la cui opzione ho selezionato
*  @param int id_opzione               id dell'opzione selezionata
*  @param int valore	               valore dell'opzione selezionata
*  @return string
*/
function parseCondition(condition, id_domanda_on_off, id_domanda_on_off_type, id_domanda, domanda_type, id_opzione, valore, isvisible)
{
    var new_condition = "";
    if(condition.match(/%/g)){

      // se nella stringa con l'espressione da valutare c'è un placeholder con l'id dell'opzione uguale a 0
      // vuol dire che devo eseguire la sostituzione con il valore dell'opzione selezionata
      // facendo il match tra lo 0 e l'id della domanda a cui l'opzione appartiene
      var sost = (condition.match(/%0%/)) ? new RegExp("%0%", "g") : new RegExp("%"+id_opzione+"%", "g");

      // controllo che l'opzione che ho selezionato (id_opzione) compaia nella stringa (rappresentata
      // da condition) con le condizioni che devo verificare (questa condizione potrebbe essere falsa nei
      // tipi di domanda associazione e classifica)
      if((domanda_type==_DOMANDA_TIPO_ASSOCIAZIONE || domanda_type==_DOMANDA_TIPO_CLASSIFICA) &&
        id_opzione!=""){
        if(!condition.match(sost)) return condition;
      }

      // Se la domanda che sto esaminando non è visibile non è valutabile e quindi la dovrei
      // eliminare dall'espressione. Visto che non è così semplice farlo, considero le condizioni
      // basate su di essa sempre false.
      if (!isvisible)
      {
        // Espressione regolare per matchare il valore da confrontare
        // con il valore dell'opzione selezionata (che in questo caso non abbiamo).
        // %id_opzione%='valore' è sotituita con 1 in modo che sia sempre vera.
        var matchin = new RegExp("%"+id_opzione+"%[=><!]=?'\\d+'", "g");
        condition = condition.replace(matchin, "0");
      }
      else
        condition = condition.replace(sost, "'" + valore + "'");

      var new_condition = condition;

      // Se la sostituzione non ha avuto luogo vuol dire che non ho cliccato l'opzione per visualizzare
      // la domanda; per sicurezza sostituisco l'espressione %[id_opzione]% con 0 in modo che l'eval
      // della condizione di cui sotto restituisca sempre FALSE.
      condition = condition.replace(/%\d+(_\d+)?%/g, "0");

      if(eval(condition))
        showDomanda(id_domanda_on_off, id_domanda_on_off_type);
      else
        hideDomanda(id_domanda_on_off, id_domanda_on_off_type);

      return new_condition;
    }

    return new_condition;
}

function hideDomanda(id_domanda_on_off, id_domanda_on_off_type)
{
  document.getElementById("D_" + id_domanda_on_off).style.display = document.forms["intervista"].elements["visualizzazione[" + id_domanda_on_off + "]"].value = "none";
  //resetDomanda(id_domanda_on_off, id_domanda_on_off_type);
}

function showDomanda(id_domanda_on_off, id_domanda_on_off_type)
{
  document.getElementById("D_" + id_domanda_on_off).style.display = document.forms["intervista"].elements["visualizzazione[" + id_domanda_on_off + "]"].value = "block";
}

var is_checked=new Array();

function deCheck(obj, id, id_domanda, id_opzione)
{
  if (id_domanda != null)
  {
    if (id_opzione == null) id_opzione = "";

    // Indice di selezione dell'elemento.
    var indice = "risposte[" + id_domanda + "][" + id_opzione + "]";
    for(var i=0; i<document.forms["intervista"].elements[indice].length; i++)
    {
      values = document.forms["intervista"].elements[indice][i].value;
      if (values != id) is_checked[values] = false;
    }
  }

  if(!is_checked[id]){
    is_checked[id] = true;
    obj.checked=true;
    return;
  }

  if(is_checked[id]){
    is_checked[id] = false;
    obj.checked = false;
    return;
  }
}


function stripHtmlTags(text)
{
  var reg_exp = new RegExp("<[\/\!]*?[^<>]*?>", "gi");
  text = text.replace(reg_exp, "");

  //text = text.replace(/<[\/\!]*?[^<>]*?>/gi, "");

  return "\"" + text + "\"";
}

/**
*  Sostituisce il placeholder presente nel testo passato tramite il parametro text e
*  specificato nel primo elemento dell'array replace con il testo specificato
*  nel secondo elemento dell'array medesimo.
*
*  @param string text
*  @param array replace
*  @return string
*/
function parse(text, replace)
{
  var reg = new RegExp("%"+replace[0]+"%", "g");
  text = text.replace(reg, replace[1]);
  return text;
}

function changeOpzionePersonalizzabile(id_domanda, id_opzione, valore_opzione)
{
  // Valore da assegnare al checkbox/radio.
  var check_val = (document.forms["intervista"].elements["opzioni_personalizzabili["+id_domanda+"]["+id_opzione+"]["+valore_opzione+"]"].value != "")

  var domanda_obj = document.forms["intervista"].elements["risposte["+id_domanda+"][]"];

  // Se non trova l'elemento col nome semplice, lo cerca considerando l'incrocio dato dalla coppia <opzione, valore>.
  if (domanda_obj==null)
    domanda_obj = document.forms["intervista"].elements["risposte["+id_domanda+"]["+id_opzione+"]["+valore_opzione+"]"];

  if (domanda_obj.length)
  {
    for(var i=0; i<domanda_obj.length; i++)
    {
      if (domanda_obj[i].value == id_opzione+"_"+valore_opzione) domanda_obj[i].checked=check_val;
    }
  }
  else if (domanda_obj.value == id_opzione+"_"+valore_opzione) domanda_obj.checked=check_val;
}

function login()
{
  if ((document.forms["frmLogin"].elements["username"].value!='') && (document.forms["frmLogin"].elements["password"].value!='')) {
    document.forms["frmSubmit"].elements["u"].value = document.forms["frmLogin"].elements["username"].value;
    document.forms["frmSubmit"].elements["response"].value = hex_hmac_md5(document.forms["frmLogin"].elements["username"].value + document.forms["frmLogin"].elements["password"].value, document.forms["frmSubmit"].elements["challenge"].value);
    document.forms["frmSubmit"].submit();
  }
}


//function scegliTraduzione(questionario_id){
function scegliTraduzione(questionario_lingua)
{
  //document.forms["frmSubmit"].elements["questionario_lingua"].value = questionario_id;
  document.forms["frmSubmit"].elements["questionario_lingua"].value = questionario_lingua;
  document.forms["frmSubmit"].submit();
}

function submitPrivacyForm(button_obj)
{
  if(!check_actived)
    document.forms["frmWelcome"].elements["questionario_id"].value=0;
  else{
    if(!document.forms["frmWelcome"].elements["privacy"][0].checked)
    {
      alert(messaggi["privacy_rifiutata"]);
      return;
    }
  }

  document.forms["frmWelcome"].elements["cmd"].name = button_obj.name;
  document.forms["frmWelcome"].submit();
}

function limitText(field, maxlimit)
{
  if (field.value.length > maxlimit)
    field.value = field.value.substring(0, maxlimit);
}


function get_html_translation_table(table, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: noname
    // %          note: It has been decided that we're not going to add global
    // %          note: dependencies to php.js. Meaning the constants are not
    // %          note: real constants, but strings instead. integers are also supported if someone
    // %          note: chooses to create the constants themselves.
    // %          note: Table from http://www.the-art-of-web.com/html/character-codes/
    // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
    // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}

    var entities = {}, histogram = {}, decimal = 0, symbol = '';
    var constMappingTable = {}, constMappingQuoteStyle = {};
    var useTable = {}, useQuoteStyle = {};

    useTable      = (table ? table.toUpperCase() : 'HTML_SPECIALCHARS');
    useQuoteStyle = (quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT');

    // Translate arguments
    constMappingTable[0]      = 'HTML_SPECIALCHARS';
    constMappingTable[1]      = 'HTML_ENTITIES';
    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
    constMappingQuoteStyle[2] = 'ENT_COMPAT';
    constMappingQuoteStyle[3] = 'ENT_QUOTES';

    // Map numbers to strings for compatibilty with PHP constants
    if (!isNaN(useTable)) {
        useTable = constMappingTable[useTable];
    }
    if (!isNaN(useQuoteStyle)) {
        useQuoteStyle = constMappingQuoteStyle[useQuoteStyle];
    }

    if (useQuoteStyle != 'ENT_NOQUOTES') {
        entities['34'] = '&quot;';
    }

    if (useQuoteStyle == 'ENT_QUOTES') {
        entities['39'] = '&#039;';
    }

    if (useTable == 'HTML_SPECIALCHARS') {
        // ascii decimals for better compatibility
        entities['38'] = '&amp;';
        entities['60'] = '&lt;';
        entities['62'] = '&gt;';
    } else if (useTable == 'HTML_ENTITIES') {
        // ascii decimals for better compatibility
      entities['38']  = '&amp;';
      entities['60']  = '&lt;';
      entities['62']  = '&gt;';
      entities['160'] = '&nbsp;';
      entities['161'] = '&iexcl;';
      entities['162'] = '&cent;';
      entities['163'] = '&pound;';
      entities['164'] = '&curren;';
      entities['165'] = '&yen;';
      entities['166'] = '&brvbar;';
      entities['167'] = '&sect;';
      entities['168'] = '&uml;';
      entities['169'] = '&copy;';
      entities['170'] = '&ordf;';
      entities['171'] = '&laquo;';
      entities['172'] = '&not;';
      entities['173'] = '&shy;';
      entities['174'] = '&reg;';
      entities['175'] = '&macr;';
      entities['176'] = '&deg;';
      entities['177'] = '&plusmn;';
      entities['178'] = '&sup2;';
      entities['179'] = '&sup3;';
      entities['180'] = '&acute;';
      entities['181'] = '&micro;';
      entities['182'] = '&para;';
      entities['183'] = '&middot;';
      entities['184'] = '&cedil;';
      entities['185'] = '&sup1;';
      entities['186'] = '&ordm;';
      entities['187'] = '&raquo;';
      entities['188'] = '&frac14;';
      entities['189'] = '&frac12;';
      entities['190'] = '&frac34;';
      entities['191'] = '&iquest;';
      entities['192'] = '&Agrave;';
      entities['193'] = '&Aacute;';
      entities['194'] = '&Acirc;';
      entities['195'] = '&Atilde;';
      entities['196'] = '&Auml;';
      entities['197'] = '&Aring;';
      entities['198'] = '&AElig;';
      entities['199'] = '&Ccedil;';
      entities['200'] = '&Egrave;';
      entities['201'] = '&Eacute;';
      entities['202'] = '&Ecirc;';
      entities['203'] = '&Euml;';
      entities['204'] = '&Igrave;';
      entities['205'] = '&Iacute;';
      entities['206'] = '&Icirc;';
      entities['207'] = '&Iuml;';
      entities['208'] = '&ETH;';
      entities['209'] = '&Ntilde;';
      entities['210'] = '&Ograve;';
      entities['211'] = '&Oacute;';
      entities['212'] = '&Ocirc;';
      entities['213'] = '&Otilde;';
      entities['214'] = '&Ouml;';
      entities['215'] = '&times;';
      entities['216'] = '&Oslash;';
      entities['217'] = '&Ugrave;';
      entities['218'] = '&Uacute;';
      entities['219'] = '&Ucirc;';
      entities['220'] = '&Uuml;';
      entities['221'] = '&Yacute;';
      entities['222'] = '&THORN;';
      entities['223'] = '&szlig;';
      entities['224'] = '&agrave;';
      entities['225'] = '&aacute;';
      entities['226'] = '&acirc;';
      entities['227'] = '&atilde;';
      entities['228'] = '&auml;';
      entities['229'] = '&aring;';
      entities['230'] = '&aelig;';
      entities['231'] = '&ccedil;';
      entities['232'] = '&egrave;';
      entities['233'] = '&eacute;';
      entities['234'] = '&ecirc;';
      entities['235'] = '&euml;';
      entities['236'] = '&igrave;';
      entities['237'] = '&iacute;';
      entities['238'] = '&icirc;';
      entities['239'] = '&iuml;';
      entities['240'] = '&eth;';
      entities['241'] = '&ntilde;';
      entities['242'] = '&ograve;';
      entities['243'] = '&oacute;';
      entities['244'] = '&ocirc;';
      entities['245'] = '&otilde;';
      entities['246'] = '&ouml;';
      entities['247'] = '&divide;';
      entities['248'] = '&oslash;';
      entities['249'] = '&ugrave;';
      entities['250'] = '&uacute;';
      entities['251'] = '&ucirc;';
      entities['252'] = '&uuml;';
      entities['253'] = '&yacute;';
      entities['254'] = '&thorn;';
      entities['255'] = '&yuml;';
    } else {
        throw Error("Table: "+useTable+' not supported');
        return false;
    }

    // ascii decimals to real symbols
    for (decimal in entities) {
        symbol = String.fromCharCode(decimal)
        histogram[symbol] = entities[decimal];
    }

    return histogram;
}

function htmlspecialchars (string, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Mirek Slugen
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Nathan
    // +   bugfixed by: Arno
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // -    depends on: get_html_translation_table
    // *     example 1: htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
    // *     returns 1: '&lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;'

    var histogram = {}, symbol = '', tmp_str = '', entity = '';
    tmp_str = string.toString();

    if (false === (histogram = get_html_translation_table('HTML_SPECIALCHARS', quote_style))) {
        return false;
    }

    for (symbol in histogram) {
        entity = histogram[symbol];
        tmp_str = tmp_str.split(symbol).join(entity);
    }

    return tmp_str;
}



/********************** AJAX-JQUERY **********************************/

function customConditionsEvaluation(request_method, response_method)
{
	error_msg = new Array();

  	var options = {
    	url:		  'valutatore_condizioni.php',
    	type:		  'post',
        dataType:  	  'xml',        // 'xml', 'script', or 'json' (expected server response type)
        //target:        '#output2',   // target element(s) to be updated with server response
        beforeSubmit:  request_method,  // pre-submit callback
        success:       response_method  // post-submit callback
    };

  	$('#intervista').ajaxSubmit(options);
}

function prepareForDomandaVisibility(formData, jqForm, options)
{
	error_msg = new Array();

	options.url = "valutatore_condizioni.php?tipo_controllo=" + _ESPRESSIONE_VISIBILITA;
	return true;
}

function prepareForValidation(formData, jqForm, options)
{
	options.url = "valutatore_condizioni.php?tipo_controllo=" + _ESPRESSIONE_VALIDAZIONE;
	return true;
}

/*
	post-submit callback
	Legge la risposta di XMLHTTPRequest. Avendo usato come tipo di risposta l'xml,
	si usa la proprietà di XMLHTTPRequest apposita per questo caso: responseXML.
	Si legge l'xml usando degli oggetti DHTML un pò più cross-browser rispetto a quelli
	forniti dal DOM.

	La risposta XML è cosi formata (leggere lo script validatore.php):

	<?xml version="1.0" encoding="UTF-8"?>
	<root>
		<domanda id="5">
			<messaggio id_domanda="1" codice_domanda="D1">
				<testo>Devi rispondere bene!</testo>
				[<titolo>Titolo custom</testo>]
			</messaggio >
			<messaggio id_domanda="2" codice_domanda="D2">
				<testo>Deve essere una data corretta.</testo>
				[<titolo>Titolo custom</testo>]
			</messaggio >
		</domanda>
	</root>
*/

// Gestisce la validazione delle risposte sulla base della risposta restituita dal valutatore delle condizioni.
function manageValidation(responseXML)
{
	var messaggio = responseXML.getElementsByTagName("messaggio");

	if (messaggio.length > 0)
	{
		var id = 0;
		var msg = "";
		var titolo = null;
		for (var i = 0; i < messaggio.length; i++)
		{
			id = messaggio[i].getAttribute("id_domanda");
			msg = (messaggio[i].childNodes[0].childNodes[0] != null) ? messaggio[i].childNodes[0].childNodes[0].nodeValue : "";
			if (messaggio[i].childNodes[1] != null)
				titolo = (messaggio[i].childNodes[1].childNodes[0] != null) ? messaggio[i].childNodes[1].childNodes[0].nodeValue : "";

			addToErrorMsg(id, ((messaggi[msg] != null) ? messaggi[msg] : msg), titolo);

			titolo = null;
		}
	}

	// Chiamata al classico metodo usato per spedire il form.
	// Questo metodo esegue ulteriori controlli "standard" sui campi di tipo "testo libero"
	// e impedisce la spedizione del form se la variabile "errror_msg" non è vuota (vuol dire
	// che ci sono dei messaggi di errore da mostrare).
	submitForm(window.document.forms["intervista"].elements["__NEXT__"], true);
}

// Gestisce la visibilità di una domanda sulla base della risposta restituita dal valutatore delle condizioni.
function manageDomandaVisibility(responseXML)
{
	var id = 0;
	var domande_condizionate = responseXML.getElementsByTagName("domanda");	
	for (var i = 0; i < domande_condizionate.length; i++)
	{
		if (domande_condizionate[i].childNodes.length > 0)
		{
			id = domande_condizionate[i].getAttribute("id");
			hideDomanda(id);		
		}
		else
		{		
			id = domande_condizionate[i].getAttribute("id");
			showDomanda(id);		
		}
	}
}

function debugResponse(responseText, statusText)
{
	alert(responseText + ' ' + statusText);
}

var connectionSpeed = 0;

function drawCSImageTag( fileLocation, fileSize, imgTagProperties )
{
	// This function draws the image tag required to run this process.
	// It needs to be passed:
	//     1.  (String)   The location of the file to be loaded
	//     2.  (Integer)  The size of the image file in bytes
	//     3.  (String)   The tag properties to be included in the <img> tag
	// Place a call to this function inside the <body> of your file
	// in place of a static <img> tag.

	start = (new Date()).getTime();
	// Record Start time of <img> load.

	loc = fileLocation + '?t=' + escape(start);
	// Append the Start time to the image url
	// to ensure the image is not in disk cache.

	document.write('<img src="' + loc + '" ' + imgTagProperties + ' onload="connectionSpeed=computeConnectionSpeed(' + start + ',' + fileSize + ');">');
	// Write out the <img> tag.

	return;
}

function debugConnectionType(speed)
{
	// This function returns a string describing the connection type
	// being used by the user-agent hitting the page.

	SLOW_MODEM = 15;
	FAST_MODEM = 57;
	ISDN_MODEM = 120;
	// These are constants which define the base speeds
	// for a number of different connections.  They are
	// measured in units of kbps.

	if (speed)
	{
		if (speed < SLOW_MODEM)
		{
			return "Slow Modem";
		} else if (speed < FAST_MODEM)
		{
			return "Fast Modem";
		} else if (speed < ISDN_MODEM)
		{
			return "ISDN Modem";
		} else
		{
			return "partial T1 or greater connection";
		}
	}
	else
	{
		return "Undetermined Connection";
	}
}

function computeConnectionSpeed( start, fileSize )
{
	// This function returns the speed in kbps of the user's connection,
	// based upon the loading of a single image.  It is called via onload
	// by the image drawn by drawCSImageTag() and is not meant to be called
	// in any other way.  You shouldn't ever need to call it explicitly.
	end = (new Date()).getTime();
	connectSpeed = (Math.floor((((fileSize * 8) / ((end - start) / 1000)) / 1024) * 10) / 10);
	return connectSpeed;
}

function getStyleProp(element, prop)
{
  if(element.currentStyle)
      return(element.currentStyle[prop]);
  if(document.defaultView.getComputedStyle)
      return rgbConvert(document.defaultView.getComputedStyle(element,'')[prop]);
  return(null);
}

function rgbConvert(str)
{
   str = str.replace(/rgb\(|\)/g, "").split(",");
   str[0] = parseInt(str[0], 10).toString(16).toLowerCase();
   str[1] = parseInt(str[1], 10).toString(16).toLowerCase();
   str[2] = parseInt(str[2], 10).toString(16).toLowerCase();
   str[0] = (str[0].length == 1) ? '0' + str[0] : str[0];
   str[1] = (str[1].length == 1) ? '0' + str[1] : str[1];
   str[2] = (str[2].length == 1) ? '0' + str[2] : str[2];
   return ('#' + str.join(""));
}

function isArray(variable)
{
    return (variable.constructor == Array);
}