/*
 
required
req  The field should not be empty  

date  Data DD/MM/YYYY
time  Ora HH:MI

piva     Verifica la correttezza formale di una partita iva

codfisc  Verifica la correttezza formale di un codice fiscale 

nospace  Verifica che non ci siano spazi nella stringa (ad es in una password)

ip       Verifica che sia un indirizzo ip valido

maxlen=???
maxlength=???  checks the length entered data to the maximum. For example, if the maximum size permitted is 25, give the validation descriptor as "maxlen=25"  

minlen=???
minlength=???  checks the length of the entered string to the required minimum. example "minlen=5"  

alphanumeric /
alnum  Check the data if it contains any other characters other than alphabetic or numeric characters  

alnumhyphen   Check the data if it contains any other characters other than alphabetic (included '-' and '_') or numeric characters

num 
numeric  Check numeric data  

alpha 
alphabetic  Check alphabetic data.  

email  The field is an email field and verify the validity of the data.  

lt=???
lessthan=???  Verify the data to be less than the value passed. Valid only for numeric fields. 
example: if the value should be less than 1000 give validation description as "lt=1000"  

gt=???
greaterthan=???  Verify the data to be greater than the value passed. Valid only for numeric fields. 
example: if the value should be greater than 10 give validation description as "gt=10"  

regexp=???  Check with a regular expression the value should match the regular expression.
example: "regexp=^[A-Za-z]{1,20}$" allow up to 20 alphabetic characters.  

regexpwithmessage=???  Check with a regular expression the value should match the regular expression (con messaggio personalizzato).
example: "regexp=^[A-Za-z]{1,20}$" allow up to 20 alphabetic characters. 


dontselect=??  This validation descriptor is valid only for select input items (lists) Normally, the select list boxes will have one item saying 'Select One' or some thing like that. The user should select an option other than this option. If the index of this option is 0, the validation description should be "dontselect=0"



*/  

function Validator(frmname)
{
  this.formobj=document.forms[frmname];
	if(!this.formobj)
	{
	  alert("BUG: Impossibile referenziare l'oggetto FORM "+frmname);
		return;
	}
	if(this.formobj.onsubmit)
	{
	 this.formobj.old_onsubmit = this.formobj.onsubmit;
	 this.formobj.onsubmit=null;
	}
	else
	{
	 this.formobj.old_onsubmit = null;
	}
	this.formobj.onsubmit=form_submit_handler;
	this.addValidation = add_validation;
	this.setAddnlValidationFunction=set_addnl_vfunction;
	this.clearAllValidations = clear_all_validations;
}

function set_addnl_vfunction(functionname)
{
  this.formobj.addnlvalidation = functionname;
}

function clear_all_validations()
{
	for(var itr=0;itr < this.formobj.elements.length;itr++)
	{
		this.formobj.elements[itr].validationset = null;
	}
}

function form_submit_handler()
{
	for(var itr=0;itr < this.elements.length;itr++)
	{
		if(this.elements[itr].validationset &&
	   !this.elements[itr].validationset.validate())
		{
		  return false;
		}
	}
	if(this.addnlvalidation)
	{
	  str =" var ret = "+this.addnlvalidation+"()";
	  eval(str);
    if(!ret) return ret;
	}
	return true;
}

function add_validation(itemname,descname,descriptor)
{
  if(!this.formobj)
	{
	  alert("BUG: l'oggetto FORM non è settato correttamente");
		return;
	}//if
	var itemobj = this.formobj[itemname];
  if(!itemobj)
	{
	  alert("BUG: Impossibile referenziare l'input "+itemname);
		return;
	}
	if(!itemobj.validationset)
	{
	  itemobj.validationset = new ValidationSet(itemobj);
	}
  itemobj.validationset.add(descriptor,descname);
}

function ValidationDesc(inputitem,desc,error)
{
  this.desc=desc;
	this.error=error;
	this.itemobj = inputitem;
	this.validate=vdesc_validate;
}

function vdesc_validate()
{
 if(!V2validateData(this.desc,this.itemobj,this.error))
 {
    this.itemobj.focus();
		return false;
 }
 return true;
}

function ValidationSet(inputitem)
{
    this.vSet=new Array();
	this.add= add_validationdesc;
	this.validate= vset_validate;
	this.itemobj = inputitem;
}

