/*******************************************************
* QUIX S.r.l. - Form Validation V1.0 - 29/04/2003 10.29
* Author: Mattia Miello - mattia.miello@quix.it
* Copyright (C) 2003 - QUIX S.r.l.
*******************************************************/


// CONTROLLO ED EVENTUALE IMPOSTAZIONE DELLE VARIABILI GLOBALI 
// (CHE DOVREBBERO ESSERE DEFINITE ALL'INTERNO DELLA PAGINA HTML)
// SE NON LO SONO IMPOSTIAMO ALCUNI VALORI DI DEFAULT (SEMPRE A LIVELLO GLOBALE)
//if(!_ERROR_MSG_NOT_VALID_VALUE) var _ERROR_MSG_NOT_VALID_VALUE = "Errore! Valore non ammesso!";
//if(!_ERROR_MSG_REQUIRED_FIELD_VOID) var _ERROR_MSG_REQUIRED_FIELD_VOID = "Errore! Il campo non può essere lasciato vuoto!";
//if(!_LOCAL_DATE) var _LOCAL_DATE = "dmy";
//if(!_LOCAL_DECIMAL_CHAR) var _LOCAL_DECIMAL_CHAR =  "."; 
//if(!_LOCAL_THOUSAND_CHAR) var _LOCAL_THOUSAND_CHAR = ",";  
//if(!_ERR_STYLE) var _ERR_STYLE = "flatinput";
//if(!_OK_STYLE) var _OK_STYLE = "flatinput"; 
//if(!KO_IMAGE) var KO_IMAGE = "images/error.gif";
//if(!OK_IMAGE) var OK_IMAGE = "images/icon_ok.gif";

//VARIABILE GLOBALE CHE INDICA LA NORMALIZZAZIONE DEL VALORE
//POSTO NULL PERCHÈ VARIERA' IN BASE AL TIPO DI DATO
var normalizedValue=null;

// PRELOAD IMMAGINI DI ERRORE
var img_ko = new Image();
var img_ok = new Image();
//IMMAGINE CHE VIENE VISUALIZZATA ALLA PRESENZA DI UN ERRORE
//DEFINITA LOCALMENTE ALL'INTERNO DELLA PAGINA HTML
img_ko.src = KO_IMAGE;
//IMMAGINE CHE VIENE VISUALIZZATA IN MANCANZA DI ERRORI(PIXEL VUOTI)
//DEFINITA LOCALMENTE ALL'INTERNO DELLA PAGINA HTML
img_ok.src = OK_IMAGE;


// VERIFICA SE IL VALORE INSERITO IN UN CAMPO È UNA MAIL O NO
// RITORNA TRUE SE È UNA MAIL; FALSE SE NON LO È.
function is_email(theValue) {
	
	normalizedValue=null;
	//REG.EXP CHE CONTROLLA L'EMAIL
  var filter=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i
  
  //CONFRONTO TRA IL VALORE E LA REG.EXP
	if (filter.test(theValue)){
		 //LA NORMALIZZAZIONE DEL VALORE È IL VALORE STESSO
		 normalizedValue = theValue;
		 return true;
	}else 
	   return false;
}



// VERIFICA SE UN DATO NUMERO È INTERO E METTE IL VALORE NUMERICO NORMALIZZATO (CIOÈ PRIVATO 
// DEL SEPARATORE DELLE MIGLIAIA) NELLA VARIABILE GLOBALE NORMALIZEDVALUE
function is_integer(theValue){
	
	// OSS: 01 0003 ECC VENGONO RITENUTI CORRETTI COME INTERI
	//_LOCAL_THOUSAND_CHAR VARIABILE LOCALE INDICIZZATA NELL'HTML
	var ltc=_LOCAL_THOUSAND_CHAR;
	var first= theValue.indexOf(ltc);
	var pattern;
	normalizedValue=null;
	
	if(first==-1){
		//SE IL SEPARATORE DELLE MIGLIAIA NON È PRESENTE
		pattern=/^[+-]?\d+$/;
		if(pattern.test(theValue)){
			normalizedValue = theValue;
			return true;
		}else{
			return false;
		}
	}else{
		//SEPARATORE MIGLIAIA PRESENTE. SI CONTROLLA  CHE CE NE SIA UNO SOLO
		var specialChar = "\\/.*+?|()[]{}";
		if (specialChar.indexOf(ltc)!=-1){
			//CARATTERE SPECIALE, DEVE ESSERE PRECEDUTO DA BACKSLASH NELL'ESPRESSIONE
			ltc = '\\'+ltc;
		}
		var appo="^[+-]?[1-9]\\d?\\d?"+ltc+"(\\d{3}"+ltc+")*\\d{3}$";
		pattern=new RegExp(appo); 
		if(pattern.test(theValue)){
			//MATCH: CORRETTO
			var p=ltc;
			var re = new RegExp(p,'g');
			normalizedValue = theValue.replace(re,"");
			return true;
		}else{
			return false;
		}
	}
}