function add_validationdesc(desc,error)
{
  this.vSet[this.vSet.length]= 
	  new ValidationDesc(this.itemobj,desc,error);
}

function vset_validate()
{
   for(var itr=0;itr<this.vSet.length;itr++)
	 {
	   if(!this.vSet[itr].validate())
		 {
		   return false;
		 }
	 }
	 return true;
}

function validateTime(time) {
	
	if (time.length<=0) {
		return true;
	}
	
	re = /^(\d{1,2}):(\d{2})([ap]m)?$/;

	if(time != '') {
		if(time.length < 6) {
			if(regs == time.match(re)) {
				if(regs[3]) {
					if(regs[1] < 1 || regs[1] > 12) {
						return false;
		      }
				} else {
					if(regs[1] > 23) {
						return false;      
					}
		    }
				if(regs[2] > 59) {
					return false;      
				}
			} else {
				return false;
			}
		} else { 
			return false;
		}
	}

return true;

}

function validateDate(date)
{
    if(date.length <= 0)
	{
	  return true;
	}
  var data = date; 
  if (data.length > 0) { 
    var ok = true; 
    var first = false; 
    var second = false; 
    var g = 0; 
    var m = 0; 
    var giorno; 
    var mese; 
    var anno; 
    for(i=0;i<data.length;i++) { 
      if (data.charAt(i) != '/' && (data.charAt(i) < '0') || (data.charAt(i) > '9')) ok = false; 
    } 
    if (!ok){
      return false;
    }
    for(i=0;i<data.length;i++) { 
      if (data.charAt(i) == '/' && !first) {; 
        first = true;
        g = i;
      } 
      else if (data.charAt(i) == '/' && first) { 
        second = true;
        m = i;
      } 
    } 
    if (!first || !second) ok = false; 
    if (!ok){
      return false;
    }
    giorno = data.substring(0,g); 
    mese   = data.substring(g+1,m); 
    anno   = data.substring(m+1,data.length); 
    if (anno < 1000) ok = false;     
    if (mese < 1 || mese > 12) ok = false;     
    if (giorno < 1 || giorno > 31) ok = false; 
    if (giorno > 30 && mese == 4) ok = false; 
    if (giorno > 30 && mese == 6) ok = false; 
    if (giorno > 30 && mese == 9) ok = false; 
    if (giorno > 30 && mese == 11) ok = false; 
    if (giorno > 29 && mese == 2) ok = false; 
    if (giorno == 29 && mese == 2) {
      if (anno % 4 == 0) {
        if (anno % 100 == 0) { 
          if (anno % 400 != 0) ok = false; 
        }
      }
      else ok = false;
    } 
    if (!ok){
      return false;
    }
  }
  return true;

}

function validateEmailv2(email)
{
// a very simple email validation checking. 
// you can add more complex email checking if it helps 
    if(email.length <= 0)
	{
	  return true;
	}
    var splitted = email.match("^(.+)@(.+)$");
    if(splitted == null) return false;
    if(splitted[1] != null )
    {
      var regexp_user=/^\"?[\w-_\.]*\"?$/;
      if(splitted[1].match(regexp_user) == null) return false;
    }
    if(splitted[2] != null)
    {
      var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
      if(splitted[2].match(regexp_domain) == null) 
      {
	    var regexp_ip =/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
	    if(splitted[2].match(regexp_ip) == null) return false;
      }// if
      return true;
    }
return false;
}

function validateEmailv3(email) {
	if (email.length<=0) {
		return true;
	}
	var regex = /^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$/;
	if (!regex.test(email.toUpperCase())) {
		regex = /^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
		var splittedEmail = email.split('@');
		if (!(regex.test(email.toUpperCase()) && validateIP(splittedEmail[1]))) {
			return false;
		}
	}
	
	return true;
}

function V2validateData(strValidateStr,objValue,strObjDescr) 
{ 
    var  epos = strValidateStr.search("="); 
    var  command  = ""; 
    var  cmdvalue = ""; 
    var  strError;
    if(epos >= 0) 
    { 
     command  = strValidateStr.substring(0,epos); 
     cmdvalue = strValidateStr.substr(epos+1); 
    } 
    else 
    { 
     command = strValidateStr; 
    } 
    switch(command) 
    { 
        case "req": 
        case "required": 
         {            
             if (eval(objValue.type != 'select-multiple'))                
             {  //caso text item                
                 if(strTrim(objValue.value) == "") 
                 { 
                 strError = "Il campo '" + strObjDescr + "' è obbligatorio"; 
                 alert(strError); 
                 return false; 
           	     } 
              } 
              else
              { //caso combo item
               if(eval(objValue.length) == 0) 
                 { 
	              strError = "E' necessario selezionare almeno un valore per la lista '" + strObjDescr + "'"; 
	              alert(strError); 
	              return false; 
	             }
              }              
                       
           break;             
         }//case required 
        case "maxlength": 
        case "maxlen": 
          { 
             if(eval(objValue.value.length) >  eval(cmdvalue)) 
             { 
               strError = "Il campo '" + strObjDescr + "' può contenere al massimo " + cmdvalue +" caratteri"; 
               alert(strError + "\n[Attualmente è lungo " + objValue.value.length + " caratteri]"); 
               return false; 
             }//if 
             break; 
          }//case maxlen 
        case "minlength": 
        case "minlen": 
           { 
             if(eval(objValue.value.length) <  eval(cmdvalue)) 
             { 
               strError = "Il campo " + strObjDescr + " deve essere minimo " + cmdvalue + " caratteri"; 
               alert(strError); 
               return false;                 
             }//if 
             break; 
            }//case minlen 
        case "alnum": 
        case "alphanumeric": 
           { 
              var charpos = objValue.value.search("[^A-Za-z0-9]"); 
              if(objValue.value.length > 0 &&  charpos >= 0) 
              { 
                strError = "Nel campo '" + strObjDescr +"' Sono ammessi solo caratteri alfanumerici"; 
                alert(strError); 
                return false; 
              }//if 
              break; 
           }//case alphanumeric 
        case "num": 
        case "numeric": 
           { 
              var charpos = objValue.value.search("[^0-9]"); 
              if(objValue.value.length > 0 &&  charpos >= 0) 
              { 
                strError = "Il campo '" + strObjDescr + "' può contenere solo caratteri numerici"; 
                alert(strError + "\n [E' presente una discrepanza nel carattere n." + eval(charpos+1)+"]"); 
                return false; 
              }//if 
              break;               
           }//numeric 
        case "alphabetic": 
        case "alpha": 
           { 
              var charpos = objValue.value.search("[^A-Za-z]"); 
              if(objValue.value.length > 0 &&  charpos >= 0) 
              { 
                strError = "Il campo '" + strObjDescr + "' può contenere solo caratteri alfabetici";                          
                alert(strError + "\n [E' presente una discrepanza nel carattere n." + eval(charpos+1)+"]");
                return false; 
              }//if 
              break; 
           }//alpha 
		case "alnumhyphen":
			{
              var charpos = objValue.value.search("[^A-Za-z0-9\-_]"); 
              if(objValue.value.length > 0 &&  charpos >= 0) 
              { 
                strError = "Il campo '" + strObjDescr + "' può contenere solo caratteri alfabetici (inclusi '-' e '_') o numerici";      
                alert(strError + "\n [E' presente una discrepanza nel carattere n." + eval(charpos+1)+"]");
                return false; 
              }//if 			
			break;
			}
        case "email": 
          { 
               if(!validateEmailv3(objValue.value)) 
               { 
                 strError = "L'indirizzo E-mail immesso nel campo '" + strObjDescr + "' non è valido";                                              
                 alert(strError); 
                 return false; 
               }//if 
           break; 
          }//case email
        case "date": 
          { 
               if(!validateDate(objValue.value)) 
               { 
                 strError = "Il formato della data nel campo '" + strObjDescr +"' deve essere DD/MM/YYYY";                        
                 alert(strError); 
                 return false; 
               }//if 
           break; 
          }//case date 
        case "time": 
          { 
               if(!validateTime(objValue.value)) 
               { 
                 strError = "Il formato dell'ora nel campo '" + strObjDescr +"' deve essere HH:MI";                        
                 alert(strError); 
                 return false; 
               }//if 
           break; 
          }//case time 
          
          
        case "lt": 
        case "lessthan": 
         { 
            if(isNaN(objValue.value)) 
            { 
              alert("Il campo '" + strObjDescr +"' deve essere un numero"); 
              return false; 
            }//if 
            if(eval(objValue.value) >=  eval(cmdvalue)) 
            { 
              strError = "Il valore del campo '" + strObjDescr + "' deve essere minore di "+ cmdvalue;             
              alert(strError); 
              return false;                 
             }//if             
            break; 
         }//case lessthan 
        case "gt": 
        case "greaterthan": 
         { 
            if(isNaN(objValue.value)) 
            { 
              alert("Il campo '" + strObjDescr +"' deve essere un numero"); 
              return false; 
            }//if 
             if(eval(objValue.value) <=  eval(cmdvalue)) 
             { 
               strError = "Il valore del campo " + strObjDescr + " deve essere maggiore di "+ cmdvalue;            
               alert(strError); 
               return false;                 
             }//if             
            break; 
         }//case greaterthan 
        case "regexp": 
         { 
		 	if(objValue.value.length > 0)
			{
	            if(!objValue.value.match(cmdvalue)) 
	            { 
	              strError = "Nel campo '" + strObjDescr +"' è stato immesso un carattere non valido";                                    
	              alert(strError); 
	              return false;                   
	            }//if 
			}
           break; 
         }//case regexp 
        case "regexpwithmessage": 
         { 
		 	if(objValue.value.length > 0)
			{
	            if(!objValue.value.match(cmdvalue)) 
	            { 
	              strError = strObjDescr;                                    
	              alert(strError); 
	              return false;                   
	            }//if 
			}
           break; 
         }//case regexp 
        case "dontselect": 
         { 
            if(objValue.selectedIndex == null) 
            { 
              alert("BUG: dontselect command for non-select Item"); 
              return false; 
            } 
            if(objValue.selectedIndex == eval(cmdvalue)) 
            { 
              strError = "Selezionare un valore nella lista '" + strObjDescr +"' ";                                      
              alert(strError); 
              return false;                                   
             } 
             break; 
         }//case dontselect
        case "codfisc":
        	if(!validateCodFisc(objValue.value)) { 
                 strError = "Il Codice Fiscale inserito nel campo " + strObjDescr + " non è valido";                        
                 alert(strError); 
                 return false; 
               }//codfisc 
        	break; 
        case "piva":
        	if(!validatePIVA(objValue.value)) { 
                 strError = "La Partita IVA inserita nel campo " + strObjDescr + " non è valida";                        
                 alert(strError); 
                 return false; 
               }//piva 
        	break; 
        case "nospace":
        	regex = /\s/;
        	if(regex.test(objValue.value)) { 
                 strError = "Nel campo " + strObjDescr + " non sono ammessi spazi";                        
                 alert(strError); 
                 return false; 
               }//nospace 
        	break; 
        case "ip":
        	if(!validateIP(objValue.value)) { 
                 strError = "L'indirizzo ip immesso nel campo " + strObjDescr + " non è valido";                        
                 alert(strError); 
                 return false; 
               }//ip 
        	break;
                                            
    }//switch 
    return true; 
}