// VERIFICA SE UN DATO NUMERO È DECIMALE E METTE IL VALORE NUMERICO NORMALIZZATO (PARETE INTERA PRIVATA
// DEL SEPARATORE DELLE MIGLIAIA E SEPARATORE DECIMALE IMPOSTATO A .) NELLA VARIABILE GLOBALE NORMALIZEDVALUE
function is_decimal(theValue){
	
	//VARIABILE LOCALE INDICIZZATA NELL'HTML
	
	//VARIABILE LOCALE INDICIZZATA NELL'HTML
	var ldc=_LOCAL_DECIMAL_CHAR;
	var first;
	normalizedValue=null;
	
	//SI CONTROLLA LA PRESENZA DEL SEPARATORE
	if((first=theValue.indexOf(ldc))==-1){
		//SE IL SEPARATORE DEI DECIMALI NON È PRESENTE
			return is_integer(theValue);
	}else{ 
		if(theValue.lastIndexOf(ldc)!=first){
			//PIÙ DI UN SEPARATORE DECIMALE PRESENTE
			return false;
		}
		//ARRAY DI STRINGHE INDIVIDUATE DA LDC
		var theNumber = theValue.split(ldc);
		//VAR VALUEDEC = /\D+/.TEST(THENUMBER[1]);
		//RETURN (IS_INTEGER(THENUMBER[0]) && VALUEDEC);
					
		//CONTROLLI E NORMALIZZAZIONE DEI VALORI DELL'ARRAY
		if (theNumber[1]==""){
			return false;
		}
		var errDec = /\D+/.test(theNumber[1]);
		if (theNumber[0]==""){
			if (!errDec){
				normalizedValue = 0+ldc+theNumber[1];	
			}
			return (!errDec);
		}
		if (is_integer(theNumber[0]) && !errDec){
			normalizedValue = normalizedValue+ldc+theNumber[1];	
			return true;	
		}
		return false;			
	}
}



//FUNZIONE CHE CONTROLLA CHE SIA UN CARATTERE(VALORE DEL CAMPO)
function is_char(theValue){
	normalizedValue=null;
	if (theValue.length==1){
		normalizedValue=theValue;
		return true;
	}
	return false;
}



//FUNZIONE CHE CONTROLLA CHE SIA UNA STRINGA(VALORE DEL CAMPO)
function is_string(theValue){
	normalizedValue=theValue;
		return true;
}



//FUNZIONE CHE CONTROLLA L'ANNO BISESTILE(YEAR)
function _bisestile(y){
	if (y % 4 != 0){
	return false;
	}  
	if (y % 100 != 0){
	  return true;
	}  
	if (y % 400 != 0){
	  return false;
	}  
	return true;
}



//FUNZIONE CHE CONTROLLA QUANTI GIORNI HANNO I MESI(MONTH,YEAR)
function _maxDay(m,y){
	if (m == 4 || m == 6 || m == 9 || m == 11){
    	return 30;
  }else{ 
    if (m == 2){
			if (_bisestile(y)){
      		return 29;
      }else{
      		return 28;
      }
    }else{ 
    			return 31;
    }		
  }		  			
}



//FUNZIONE CHE CONTROLLA SE LO SPAZIO E' VUOTO
function isBlank(stringa){
  for(c=0; c< stringa.length; c++){
    caratt = stringa.substring(c,c+1);
	  if (!(caratt==' '))
	     return false;
  }
       return true;
}



/*******************************************************************************************************************
*   FUNZIONE IS_DATE:
*   CONTROLLA LA DATA A PARTIRE DAL VALORE DEL CAMPO, E DAL FORMATO LOCALE LA FUNZIONE ESTRAE I VALORI DI GIORNO 
    MESE ED ANNO E NE VERIFICA LA VALIDITA' COME ELEMENTO DI DATA.
*   COME SEPARATORI SONO AMMESSI LO SPAZIO, "/" E "-". È POSSIBILE OMETTERE IL SEPARATORE.
* 	SE LA DATA È CORRETTA VIENE SALVATO IL SUO VALORE E  NORMALIZZATO IN BASE ALLA VARIABILE _LOCAL_DATE INDICIZZATA
*   NELLA PAGINA HTML
********************************************************************************************************************
*  LA FUNZIONE is_time ACCETTA UN PARAMETRO STRINGA E RESTITUISCE TRUE O FALSE
*******************************************************************************************************************/

function is_date(strIn) {
	  var ld=_LOCAL_DATE ;
    data_st=strIn;
    //LUNGHEZZA CAMPO
		data_len=data_st.length;
		//CONTROLLO SE È VUOTA 
		if (isBlank(data_st)){
       return false;
		}
		
		// PRIMO CONTIENE LA POSIZIONE DEL PRIMO SEPARATORE, 
		//SECONDO LA POSIZIONE DEL SECONDO 
		//DELTA VALE 1 SE ESISTE SEPARATORE, 0 ALTRIMENTI
    delta=1;
		primo = data_st.indexOf('/');
		if (primo != -1){ 
		   separatore='/';    
		}else{
		   primo = data_st.indexOf('-');
		   if (primo != -1)
		      separatore='-';
		   else{
		     delta=0;
			   primo=2;
			   secondo=4;
		   }	
		}	
		if (delta==1){
		  secondo = data_st.indexOf(separatore, primo + 1)
		  if (secondo == -1){
		     return false;
		  }
		} 
		 	 
		//CICLO PER TROVARE L'ESATTA POSIZIONE DI MESE,GIORNO,ANNO ALL'INTERNO DELLA STRINGA DI _LOCAL_DATE
		//_LOCAL_DATE E' LA VARIABILE LOCALE SULLA PAGINA HTML
		for (var m=0; m<3; m++) {
			var tmp = ld.charAt(m);
			//PRIMA POSIZIONE
			if(m==0) {
				if("d"==tmp) { giorno = data_st.substring(0,primo); }
				if("m"==tmp) { mese = data_st.substring(0,primo); }
				if("y"==tmp) { anno = data_st.substring(0,primo); }
				continue;
			}
			//SECONDA POSIZIONE
			if(m==1) {
				if("d"==tmp) { giorno = data_st.substring(primo+delta, secondo); }
				if("m"==tmp) { mese = data_st.substring(primo+delta, secondo); }
				if("y"==tmp) { anno = data_st.substring(primo+delta, secondo); }
				continue;
			}
			//TERZA POSIZIONE
			if(m==2) {
				if("d"==tmp) { giorno = data_st.substring(secondo + delta); }
				if("m"==tmp) { mese = data_st.substring(secondo + delta); }
				if("y"==tmp) { anno = data_st.substring(secondo + delta); }
				continue;
			}
		}
		
     //CONTROLLO CHE D,M,Y SIANO NUMERI INTERI
     //ELIMINO EVENTUALI ZERO E TRASFORMO IN VALORE NUMERICO 
		if (!(is_integer(giorno))){
		  return false;
		}
	    giorno = eliminaZeriDavanti(giorno);
		  giorno=parseInt(giorno);   
		
		if (!(is_integer(mese))){
		   return false;
		}
	    mese = eliminaZeriDavanti(mese);
		  mese=parseInt(mese);   
		
		if (!(is_integer(anno))){
		   return false;
		} 
	    anno = eliminaZeriDavanti(anno);
	    
	    
		// NORMALIZZO L'ANNO AL 1900
		if ((40 <= anno) && ( anno <= 99 ) )
		  anno= parseInt(anno) + 1900;
		if ((0<=anno) && (anno<=39))
		  anno = parseInt(anno) + 2000;
		    
		//ORA HO ISOLATO GIORNO MESE E ANNO
		//CONTROLLO LA VALIDITA DEI VALORI
    if (!(annoOk(anno))){
		  return false;
		}
		if (!(meseOk(mese))){
		  return false;
		}	
		if (!(giornoOk(giorno,mese,anno))){
		  return false;
		}
		
    //COSTRUZIONE STRINGA PER LA FORMATTAZIONE DELLA DATA ATTRAVERSO UN CICLO 
    //DOPO OGNI VALORE VIENE INSERITO IL SEPARATORE "/"
		normalizedValue = "";
		for (var m=0; m<3; m++) {
			var tmp = ld.charAt(m);
			if('d'==tmp) { normalizedValue += giorno; }
			if('m'==tmp) { normalizedValue += mese; }
			if('y'==tmp) { normalizedValue += anno; }
			normalizedValue += "/";
		}
    //ELIMINO IL SEPARATORE IN CODA ALLA STRINGA
		normalizedValue = normalizedValue.substring(0,normalizedValue.length-1);		
		return true;		 
}


	
//ELIMINA GLI EVENTUALI ZERO PRESENTI DAVANTI ALLA STRINGA
function eliminaZeriDavanti(stringa){
  if (stringa.substring(0,1)=="0") return stringa.substring(1);
  else return stringa;
}

 

//CONTROLLO DEL GIORNO 
function giornoOk(giorno,mese,anno){
  if ((1<=giorno) && (giorno<=28))
    return true;
  else
    //VALORE ED ANNO BISESTILE OK
    if ((giorno==29) && _bisestile(anno))
	  return true;
	else
	 //VALORE E MESE DI 30 G. OK
	  if((giorno<=30) && meseDi30(mese))
	    return true;
	  else
	  //VALORE E MESE DI 31 G. OK
	    if((giorno<=31) && meseDi31(mese))
	  	  return true; 
		else
		  return false;
}



//CONTROLLA I MESI DI 31 GIORNI
function meseDi31(mese){
  if ((mese==1) ||(mese==3) ||(mese==5) ||(mese==7) ||(mese==8) ||(mese==10) ||(mese==12))
    return true;
  else
    return false;
}



//CONTROLLA I MESI DI 3O GIORNI
function meseDi30(mese){
  if ((mese==4) ||(mese==6) ||(mese==9) ||(mese==11) )
    return true;
  else
    return false;
}



//CONTROLLA IL VALORE DEI MESI DA 1 A 12
function meseOk(mese){
  if ((1<=mese) && (mese<=12))
    return true;
  else
    return false;
}



//CONTROLLA IL VALORE DELL'ANNO(INTERVALLO TRA 1L 1940 ED IL 2039)
function annoOk(anno){
  if ((1940<=anno) && (anno<=2039))
    return true;
  else
    return false;
}