function validateCodFisc(codFisc) {
	var codiceFiscale = codFisc.toUpperCase();
	var codiceFiscaleNoOmocodia = codFisc.toUpperCase();
	var omocodiaChars = 'LMNPQRSTUV';
	var omocodiaIndex = 0;
	var alphanumericChars = '0123456789ABCDEFGHIKJLMNOPQRSTUVWXYZ';
	var alphabeticChars = 'ABCDEFGHIKJLMNOPQRSTUVWXYZ';
	var transformOddChars = new Array(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25);
	var transformEvenChars = new Array(1,0,5,7,9,13,15,17,19,21,1,0,5,7,9,13,15,17,19,21,2,4,18,20,11,3,6,8,12,14,16,10,22,25,24,23);
	var transformRemainderChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
	var sum = 0;
	
	if (codiceFiscale.length<=0) {
		return true;
	}
	
	//normalizzo il codice fiscale rimuovendo le eventuali omocodie
	for (var i=14;i>5;i--) {
		if (i==11 || i==8) {
			continue;
		}
		omocodiaIndex = omocodiaChars.indexOf(codiceFiscale.charAt(i));
		if (omocodiaIndex!=-1) {
			codiceFiscaleNoOmocodia = codiceFiscaleNoOmocodia.substring(0,i) + omocodiaIndex.toString() + codiceFiscaleNoOmocodia.substring(i+1);
		} else {
			break;
		}
	}
	
	var regexp = /^[A-Z]{6}[0-9]{2}[ABCDEHLMPRST]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$/;
	if (!regexp.test(codiceFiscaleNoOmocodia)) {
		return false;
	}
	
	//controllo che il giorno sia coerente con il mese
	var day = parseInt(codiceFiscaleNoOmocodia.substring(9,11),10);
	var month = codiceFiscaleNoOmocodia.charAt(8);
	var year = parseInt(codiceFiscaleNoOmocodia.substring(6,8),10);
	switch (month) {
		//mesi di 30 giorni
		case 'D':
		case 'H':
		case 'P':
		case 'S':
			if (!((day>=1 && day<=30) || (day>=41 && day<=70))) {
				return false;
			}
			break;
		//mesi di 31 giorni
		case 'A':
		case 'C':
		case 'E':
		case 'L':
		case 'M':
		case 'R':
		case 'T':
			if (!((day>=1 && day<=31) || (day>=41 && day<=71))) {
				return false;
			}
			break;
		//febbraio, se bisestile di 29 giorni, altrimenti di 28 giorni
		case 'B':
			if ((year%4)==0) {
				if (!((day>=1 && day<=29) || (day>=41 && day<=69))) {
					return false;
				}
			} else {
				if (!((day>=1 && day<=28) || (day>=41 && day<=68))) {
					return false;
				}
			}
			break;
	}
	
	//controllo che il sedicesimo carattere (carattere di controllo) sia coerente con gli altri 15 caratteri
	//NOTA: il carattere di controllo deve essere coerente con il codice fiscale NON normalizzato
	//ciclo sui caratteri di posto dispari (parto da i=0 con passo 2, il che vuol dire il 1°, il 3° ecc)
	for (var i=0;i<15;i+=2) {
		sum += transformEvenChars[alphanumericChars.indexOf(codiceFiscale.charAt(i))];
	}
	//ciclo sui caratteri di posto pari (parto da i=1 con passo 2, il che vuol dire il 2°, il 4° ecc)
	for (var i=1;i<15;i+=2) {
		sum += transformOddChars[alphanumericChars.indexOf(codiceFiscale.charAt(i))];
	}
	
	return (codiceFiscale.charAt(15)==alphabeticChars.charAt(sum%26));
}