/****************************************************************************************************************
*  FUNZIONE IS_TIME:
*  VERIFICA LA CORRETTEZZA DI UN ORARIO. SI ACCETTANO SOLO ORARI NEL FORMATO HH MM SS,
*  OPPURE HH MM  (NEL CASO DI ORE O MINUTI <10 E' AMMESSA UNA SOLA CIFRA...CIOE' NON È NECESSARIO INSERIRE 
*  02:02 MA VA ANCHE BENE 2:02, 02:2 E 2:2. COME SEPARATORI SONO AMMESSI LO SPAZIO, ":" E "."
*  PER AGGIUNGERE SEPARATORI O ELIMINARNE ALCUNI E NECESSARIO MODIFICARE LA STRINGA TIMESEPARATORS A CUI VANNO
*  AGGIUNTI I NUOVI CARATTERI AMMESSI COME SEPARATORI O VANNO TOLTI I VECCHI CARATTERI CHE NON SI VUOLE PIU'
*  AMMETTERE COME SEPARTORI
*  SE L'ORARIO È CORRETTO VIENE SALVATO IL SUO VALORE NORMALIZZATO NORMALIZZATO (H:M:S)
*  NELLA VARIABILE GLOBALE NORMALIZEDVALUE
*****************************************************************************************************************
*  LA FUNZIONE is_time ACCETTA UN PARAMETRO STRINGA E RESTITUISCE TRUE O FALSE
****************************************************************************************************************/
function is_time(theValue){
	var timeSeparators  = ":. ";
	var theSeparator = "";
	var theSep;
	var hours;
  var minutes;
  var secs;
    	    
  normalizedValue=null;    

	// DETERMINAZIONE DEL SEPARATORE
	for (var i=0;i<timeSeparators.length;i++){
		var s = timeSeparators.charAt(i);
		if (theValue.indexOf(s)!=-1){
			theSeparator=s;
			break;
		}
	}
	// IL SEPARATORE NON PUÒ ESSERE ASSENTE
	if (theSeparator==""){ 
		return false;
	}
	var specialChar = "\\/.*+?|()[]{}";
	if (specialChar.indexOf(theSeparator)!=-1){
		//CARATTERE SPECIALE, DEVE ESSERE PRECEDUTO DA BACKSLASH NELL'ESPRESSIONE
		theSep = '\\'+theSeparator;
	}else{
		theSep = theSeparator;
	}
	
	
	//CONTROLLO CHE L'ORARIO NON CONTENGA VALORI DIVERSI DA CIFRE E SEPARATORE
	//STRINGA X LA COSTRUZIONE DELL'ESPRESSIONE REGOLARE
	var appo = "([^\\d"+theSep +"])"; 
	var pattern = new RegExp(appo);
	if(pattern.test(theValue)){
		// NELL'ORARIO IMMESSO C'È UN CARATTERE CHE NON È NE UNA CIFRA NE IL SEPARATORE AMMESSO.
		return false;
	}
	//ARRAY DETERMINATO DAI SEPARATORI
	var timeElements = theValue.split(theSeparator);
	//LUNGHEZZA CONCESSA AI SINGOLI ELEMENTI
	if (timeElements.length > 3 || timeElements.length < 2){
		return false;
	}
	//DEFINIZIONE PRIMO ELEMENTO
	if(timeElements[0]) {
		hours = timeElements[0];
	} else {
		return false;
	}
	//DEFINIZIONE PRIMO ELEMENTO
	if(timeElements[1]) {
		minutes = timeElements[1];
	} else {
		return false;
	}
	//DEFINIZIONE PRIMO ELEMENTO
	if(timeElements[1]) {
		secs = timeElements[2];
	} else {
		secs = null;
	}	
		
	//CONTROLLO ELEMENTI HOURS, MINUTES E SECS
	if (hours.length>2 || minutes.length>2 || (secs!=null && secs.length > 2)) return false;
	if (secs!=null && (secs < 0 || secs > 59)) return false;
	if (minutes < 0 || minutes >59) return false;
	if (hours < 0 || hours > 23) return false;
	
	// NESSUN ERRORE RISCONTRATO
	if (secs==null) secs="0";	

	//NORMALIZZAZIONE DEL TIME
	normalizedValue=hours+":"+minutes; //+":"+secs;
	return true	
}



/******************************************************************************************************
* 	SE IL DATETIME È CORRETTO VIENE SALVATO IL SUO VALORE È NORMALIZZATO PER LA DATA IN BASE AL 
*   VALORE DELLA _LOCAL_DATA MENTRE PER L'ORA IN H:M:S
*******************************************************************************************************
*  LA FUNZIONE is_time ACCETTA UN PARAMETRO STRINGA E RESTITUISCE TRUE O FALSE
******************************************************************************************************/	

function is_datetime(theValue){
	// UN TIPO DATETIME È UNA DATA, SEGUITA DA UNO SPAZIO, SEGUITA DA UN ORARIO
	
	//ARRAY DETERMINATO DA " "
	var theElements = theValue.split(" ");
	var date,time;
	normalizedValue=null;
	
	if (theElements.length==2){ 
		//LO SPAZIO È L'UNICO SEPARATORE PRESENTE, VIENE USATO PER SEPARARE LA DATA DALL'ORARIO
		date=theElements[0];
		time=theElements[1];
		
		//CONTROLLO CHE DATE SIA CORRETTO
		if(is_date(date)){
			var temp = normalizedValue;
			//CONTROLLO CHE TIME SIA CORRETTO
			if(is_time(time)){
				normalizedValue = temp +" "+ normalizedValue;
				return true;
			}		
		}
		return false;	
	}

	//EVENTUALI CASI DI SCRITTURA DEL VALORE DEL CAMPO 
	if (theElements.length == 3){
		//CASO: data h m
		date = theElements[0];
		var appo = theValue.indexOf(" ");
		time = theValue.substring(appo+1,theValue.length);

		if(is_date(date)){
			var temp = normalizedValue;
			if(is_time(time)){
				normalizedValue = temp +" "+ normalizedValue;
				return true;
			}		
		}
		return false;			
	}
	
	
  if (theElements.length == 4){
		//DUE POSSIBILI CASI: 
		// 	1) DATA H M S
		//	2) G M A TIME
		
		//SI SUPPONE SIA VERO IL CASO 1
		date = theElements[0];
		if (!is_date(date)){ 
			//CASO 1 FALSO O DATA SCORRETTA
			//SI SUPPONE SIA VERO IL CASO 2
			time=theElements[3];
			if (!is_time(time)){
				//CASO 2 FALSO O ORARIO SCORRETTO
				return false;
			}else{
				//TIME OK, SI MEMORIZZA LA VAR GLOBALE NORMALIZEDVALUE SETTATA DA IS_TIME IN UNA VAR LOCALE
				var normTime = normalizedValue; 
				var appo = theValue.lastIndexOf(" ");
				date = theValue.substring(0,appo);
				if (is_date(date)){
					normalizedValue +=" "+normTime;
					return true;
				}
				return false;	
			}
		}else{
			//CASO 1 VERO E DATA CORRETTA
			var appo = theValue.indexOf(" ");
			time=theValue.substring(appo+1,theValue.length);
			var normDate = normalizedValue; 
			
			if (is_time(time)){
					normalizedValue =normDate+" "+normalizedValue;
					return true;
			}
			return false;	
		}
	}
	
	if (theElements.length>4){
		//LO SPAZIO È IL SEPARATORE SIA PER LA DATA CHE PER L'ORARIO
		
		date = theElements[0]+" "+theElements[1]+" "+theElements[2];
		time = theElements[3]+" "+theElements[4];
		if (theElements[5]){
			time=time+" "+theElements[5];
		}

		if(is_date(date)){
			var temp = normalizedValue;
			if(is_time(time)){
				normalizedValue = temp +" "+ normalizedValue;
				return true;
			}		
		}
		return false;	
	}
}


										
//F U N Z I O N I     D I        U T I L I T A'				
												
 
//ELIMINAZIONE DEGLI SPAZI BIANCHI IN TESTA ED IN CODA
function _trimAll(theValue){
	//RITORNA IL VALORE PRIVATO DEGLI SPAZI IN TESTA O IN CODA OPPURE
	//LA STRINGA VUOTA NEL CASO IN CUI IL CAMPO SIA COSTITUITO SOLAMENTE DA SPAZI
	var result = theValue.replace(/^\s+/,"");
	result = result.replace(/\s+$/,"");
	return result;
}



/*******************************************************************************************************************
*	LA FUNZIONE VALIDATEALL CONTROLLA TUTTI GLI ELEMENTI DELLA FORM RICEVUTA COME PARAMETRO E RITORNA TRUE SOLO
*	SE NESSUN ELEMENTO DELLA FORM HA CAUSATO ERRORE. QUESTA FUNZIONE CHIAMA LA VALIDATE(THEFIELD) SU CIASCUN CAMPO
*	DELLA FORM.
*******************************************************************************************************************/
function validateAll(theForm){
	var noError=true; 
	for (var i=0;i<theForm.elements.length;i++){
		//VIENE CHIAMATA LA VALIDATE SU OGNI ELEMENTO , IN MODO CHE VENGANO CONTROLLATI TUTTI 
		//I CAMPI E SETTATI GLI OPPORTUNI ATTRIBUTI
		
		var result = validate(theForm.elements[i]);
		
		if (noError){
			//NEL CASO IN CUI NON CI SIANO STATI ERRORI FINO A QUESTO MOMENTO, IL VALORE 
			//DI NOERROR VIENE AGGIORNATO CON IL RISULTATO DEL SUCCESSIOVO CONTROLLO
			//QUANDO NOERROR DIVENTA FALSE NON VIENE PIÙ MODIFICATO.
			noError=result;
		}
			
	}
	return noError;
}



 /*********************************************************************************************************************************** 
 * FUNZIONE VALIDATE: 
 * CONTROLLA IL CAMPO DEL FORM RICEVUTO COME PARAMETRO.SE IL CAMPO NON È "TEXT","TEXTAREA","RADIO","CHECKBOX" E "SELECT" LA FUNZIONE 
 * RITORNA SEMPRE TRUE.A SECONDA DEL TIPO DI CAMPO LA FUNZIONE SI COMPORTERÀ DIVERSAMENTE NELL'ANALISI DELL'OBBLIGARIETÀ DEL CAMPO.
 *  
 * SE DATATYPE NON È DEFINITO CONTROLLA L'OBBLIGATORIETÀ DEL CAMPO,ED INFINE SE IL DATATYPE È DEFINITO CONTROLLA SIA L'OBBLIGATORIETÀ
 * SIA LA VALIDITÀ DELL'INPUT RISPETTO AL TIPO DI DATO.
 ************************************************************************************************************************************/