function validatePIVA(pIva) {
	if (pIva.length<=0) {
		return true;
	}
	
	var regex = /^\d{11}$/;
	if (!regex.test(pIva) || pIva=='00000000000') {
		return false;
	}
	
	var sum = 0;
	var currentNum = 0;
	
	for (var i=0;i<10;i+=2) {
		currentNum = parseInt(pIva.charAt(i),10);
		sum += currentNum;
	}
	
	for (var i=1;i<10;i+=2) {
		currentNum = parseInt(pIva.charAt(i),10)*2;
		sum += (currentNum<=9) ? currentNum : (currentNum-9);
	}
	
	return (((10 - sum%10)%10) == parseInt(pIva.charAt(10),10));
}


function validateIP(ip) {
	if (ip.length<=0) {
		return true;
	}
	
	var regex = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
	if (!regex.test(ip)) {
		return false;
	}
	
	var splittedIP = ip.split('\.');
	for (var i=0;i<4;i++) {
		if (parseInt(splittedIP[i],10)<0 || parseInt(splittedIP[i],10)>255) {
			return false;
		}
	}
	
	return true;
}


function strTrim(strInput) {
	var regexp = /^[\s\xA0]+|[\s\xA0]+$/g;
	return strInput.replace(regexp,"");
}

function strLeftTrim(strInput) {
	var regexp = /^[\s\xA0]+/g;
	return strInput.replace(regexp,"");
}

function strRightTrim(strInput) { 
	var regexp = /[\s\xA0]+$/g;
	return strInput.replace(regexp,"");
}