function validate(theField){

	// FUNZIONE DI CONTROLLO CHE ELIMINA L'EVENTUALE ATTRIBUTO "dataType" SU UNA TEXTAREA
	// QUESTO E' DOVUTO AL FATTO CHE SU UNA TEXTAREA IL CONTENUTO DEL CAMPO DEVE ESSERE
	// ESTRATTO CON TEXTAREA.TEXT E NON CON FIELD.VALUE (COME PER TUTTI GLI ALTRI CAMPI)
	if(theField.type.toUpperCase()=="TEXTAREA") { theField.removeAttribute('dataType');	}

	
	//VARIABILI CHE RIGUARDANO GLI ATTRIBUTI DEL CAMPO 
	//(I TAG ALL'INTERNO DEGLI ELEMENTI DEL FORM)  
	var theValue=theField.value;
	errorMsg = theField.errorMsg; 
	var required;
	var dataType;
	lastOkValue = theField._lastOkValue;
	lastCheckedValue = theField._lastCheckedValue;
	
	
	// SE IL CAMPO CHE STO ANALIZZANDO FA PARTE DI UN GRUPPO DI ELEMENTI (STESSO NOME)
	// ALLORA GLI ATTRIBUTI "REQUIRED" E "DATATYPE" LI ESTRAGGO SOLO SEMPRE DAL PRIMO ELEMENTO.
	// TROVO IL NOME DELL'ELEMENTO CORRENTE
	var elementName = theField.name;
	// ESTRAGGO GLI ELEMENTI DAL NOME PER VERIFICARE SE FANNO PARTE DI UN GRUPPO O NO.
	var elementGroup = eval("theField.form.elements['" + elementName + "']");

  theType = theField.type;
  
	// SE L'ELEMENTO FA PARTE DI UN GRUPPO (STESSO NOME)
	if (elementGroup && (elementGroup.length>1)) {
		
		  //ESTRAZIONE ATTRIBUTI DEGLI ELEMENTI PER GRUPPO SELECT
		  //NELLA SELECT GLI ELEMENTI SONO I VARI OPTIONS
			if(theType.substring(0,6).toUpperCase()!="SELECT") {
				required = elementGroup[0].getAttribute('required');
				dataType = elementGroup[0].getAttribute('dataType');	    
			} else {
				//CONTROLLO ATTRIBUTI DEGLI ELEMENTI PER GLI ALTRI GRUPPI 
				required = elementGroup.getAttribute('required');
				dataType = elementGroup.getAttribute('dataType');	    
			}
	} else {
		//ESTRAZIONE ATTRIBUTI SE L'ELEMENTO NON FA PARTE DI UN GRUPPO 
		required = theField.getAttribute('required');
		dataType = theField.getAttribute('dataType');	    
	}		
	
	//SE IL CAMPO NON È DI TIPO "TEXT","TEXTAREA","RADIO", "CHECKBOX", "SELECT-ONE" E "SELECT-MULTIPLE" RITORNA SEMPRE TRUE
	if ((theType.toUpperCase()!="TEXT")&&(theType.toUpperCase()!="TEXTAREA")&&(theType.toUpperCase()!="RADIO")&&(theType.toUpperCase()!="CHECKBOX")&&(theType.toUpperCase()!="FILE")&&(theType.toUpperCase()!="SELECT-ONE")&&(theType.toUpperCase()!="SELECT-MULTIPLE")) {
		return true;	
	}
	
  //SE IL CAMPO È DI TIPO "SELECT"
	if(theType.substring(0,6).toUpperCase()=="SELECT") {
		
		//INIZIALIZZO IL VALORE DEL CAMPO (SELECT) UGUALE AD ""
		theValue="";
		//CICLO ALL'INTERNO DEGLI OPTIONS DELLA SELECT PER TROVARE SE È SELEZIONATO UN VALORE
		for (var k=0; k<theField.options.length; k++) {
			if(theField.options[k].selected) {
				//PONGO IL VALORE DEL CAMPO (SELECT) UGUALE AL VALORE DELL'OPTIONS
				theValue += theField.options[k].value;
			}
		}
	}
	
  //SE IL CAMPO È DI TIPO "RADIO"
	if (theType.toUpperCase()=="RADIO") {
		//CONTROLLO L'OBBLIGATORIETÀ    
		if (!required || (required.toUpperCase()=="FALSE")) {
			return true;
		}
		//INIZIALIZZO LA VARIABILE DELLO STATO DEI RADIO 
		var radioState = false;
   //CICLO PER VEDERE SE ALMENO UN "RADIO" È CECCATO, SE È CECCATO ESCO 
	  for(var i=0; i<elementGroup.length; i++){
			if(elementGroup[i].checked) {
				radioState = true;
				break;
			}
		}
		 
		if(!radioState) {
			  //SETTO SE È PRESENTE L'ATTRIBUTO ERRORMSG E CHIAMO LA FUNZIONE CHE RAPPRESENTA GLI ERRORI
			  //CONTROLLO SUL PRIMO ELEMENTO DEL GRUPPO 
				elementGroup[0].setAttribute("errorMsg",_ERROR_MSG_REQUIRED_FIELD_VOID);
				//RAPPRESENTAZIONE ERRORI
				_displayError(elementGroup[0]);
			return false;
		}else{ 
			// CAMPO VUOTO E NON OBBLIGATORIO 
			//SE ERA PRESENTE L'ATTRIBUTO ERRORMSG VIENE RIMOSSO
			elementGroup[0].removeAttribute("errorMsg");
			//RAPPRESENTAZIONE ERRORI
			_displayError(elementGroup[0]);
			
			return true;			
		}
	}	



  //SE IL CAMPO È DI TIPO "CHECKBOX"
	if (theType.toUpperCase()=="CHECKBOX") {
		//CONTROLLO L'OBBLIGATORIETÀ
		if (!required || (required.toUpperCase()=="FALSE")) {
			return true;
		}
		//INIZIALIZZO LA VARIABILE DELLO STATO DEI CHECKBOX
		var checkState = false;
    //SE È PRESENTE UN GRUPPO DI "CHECKBOX" CICLO PER VEDERE SE ALMENO UNO È CECCATO
    //SE È CECCATO ESCO
		if(elementGroup.length) {
		  for(var i=0; i<elementGroup.length; i++){
				if(elementGroup[i].checked) {
					checkState = true;
					break;
				}
			}
		} else {
			//SE È PRESENTE UN SOLO "CHECKBOX"
			if(theField.checked) {
				checkState = true;
			}
		}
		
		
		if(!checkState) {
			//SETTO SE È PRESENTE L'ATTRIBUTO ERRORMSG E CHIAMO LA FUNZIONE CHE RAPPRESENTA GLI ERRORI
			//SE È PRESENTE UN GRUPPO DI "CHECKBOX" CONTROLLO SUL PRIMO ELEMENTO
			if(elementGroup.length) {
				elementGroup[0].setAttribute("errorMsg",_ERROR_MSG_REQUIRED_FIELD_VOID);
				//RAPPRESENTAZIONE ERRORI
				_displayError(elementGroup[0]);
				
			} else {
				//SE È PRESENTE UN SOLO "CHECKBOX"
				theField.setAttribute("errorMsg",_ERROR_MSG_REQUIRED_FIELD_VOID);
				//RAPPRESENTAZIONE ERRORI
				_displayError(theField);
				
			}
			return false;
		}else{ 
			// CAMPO VUOTO E NON OBBLIGATORIO
			//SE ERA PRESENTE L'ATTRIBUTO ERRORMSG VIENE RIMOSSO
			//SE È PRESENTE UN GRUPPO DI "CHECKBOX" CONTROLLO SUL PRIMO ELEMENTO
			if(elementGroup.length) {
				elementGroup[0].removeAttribute("errorMsg");
				//RAPPRESENTAZIONE ERRORI
				_displayError(elementGroup[0]);
			} else {
				//SE È PRESENTE UN SOLO "CHEKBOX"
				theField.removeAttribute("errorMsg");	
				//RAPPRESENTAZIONE ERRORI
				_displayError(theField);
			}
			
			return true;			
		}
	}	

	

	//SE IL VALORE DEL CAMPO È DEFINITO, ELIMINO GLI SPAZI VUOTI IN TESTA E/O IN CODA
	if (theValue){
		//VIENE RICHIAMATA LA FUNZIONE CHE ELIMINA GLI SPAZI(GLI PASSO IL VALORE DEL CAMPO)
		theValue=_trimAll(theValue);
		theField.value=theValue;
	}


	// DATATYPE NON DEFINITO: VIENE ESEGUITO SOLO IL CONTROLLO DI OBBLIGATORIETÀ. 
	// L'UNICO ATTRIBUTO 'USER DEFINED'USATO IN QUESTO CASO È ERRORMSG.
	if (!dataType){
		if (!theValue){
			 
      //CONTROLLO L'OBBLIGARIETÀ DEL CAMPO:ATTRIBUTO REQUIRED DEFINITO È TRUE
			if (required && (required.toUpperCase()=="TRUE")){ 	
				theField.setAttribute("errorMsg",_ERROR_MSG_REQUIRED_FIELD_VOID);
				//RAPPRESENTAZIONE ERRORI
				_displayError(theField);
				return false;
				
			}else{
			 	// CAMPO VUOTO MA NON OBBLIGATORIO (REQUIRED O NON DEFINITO O FALSE):
				// RIMOZIONE IN CASO DI PRESENZA  DEL MESSAGGIO DI ERRORE  
				theField.removeAttribute("errorMsg");	 
         //RAPPRESENTAZIONE ERRORI
				_displayError(theField);
				return true;
			}
		}else{ 
		 //DATATYPE NON DEFINITO, MA CAMPO NON VUOTO
		//SE ERA PRESENTE L'ATTRIBUTO ERRORMSG VIENE RIMOSSO
			theField.removeAttribute("errorMsg");
			//RAPPRESENTAZIONE ERRORI
			_displayError(theField);
			return true;
		}	
	}
 
 	
	// DATATYPE DEFINITO E VALORE DEL CAMPO UNDEFINED: CONTROLLO DI OBBLIGATORIETÀ. 
	if (!theValue){
		//CONTROLLO L'OBBLIGARIETÀ DEL CAMPO:ATTRIBUTO REQUIRED DEFINITO È TRUE
		if (required && (required.toUpperCase()=="TRUE")){
			//SETTO L'ATTRIBUTO ERRORMSG 
			theField.setAttribute("errorMsg",_ERROR_MSG_REQUIRED_FIELD_VOID);
			//RAPPRESENTAZIONE ERRORI
			_displayError(theField);
			return false;
		}else{ 
		  // CAMPO VUOTO MA NON OBBLIGATORIO (REQUIRED O NON DEFINITO O FALSE):		
			//IL VALORE 'VUOTO' IN QUESTO CASO È CORRETTO, E VIENE IMPOSTATO COME LASTOKVALUE
			
			theField.setAttribute("_lastOkValue",theValue);
			//SE ERA PRESENTE L'ATTRIBUTO ERRORMSG VIENE RIMOSSO	
			theField.removeAttribute("errorMsg"); 
			//RAPPRESENTAZIONE ERRORI
			_displayError(theField);
			return true;
		}
	}
	

	// SI VERIFICA SE IL VALORE DEL CAMPO È GIÀ STATO CONTROLLATO ED È RISULTATO CORRETTO
	if(theValue==lastOkValue){
		// ES: È STATO INSERITO UN VALORE CORRETTO CHE È STATO VALIDATO, POI UNO ERRATO E CONTROLLATO.
		// SE VIENE INSERITO DI NUOVO IL VALORE CORRETTO NON SI RIPETE IL CONTROLLO
		
		lastCheckedValue = theValue;
		//SE IL MESSAGGIO DI ERRORE ERA SETTATO, LO RIMUOVO
		theField.removeAttribute("errorMsg");
		//RAPPRESENTAZIONE ERRORI		
		_displayError(theField);
		return true;
	} 
	
	// QUI RISULTA thevalue != lastokvalue
	if(theValue==lastCheckedValue){
		// IL VALORE È GIA' STATO CONTROLLATO E POICHÈ È DIVERSO DA LASTVALUEOK È UN VALORE ERRATO.
		// I VARI ATTRIBUTI SONO GIA' STATI SETTATI DAL PRECEDENTE CONTROLLO, OCCORRE SOLAMENTE RITORNARE FALSE.
		//RAPPRESENTAZIONE ERRORI
		_displayError(theField);
		return false;
	}
	

  /*****************************************
	*	CONTROLLO DI VALIDITA' DEL CAMPO	
	*****************************************/	
	theField.setAttribute("_lastCheckedValue",theValue);
	
	
	/**********************************************************************************
	* SE LA FUNZIONE È INESISTENTE SI LASCIA CHE IL BROWSER DIA UN ERRORE JAVASCRIPT
	* L'ERRORE GENERATO IN QUEL CASO È: 'ERRORE, PREVISTO OGGETTO'
	**********************************************************************************/

	var functionName = eval("is_"+dataType.toLowerCase());
	
	if(!functionName(theValue)){ 
		//LA FUNZIONE HA RITORNATO FALSE
		//SETTO L'ATTRIBUTO ERRORMSG
		theField.setAttribute("errorMsg",_ERROR_MSG_NOT_VALID_VALUE);
		_displayError(theField);
		return false;
	} else {
		theField.value=normalizedValue;
	}
	
	
	// NESSUN ERRORE RISCONTRATO
	theField.setAttribute("_lastOkValue",theValue);
	//SE IL MESSAGGIO DI ERRORE ERA SETTATO, LO RIMUOVO
	theField.removeAttribute("errorMsg");
	//RAPPRESENTAZIONE ERRORI			
	_displayError(theField);
	return true;
}



//DETERMINA LA RAPPRESENTAZIONE GRAFICA DEL MSG SIA IN ERRORE CHE CORRETTO(GLI SI PASSA IL CAMPO)
function _displayError(theField) {
	// NOME DELL'IMMAGINE 
	var errorFieldName = theField.name + "_err";
	var tmp_img = new Image();
	eval("tmp_img = document.images['" + errorFieldName + "']");
	//VARIABILE RESTITUISCE L'IMMAGINE SE È PRESENTE NEL FORM
	var imagePresent = eval("tmp_img = document.images['" + errorFieldName + "']");
	
	
  //SE L'ATTRIBUTO ERRORMSG È PRESENTE
	if (theField.getAttribute('errorMsg')) {
		//SE L'IMMAGINE È PRESENTE VIENE CARICA L'IMG_ERROR E SETTATO ERRORMSG COL MESSAGGIO IDONEO
		if(imagePresent) {
				tmp_img.src = KO_IMAGE;
				tmp_img.setAttribute("errorMsg",theField.getAttribute('errorMsg'));
				tmp_img.setAttribute("alt",theField.getAttribute('errorMsg'));
				
				// AI "RADIO" E "CHECKBOX" VIENE ESCLUSO LO STYLE_ERROR
				if((theField.type != "checkbox")&&(theField.type != "radio")) {
					theField.className = _ERR_STYLE;
				}
			} else {
				//IN CASO DI ASSENZA O NOME ERRATO DELL'IMMAGINE IL MSG D'ERRORE VIENE POSIZIONATO SUL TITLE DEL CAMPO 
		    theField.setAttribute("title",theField.getAttribute('errorMsg'));
		    
		    // AI "RADIO" E "CHECKBOX" VIENE ESCLUSO LO STYLE_ERROR
				if((theField.type != "checkbox")&&(theField.type != "radio")) {
			    theField.className = _ERR_STYLE;
			  }
			}
				
	}else{
	  //IN CASO DI NON ERRORE
		//SE L'IMMAGINE È PRESENTE VIENE CARICA L'IMG_CORRETTA E RIMOSSO ERRORMSG 
		if(imagePresent) {
			tmp_img.src = OK_IMAGE;
			tmp_img.removeAttribute("errorMsg");
		} else {
			//IN CASO DI ASSENZA O NOME ERRATO DELL'IMMAGINE VIENE RIMOSSO ERRORMSG DAL TITLE DEL CAMPO
	    theField.removeAttribute("title");
		}
		// AI "RADIO" E "CHECBOX" VIENE ESCLUSO LO STYLE_CORRETTO
		if((theField.type != "checkbox")&&(theField.type != "radio")) {
			theField.className = _OK_STYLE;
		}
	}
	
}



//SI DETERMINA LA VISUALIZZAZIONE SCRITTA DELL'ERRORE 
//QUESTA FUNZIONE VIENE RICHIAMATA SUL ONMOUSEOVER DELL'IMMAGINE D'ERRORE
function helpMessage(fieldImage) {
	if(fieldImage.getAttribute("errorMsg")) {
		var err_str = fieldImage.getAttribute("errorMsg");
		fieldImage.setAttribute("alt", err_str);
	}
}


