 /*********************************************************************
multi-language validation script
	version 2.21
	by matthew frank
*********************************************************************/


// ************************************************** Beginning of New Functions  (SGO Cuba) **********************************************************************

/*====================================================================
Function: isEmail 
Purpose:  It determines if it is a valid mail address. 
Inputs:     emailStr: address.   
                  
Returns:  boolean   
               True if this whole OK.  
                False if not.
====================================================================*/

function isEmail (emailStr) {
	/*  Pattern of the format  algo@algo*/
	var emailPat=/^(.+)@(.+)$/
	/* Pattern for special characters. It includes ( ) < > @ , ; : \ " . [ ]    */
	var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
	/* Pattern of the range of characters not allowed on behalf of user and domain */
	var validChars="\[^\\s" + specialChars + "\]"
	/* Pattern for when the user is a chain, it doesn't take rules */
	var quotedUser="(\"[^\"]*\")"
	/* Pattern for the domains that are addresses IP. Ex. joe@[123.124.233.4] */
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
	/* Atom, series of non special characters */
	var atom=validChars + '+'
	/* Pattern for user's name */
	var word="(" + atom + "|" + quotedUser + ")"
	// Pattern for the user's structure 
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$")
	/* Pattern for the structure of a normal domain */
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")

	/* We break the address in pieces to analyze it */
	var matchArray=emailStr.match(emailPat)
	if (matchArray==null) {
              // Incorrect address. Check sign. @ y .'s"
		return false;
	}
	// I obtain user and domain
	var user=matchArray[1]
	var domain=matchArray[2]
	// we validate user
	if (user.match(userPat)==null) {
		// non valid user
		//Incorrect address. Non valid user's name
		return false;
	}
	/* if the email uses an address IP, we validate it */
	var IPArray=domain.match(ipDomainPat)
	if (IPArray!=null) {
		// es una direccion IP
		for (var i=1;i<=4;i++) {
			if (IPArray[i]>255) {
			    return false;
			}
		}
		return true;
	}
	// the domain is a normal symbolic name
	var domainArray=domain.match(domainPat)
	if (domainArray==null) {
	    return false
	}
	/*  we divide domain in atoms */
	var atomPat=new RegExp(atom,"g")
	var domArr=domain.match(atomPat)
	var len=domArr.length
	if (domArr[domArr.length-1].length<2 || domArr[domArr.length-1].length>3) {
		//Incorrect address. It should finish in 2 or 3 letters.
		return false;
	}
	// we make sure there is a hostname before the end
	if (len<2) {
		//Incorrect address. Expecting the name of the Host.
		return false
	}
	// OK.
	return true;
}



/*====================================================================
Function: operatorOk
Purpose:  It determines if all the operators are valid.  
Inputs:     pOper: Operator that is evaluated   
                pcantOper: Quantity of fields.  
Returns:  boolean   
               True if this whole OK.  
                False if not.
====================================================================*/

function operatorOk(pOper){

 var i,oNewElement;
 var sOperator=">,>=,<,<=,=,!=";
 
  if (sOperator.indexOf(pOper) < 0 ) return false;
  else return true;
   
} // End function operatorOk




/*====================================================================
Function: ftoday
Purpose: It determines the current date.
Inputs:  none   
Returns:  The current date returns in the format (YYYY/MM/DD).
====================================================================*/

function ftoday() {
   
   var Today = new Date();
   var d = Today.getDate(); // Dia

   // Mes
   var mon;
   mon = Today.getMonth()+1;

   //Anno
   var yr;
   yr = Today.getYear();
   
   var sDate = yr.toString() + "/" + mon.toString() +"/" + d.toString()    ;
   
   return sDate;

} // End function  ftoday


/*====================================================================
Function: fEvalDates
Purpose:  It compares the dates according to the operator that spends as parameter.  
Inputs:     pDate1: String that represents a date (dd/mm/yyyy)  
                pDate2:  2 types of values:  
                           .  String that represents a date (dd/mm/yyyy)  
                           .  String " sysdate ": it Indicates that the date pDate1 is wanted to compare with the current date.  
Returns:  String with the code of the error message if the comparison relationship finish  successfully  
               Empty String if the comparison failed.
====================================================================*/

function fEvalDates(pDate1,pDate2,sOper) {

    

      var arr = pDate1.split("/");
      sDate = arr[2] + "/" + arr[1] + "/" + arr[0];
      dDate1 = Date.parse(sDate);
                   
     if (pDate2=="sysdate")  {
        stoday = ftoday(); 
        dDate2 =  Date.parse(stoday);
       
     }
     else {
        arr = pDate2.split("/");
        sDate = arr[2] + "/" + arr[1] + "/" + arr[0];
         dDate2 = Date.parse(sDate);
    }
     
     var sreturn;
     var smens;
                                                
      switch (sOper) {
             case "<":
                       bAccum = (dDate1< dDate2);
                       smens = _validation.CHECK_LT_SYSDATE;
                        break;
	       case ">":
	                 bAccum = (dDate1> dDate2);
	                 smens = _validation.CHECK_GT_SYSDATE;
	                 break;    
	       case "=": 
	                  bAccum = (dDate1== dDate2);
	                  smens = _validation.CHECK_EQ_SYSDATE;
	                  break;
	       case "<=":
	                  bAccum = (dDate1<= dDate2);
	                  smens = _validation.CHECK_LE_SYSDATE;
	                  break;
	        case ">=":
	                  bAccum = (dDate1>= dDate2);
	                   smens = _validation.CHECK_GE_SYSDATE;
	                  break;
	         case "!=":
	                  bAccum = (dDate1 != dDate2);
	                  smens = _validation.CHECK_NE_SYSDATE;
	                  break;
         } //  switch
         
         
         if  (!bAccum) {
            if ( pDate2 == "sysdate")  {
               sreturn = smens;
            }
            else sreturn =_validation.CHECK_DATE;
        }
         else {
           sreturn="";
         }
         
         return sreturn;
}// End function   fEvalDates

/*====================================================================
Function: fcompare
Purpose: It compares the value of the Field that has the attribute the attribute check, with the value of one of the fields of the list defined in the attribute, using the 
                corresponding operator. 
Inputs:     factual: Current fields.
                otherValue:  One of the elements defined in the attribute check.
                oper: Operator.
                form: Current Form. 
                           
Returns:  String with the code of the error message if the comparison relationship finish  successfully  
               Empty String if the comparison failed.
====================================================================*/


function fcompare(factual, otherValue, oper,frm) {

  var variab;
  var oNewElement;
  var smens= "";
  var bAccum = false;
  var actualValue = factual.value;
 
  if (operatorOk(oper) && actualValue!="")  { // Is the Operator valid?
    var afield ;
   	
	if (!isNaN(otherValue)) {
	   afield = "\"" + otherValue + "\"";
	   otherValue=afield;  
	} 
	
   		     
    oNewElement=frm.elements[otherValue];
 
    if (oNewElement ) {    //  Does the field exist?
	if (factual.getAttribute("date")!=null ){   // Is Date?
	   if (oNewElement.getAttribute("date")!=null ) {  // assuring that the other one is also date
	      if (oNewElement.value !="") // The operator is valid and the value to compare this full one
                 smens = fEvalDates(actualValue,oNewElement.value,oper);
	   }   
						                                                                 
	}  // End  Is Date?
	else {  // It is not date    
	  if (oNewElement.value !=""){
	     
	      variab =  actualValue  +  oper   +  oNewElement.value   ;
	      
              bAccum= eval (variab);
              if (!bAccum) {
                 // Error Message 
                 smens = _validation.CHECK_NUMBER;
              }
           }   
        } // End  It is not date  
                                                                
                            		             
     }  // End Does the field exist?
     else{  // The field doesn't exist
                             		                                               		                  
         if (factual.getAttribute("date")!=null  && otherValue == "sysdate"){   // Is Sysdate?
                             		                         
             smens = fEvalDates(actualValue ,"sysdate",oper);
              
                    
          }// End Is Sysdate?
          else { // Is not Date
             variab =  actualValue  +  oper   +  otherValue;
              bAccum= eval (variab);
              if (!bAccum) {
                 // Error Message 
                 smens = _validation.CHECK_NUMBER;
              }
             

          }// End Is not Date

     } // End The field doesn't exist
     
 		                  
     
   } // End  Is the Operator valid?  
   return smens;   // Return Message      

} // End function  fcompare    


// ************************************************** End  of New Functions  (SGO Cuba) **********************************************************************



/*====================================================================
Function: Err
Purpose:  Custom object constructor
Inputs:   None
Returns:  undefined
====================================================================*/
function Err(){
	/*********************************************************************
	Method:   Err.clear
	Purpose:  Clear values from Error object
	Inputs:   none
	Returns:  undefined
	*********************************************************************/
	this.clear=function (){
		this.source=new Object;
		this.type=new Object;
		this.format=new String;
	}
	/*********************************************************************
	Method:   Err.add
	Purpose:  Adds error to Error object
	Inputs:   oSource - source element object
	          vType   - integer value of error type (or custom string)
	          sFormat - optional date format
	Returns:  undefined
	*********************************************************************/
	this.add=function (oSource,vType,sFormat){
		this.source=oSource;
		this.type=vType;
		this.format=sFormat;
	}
	
	
	/*********************************************************************
	Method:   Err.addTitles
	Purpose:  Adds error to Error object
	Inputs:   oSource - source element object
	          vType   - integer value of error type (or custom string)
	          sFormat - optional date format
	Returns:  undefined
	*********************************************************************/
	this.addTitles=function (oSource,vType,title1, title2){
		this.source=oSource;
		this.type=vType;
		this.title1=title1;
		this.title1=title2;

	}

	
	
	
	/*********************************************************************
	Method:   Err.raise
	Purpose:  Gives visual warning to user about all errors contained in
	          the Error object
	Inputs:   none
	Returns:  undefined
	*********************************************************************/
	this.raise=function (){
		var oElement=this.source;
		var sLang;
		var sNym=oElement.getAttribute("nym");
		// if type is not a number, it must be a custom error message
		var sMsg=(typeof this.type=="string")?this.type:oElement.getAttribute("msg");

		oElement.paint();
		if(oElement.select)
			oElement.select();
		if(sMsg)
			alert(sMsg);
		else{
			// Walk through object hierarchy to find applicable language
			var oParent=oElement;
			sLang=oParent.getAttribute("lang").substring(0,2).toLowerCase();
			while(!sLang || !_validation.messages[sLang]){
				oParent=oParent.parentElement;
				if(oParent)
					sLang=oParent.getAttribute("lang").substring(0,2).toLowerCase();
				else
					// Default language is English
					sLang="en";
			}
			sMsg=_validation.messages[sLang][this.type];
			alert(((sNym)?sNym+": ":"")+sMsg+((this.format)
				?" "+this.format.reformat(sLang,this.type):""));
		}

         if (oElement.disabled == false) {
		// Perform onvalidatefocus event handler for invalid field
		if(oElement.onvalidatefocus)
			oElement.onvalidatefocus();

		// Give invalid field focus
		 oElement.focus();
		// Clear the Err object
		this.clear();
	}
	else alert("Esta deshabilitado");
	}

	// Define the working object model
	this.clear();
}



/*====================================================================
Function: Validation
Purpose:  Custom object constructor.
Inputs:   None
Returns:  undefined
====================================================================*/
function Validation(){
	// Define global constants for calls to error message arrays
	this.REQUIRED = 0;
	this.INTEGER  = 1;
	this.FLOAT    = 2;
	this.DATE     = 3;
	this.AMOUNT   = 4;
	
	this.CHECK_NUMBER =   5;
	this.CHECK_DATE =   6;
	this.CHECK_LT_SYSDATE =  7;
	this.CHECK_LE_SYSDATE =   8;
       this.CHECK_GT_SYSDATE =  9;
       this.CHECK_GE_SYSDATE =   10;
       this.CHECK_NE_SYSDATE =  11;
       this.CHECK_EQ_SYSDATE =  12;
       this.EMAIL    = 13;
       this. LENGTH = 14;
       
        this.MASK     = 15;
	
	

	// Create error message dictionary
	this.messages = new Array;

	// Prototype the date tokens for each language
	Array.prototype.MM = new String;
	Array.prototype.DD = new String;
	Array.prototype.YYYY = new String;

	//English
	this.messages["en"]=new Array(
		"Please enter a value",
		"Please enter a valid integer",
		"Please enter a valid floating point",
		"Please enter a valid date",
		"Please enter a valid monetary amount",
		"The relationship is not completed between the fields",  
		"Error in Range of dates",  
		"The date should be previous to today's date",  
             "The date should be previous or similar to today's date",  
             "The date should be greater than today's date",  
              "The date should greater or the same as today's date",  
              "The date should be different to today's date",  
              "The date should be equal to today's date",
              "Please enter a valid email address",
              "Please enter the quantity of defined characters for the size of the field",
              "Please enter a value in the form of ");
		with(this.messages["en"]){
			MM="MM";
			DD="DD";
			YYYY="YYYY";
		};
		

	//Portuguese
	this.messages["pt"]=new Array(
		"Por favor digite um valor v_do",
		"Por favor digite um valor num_co inteiro",
		"Por favor digite o valor ponto flutuante",
		"Por favor digite uma data v_da",
		"Por favor digite o valor monet_o",
		" A relaÃ§Ã£o nÃ£o Ã© completada entre os campos ",    
		" Erro em Gama de datas ",    
		" A data deveria ser prÃ©via Ã  data  de hoje",    
             " A data deveria ser prÃ©via ou semelhante Ã  data  de hoje",    
             " A data deveria ser maior que a data  de hoje",    
              " A data deve maior ou igual Ã  data  de hoje",    
              " A data deveria ser diferente Ã  data  de hoje",    
              " A data deveria ser igual Ã  data  de hoje",
              "Por favor, entre em um endereÃ§o de correio vÃ¡lido",
              "Por favor introduz a quantidade de carÃ¡ter definidos pelo tamanho do campo ",   

             	"Por favor digite um valor no formulario ");
		with(this.messages["pt"]){
			MM="MM";
			DD="DD";
			YYYY="AAAA";
		};
             


	//French
	this.messages["fr"]=new Array(
		"Entrer une valeur, SVP",
		"Entrer un entier correct, SVP",
		"Entrer un point flottant correct, SVP",
		"Entrer une date correcte, SVP",
		"Entrer une valeur monetaire correcte, SVP",
		" La relation n'est pas complÃ©tÃ©e entre les champs ",    
		" Erreur dans intervalle de dates ",    
		" La date devrait Ãªtre antÃ©rieure Ã  la date  d'aujourd'hui",    
             " La date devrait Ãªtre antÃ©rieure ou semblable Ã  la date d'aujourd'hui",    
             " La date devrait Ãªtre plus grande que la date  d'aujourd'hui",    
              " La date devrait Ãªtre plus grand ou le mÃªme comme la date  d'aujourd'hui",    
              " La date devrait Ãªtre diffÃ©rente Ã  la date  d'aujourd'hui",    
              " La date devrait Ãªtre semblable Ã  la date  d'aujourd'hui",
               "S'il vous plaÃ®t, entrez une adresse du courrier valide",
               "S'il vous plaÃ®t il introduit la quantitÃ© de caractÃ¨res dÃ©finis pour la dimension du champ ",
              "Entrer, SVP, une valeur suivant le format suivant: ");
		with(this.messages["fr"]){
			MM="MM";
			DD="JJ";
			YYYY="AAAA";
		};
		


	//German
	this.messages["de"]=new Array(
		"Tragen Sie bitte einen Wert ein",
		"Tragen Sie bitte eine g_ Ganze Zahl ein",
		"Tragen Sie bitte ein Flie_omma ein",
		"Tragen Sie bitte ein g_s Datum ein",
		"Tragen Sie bitte eine g_n Geldbetrag ein",
		" Die Verbindung wird nicht zwischen den Feldern  vervollstÃ¤ndigt",      
		" Fehler in Auswahl von Daten ",      
		" Das Datum sollte zu heutigem Datum  vorausgehend sein",      
             " Das Datum sollte zu heutigem Datum  vorausgehend oder Ã¤hnlich sein",      
             " Das Datum sollte grÃ¶ÃŸer als heutiges Datum  sein",      
              " Das Datum sollte grÃ¶ÃŸer als heutiges Datum oder das Gleiche  sein",      
              " Das Datum sollte zu heutigem Datum  ander sein",      
              " Das Datum sollte zu heutigem Datum  Ã¤hnlich sein",
              "Bitte, betreten Sie eine gÃ¼ltige Email",
              "Bitte fÃ¼hrt es die QuantitÃ¤t definierter Charaktere fÃ¼r die GrÃ¶ÃŸe des Feldes ein",

              "Tragen Sie bitte einen Wert ein in Form von ");
		with(this.messages["de"]){
			MM="MM";
			DD="TT";
			YYYY="JJJJ";
		};
		


	//Italian
	this.messages["it"]=new Array(
		"Si prega di inserire un valore",
		"Si prega di inserire un valido numero intero",
		"Si prega di inserire un valido numero in virgola mobile",
		"Si prega di inserire una data valida",
		"Si prega di inserire una quantit_i valuta valida",
		" La relazione non Ã¨ completata tra i campi ",        
		" Errore in Serie di date ",        
		" La data dovrebbe essere precedente alla data  di oggi",        
             " La data dovrebbe essere precedente o simile alla data  di oggi",        
             " La data dovrebbe essere piÃ¹ grande della data  di oggi",        
              " La data dovrebbe essere piÃ¹ grande che la data di oggi o lo stesso ",        
              " La data dovrebbe essere diversa alla data  di oggi",        
              " La data dovrebbe essere simile alla data  di oggi",
              "Per favore, entri un email valido",
              "Per favore presenta la quantitÃ  di caratteri definiti per la taglia del campo ",
              "Si prega di inserire un valore nel formato ");
		with(this.messages["it"]){
			MM="MM";
			DD="GG";
			YYYY="AAAA";
		};
		


	//Spanish
	this.messages["es"]=new Array(
		"Por favor introduzca un valor",
		"Por favor introduzca un numero entero válido",
		"Por favor introduzca un punto flotante válido",
		"Por favor introduzca una fecha válida",
		"Por favor introduzca una cantidad monetaria válida",
		"No se cumple la relacion entre los campos",
		"Error en Rango de fechas",
		"La fecha debe ser anterior a la fecha de hoy",
             "La fecha debe ser anterior o igual a la fecha de hoy",
             "La fecha debe ser mayor que la fecha de hoy",
              "La fecha debe mayor o igual que la fecha de hoy",
              "La fecha debe ser diferente a la fecha de hoy",
              "La fecha debe ser igual a la fecha de hoy",
               "Por favor introduzca una dirección de e-mail válida",
               "Por favor introduzca la cantidad de caracteres definida para la longitud del campo",  

             	"Por favor introduzca un valor con el siguiente formato ");
		with(this.messages["es"]){
			MM="MM";
			DD="DD";
			YYYY="AAAA";
		};
		


	//Dutch
	this.messages["nl"]=new Array(
		"Vul s.v.p. een waarde in",
		"Vul s.v.p. een geldig geheel getal in",
		"Vul s.v.p. een geldig zwevend decimaal teken in",
		"Vul s.v.p. een geldige datum in",
		"Vul s.v.p. een geldig geldbedrag in",
		"The relationship is not completed between the fields",  
		"Error in Range of dates",  
		"The date should be previous to today's date",  
             "The date should be previous or similar to today's date",  
             "The date should be greater than today's date",  
              "The date should greater or the same as today's date",  
              "The date should be different to today's date",  
              "The date should be equal to today's date",
               "Please enter a valid e-mail",
               "Please enter the quantity of defined characters for the size of the field",

             	"Vul s.v.p. een waarde in, in de vorm van ");
		with(this.messages["nl"]){
			MM="MM";
			DD="DD";
			YYYY="JJJJ";
		};
		


	//Swedish
	this.messages["sv"]=new Array(
		"Var v_ig fyll i ett v_e",
		"Var v_ig fyll i ett giltigt heltal",
		"Var v_ig fyll i ett giltigt tal",
		"Var v_ig fyll i ett giltigt datum",
		"Var v_ig fyll i ett giltigt belopp",
		"The relationship is not completed between the fields",  
		"Error in Range of dates",  
		"The date should be previous to today's date",  
             "The date should be previous or similar to today's date",  
             "The date should be greater than today's date",  
              "The date should greater or the same as today's date",  
              "The date should be different to today's date",  
              "The date should be equal to today's date",
               "Please enter a valid e-mail",
               "Please enter the quantity of defined characters for the size of the field",

		"Var v_ig fyll i ett v_e p_ormen ");
		with(this.messages["sv"]){
			MM="MM";
			DD="DD";
			YYYY="__";
		};
		
	

	/*********************************************************************
	Method:   Validation.setDefault
	Purpose:  Set value for variable v if v is zero, empty string or
	          undefined
	Inputs:   v - variable (passed by value)
	          d - default value
	Returns:  v or d
	*********************************************************************/
	this.setDefault=function (v, d){
		return (v)?v:d;
	}
	/*********************************************************************
	Method:   Validation.isDate
	Purpose:  Check that value is a date of the correct format
	Inputs:   oElement - form element
	          sFormat  - string format
	Returns:  boolean
	*********************************************************************/
	this.isDate=function (oElement,sFormat){
		var sDate=oElement.value;
		var aDaysInMonth=new Array(31,28,31,30,31,30,31,31,30,31,30,31);

		// Fetch the date separator from the user's input
		var sSepDate=sDate.charAt(sDate.search(/\D/));
		// Fetch the date separator from the format
		var sSepFormat=sFormat.charAt(sFormat.search(/[^MDY]/i));
		// Compare separators
		if (sSepDate!=sSepFormat)
			return false;

		// Fetch the three pieces of the date from the user's input and the format
		var aValueMDY=sDate.split(sSepDate);
		var aFormatMDY=sFormat.split(sSepFormat);
		var iMonth,iDay,iYear;

		// Validate that all pieces of the date are numbers
		if (  !_validation.isNum(aValueMDY[0])
			||!_validation.isNum(aValueMDY[1])
			||!_validation.isNum(aValueMDY[2]))
			return false;

		// Assign day, month, year based on format
		switch (aFormatMDY[0].toUpperCase()){
			case "YYYY" :
				iYear=aValueMDY[0];
				break;
			case "DD" :
				iDay=aValueMDY[0];
				break;
			case "MM" :
				iMonth=aValueMDY[0];
				break;
			default :
				return false;
		}
		switch (aFormatMDY[1].toUpperCase()){
			case "YYYY" :
				iYear=aValueMDY[1];
				break;
			case "MM" :
				iMonth=aValueMDY[1];
				break;
			case "DD" :
				iDay=aValueMDY[1];
				break;
			default :
				return false;
		}
		switch(aFormatMDY[2].toUpperCase()){
			case "MM" :
				iMonth=aValueMDY[2];
				break;
			case "DD" :
				iDay=aValueMDY[2];
				break;
			case "YYYY" :
				iYear=aValueMDY[2];
				break;
			default :
				return false;
		}

		// Require 4 digit year
		if(oElement.form.getAttribute("year4")!=null && iYear.length!=4)
			return false;
		// Process pivot date and update field
		var iPivot=_validation.setDefault(oElement.getAttribute("pivot"),
			oElement.form.getAttribute("pivot"));
		if(iPivot && iPivot.length==2 && iYear.length==2){
			iYear=((iYear>iPivot)?19:20).toString()+iYear;
			var sValue=aFormatMDY.join(sSepFormat).replace(/MM/i,iMonth);
			sValue=sValue.replace(/DD/i,iDay).replace(/YYYY/i,iYear);
			oElement.value=sValue;
		}

		// Check for leap year
		var iDaysInMonth=(iMonth!=2)?aDaysInMonth[iMonth-1]:
			((iYear%4==0 && iYear%100!=0 || iYear % 400==0)?29:28);

		return (iDay!=null && iMonth!=null && iYear!=null
				&& iMonth<13 && iMonth>0 && iDay>0 && iDay<=iDaysInMonth);
	}
	/********************************************
	Method:   Validation.isNum
	Purpose:  Check that parameter is a number
	Inputs:   v - string value
	Returns:  boolean
	********************************************/
	this.isNum=function (v){
		return (typeof v!="undefined" && v.toString() && !/\D/.test(v));
	}
	/*********************************************************************
	Method:   Validation.setup
	Purpose:  Set up methods and event handlers for all forms and elements
	Inputs:   none
	Returns:  undefined
	*********************************************************************/
	this.setup=function (){
		// Fan through forms on page to perform initializations
		var i,iForms=document.forms.length;
		for(i=0; i<iForms; i++){
			var oForm=document.forms[i];
			if(!oForm.bProcessed){
				/*********************************************
				Method:   Form.markRequired
				Purpose:  Mark all required fields for a form
				Inputs:   none
				Returns:  undefined
				*********************************************/
				oForm.markRequired=function (){
					var i, iElements=this.elements.length;
					var sMarkHTML, sMarkWhere;
					for(i=0; i<iElements; i++){
						var oElement=this.elements[i];
						// Perform onmark event handler
						if(oElement.onmark && oElement.onmark()==false)
							continue;
						if(oElement.getAttribute("required")!=null){
							sMarkHTML=this.getAttribute("insert");
							sMarkWhere=this.getAttribute("mark");
							if(sMarkHTML){
								switch(sMarkWhere.toLowerCase()){
									case "before" :
										sMarkWhere="beforeBegin";
										break;
									default :
										sMarkWhere="afterEnd";
								}
								oElement.insertAdjacentHTML(sMarkWhere,sMarkHTML);
							}else{
								var sClassName=oElement.className;
								if(sClassName!="required"){
									oElement.setAttribute("nonreqClass",oElement.className);
									oElement.className="required";
								}else{
									oElement.className=_validation.setDefault(oElement.getAttribute("nonreqClass"),oElement.className);
									oElement.removeAttribute("nonreqClass");
								}
							}
						}
					}
				}
				var sValidateWhen=oForm.getAttribute("validate");
				if (sValidateWhen!=null){
					//
					// Capture and replace onreset and onsubmit event handlers
					//
					oForm.fSubmit=oForm.onsubmit;
					oForm.fReset=oForm.onreset;

					// Create new event handlers
					oForm.onsubmit=function (){
						var i, oElement, iElements=this.elements.length;
						// Restore all elements to original style
						for (i=0; i<iElements; i++)
						    this.elements[i].restore();
						// Validate individual elements
						for(i=0;i<iElements;i++){
							oElement=this.elements[i];
							// Perform default validation for element
							if (!oElement.valid()){
								_err.raise();
								event.returnValue=false;
								return;
							}
						}

						// Perform original onsubmit event handler
						if (this.fSubmit && this.fSubmit()==false){
							event.returnValue=false;
							return;
						}

						// Insert default values just before submit
						var vDefault;
						for(i=0;i<iElements;i++){
							oElement=this.elements[i];
							vDefault=oElement.getAttribute("default");
							if(vDefault && !oElement.value)
								oElement.value=vDefault;
						}
					}
					oForm.onreset=function (){
						var i, iElements=this.elements.length;
						for (i=0; i<iElements; i++)
							this.elements[i].restore();
						// Perform original event handler if present
						if (this.fReset && this.fReset()==false)
								event.returnValue=false;
					}
				}
				oForm.bProcessed=true;
			}
			// Create Input methods
			var j, iElements=oForm.elements.length;
			for(j=0; j<iElements; j++){
				var oElement=oForm.elements[j];
				if(!oElement.bProcessed) {

					// All event handlers are presumed to be strings/functions
					// at parse-time and assigned only as functions at run-time.

					// Create custom onvalidate event handlers
					var vOnValidate=oElement.getAttribute("onvalidate");
					if(vOnValidate){
						if(typeof vOnValidate!="function")
							oElement.onvalidate=new Function(vOnValidate);
						else
							oElement.onvalidate=vOnValidate;
					}
					// Create custom handler for onvalidatefocus event
					var vOnValidateFocus=oElement.getAttribute("onvalidatefocus");
					if(vOnValidateFocus){
						if(typeof vOnValidateFocus!="function")
							oElement.onvalidatefocus=new Function(vOnValidateFocus);
						else
							oElement.onvalidatefocus=vOnValidateFocus;
					}
					// Custom onmark event handler
					var vOnMark=oElement.getAttribute("onmark");
					if(vOnMark){
						if(typeof vOnMark!="function")
							oElement.onmark=new Function(vOnMark);
						else
							oElement.onmark=vOnMark;
					}
					// Custom onkeypress filtering for text fields
					if(oElement.onkeypress)
						oElement.fKeypress=oElement.onkeypress;
					oElement.onkeypress=function (){
						if(this.fKeypress && this.fKeypress()==false)
							event.returnValue=false;
						var sFilter=this.getAttribute("filter");
						if(sFilter){
							var sKey=String.fromCharCode(event.keyCode);
							var re=new RegExp(sFilter);
							// Do not filter out ENTER!
							if(sKey!="\r" && !re.test(sKey))
								event.returnValue=false;
							event.keyCode=sKey.charCodeAt(0);
						}
					}
					// Custom onchange validation
					if(sValidateWhen=="onchange") {
						// Capture and replace onchange event handlers
						if(oElement.onchange)
							oElement.fChange=oElement.onchange;
						oElement.onchange=function (){
							this.restore();
							if(!this.valid()){
								_err.raise();
								event.returnValue=false;
							}
							if(this.fChange && this.fChange()==false){
								event.returnValue=false;
							}
						}
					}
					/***********************************
					Method:   Input.paint
					Purpose:  Change style of element
					Inputs:   none
					Returns:  undefined
					***********************************/
					oElement.paint=function(){
						var sColor = _validation.setDefault(
							this.getAttribute("invalidColor"),
							this.form.getAttribute("invalidColor") );
						if (!sColor){
							// Paint element by changing class
							this.setAttribute("oldClass", this.className);
							this.className = "invalid";
						}else{
							// Paint element by changing color directly
							this.setAttribute("bg", this.style.backgroundColor);
							this.style.backgroundColor = sColor;
						}
					}
					/********************************************
					Method:   Input.restore
					Purpose:  Restore element to original style
					Inputs:   none
					Returns:  undefined
					********************************************/
					oElement.restore=function () {
						var sBG=this.getAttribute("bg");
						if (sBG!=null) {
							// Revert to previous background color
							this.style.backgroundColor = sBG;
							this.removeAttribute("bg");
						}else{
							var sOldClass=this.getAttribute("oldClass");
							if (sOldClass!=null){
								// Revert to previous class
								this.className=sOldClass;
								this.removeAttribute("oldClass");
							}
						}
					}
					/**********************************************
					Method:   Input.valid
					Purpose:  Validate an element based on the
					          attributes provided in the HTML text
					Inputs:   none
					Returns:  boolean
					**********************************************/
					oElement.valid=function (){
						var sType=this.type;
						if(sType=="text" || sType=="textarea" || sType=="file"){
							// Trim leading and trailing spaces
							if(this.form.getAttribute("notrim")==null)
								this.value = this.value.trim();
							// Remove any Server Side Include text
							if(this.form.getAttribute("ssi")==null){
								while (this.value.search("<!-"+"-#") > -1)
									this.value = this.value.replace("<"+"!--#", "<"+"!--");
							}
						}
						// REQUIRED
						if(this.getAttribute("required")!=null && !this.value){
						    	_err.add(this, _validation.REQUIRED, null);
					 		return false;
						}
						// FLOAT
						var sFloatDelimiter=this.getAttribute("float");
						var bSigned=this.getAttribute("signed")!=null;
						if (sFloatDelimiter!=null && this.value){
							// Assign default value to delimiter
							sFloatDelimiter=(sFloatDelimiter==",")?",":"\\.";
							var re=new RegExp("^("+((bSigned)?"[\\-\\+]?":"")+"(\\d*"+sFloatDelimiter+"?\\d+)|(\\d+"+sFloatDelimiter+"?\\d*))$");
							if (!re.test(this.value)){
								_err.add(this, _validation.FLOAT, null);
								return false;
							}
						}
						// AMOUNT
						var sAmtDelimiter = this.getAttribute("amount");
						if (sAmtDelimiter!=null && this.value){
							// Assign default value to delimiter
							sAmtDelimiter=(sAmtDelimiter==",")?",":"\\.";
							var re = new RegExp("^"+((bSigned)?"[\\-\\+]?":"")+"\\d+("+sAmtDelimiter+"\\d{2})?$");
							if(!re.test(this.value)){
								_err.add(this, _validation.AMOUNT, null);
								return false;
							}
						}
						
						// **************************** Beginning New attributes (CHECK,OPERATOR)  (SGO Cuba)****************************************

						//CHECK
						
				
						if (this.getAttribute("check")!=null  ){  //Is there attribute  check?
						
						 	   var actualValue = this.value;
						   var sactualTitle = this.title;
						   var smens = "";
						   var variab = "";
								  
						    var oNewElement, bAccum=false;
						    var sCheck=this.getAttribute("check");
						   
						      // Array of fields
						    var aCheck=sCheck.split(",");
						    var i, iFields=aCheck.length;
						   
						    
						     if (this.getAttribute("operator")!=null ){  //Is there attribute Operator?
						        // Array of operators 
						        var sOper=this.getAttribute("operator");
						      

						        var aOper=sOper.split(",");
						         var iOper = aOper.length;
						                                  			          
					            if ( iFields == iOper) { // Equality between quantity of Fields and Operators?
						        if (iFields == 1) { // Is there a single element?
						        
						           smens=fcompare(this,sCheck,sOper,this.form);
					
					                  if (smens != "")  {
						              //Error Message 
                                                      _err.add(this, smens , null);
						              return false;
					                  }	
					      
					              }   // End Is there a single element?  
                        			                        	  
						       else { // Array
						            var actualfield = this;
					             	     for(i=0; i<iFields; i++){
						               bAccum = false;
						               smens = "";
						               smens=fcompare(actualfield,aCheck[i],aOper[i],this.form);
						               if (smens != "")  {
						                   //Error Message 
                                                          _err.add(this, smens , null);
						                   return false;
					                      }		   
						            }// End for	
							
							   		
						      } // End Array
							                       		                  
                                          
						   } // End Equality between quantity of Fields and Operators?	
						
						} // End Is there attribute Operator?	
							
							
                                    }// End Is there attribute  check?
                                    
                                    
                                 // ****************                                         
                                    
                                //E-MAIL
						
			            if (this.getAttribute("email")!=null  ){  //Is there attribute  email?
						
						   var actualValue = this.value;
						   if (actualValue != "") {
						     if (!isEmail (actualValue)) {
						         var smens =  _validation.EMAIL;
						         //Error Message 
                                                 _err.add(this, smens , null);
						           return false;
					             }	
						     
						  }
								
                                    }// End Is there attribute  email?
                                
                                  // ****************    
                                    
                                  // Attribute LENGTH
                                  
                                  if (this.getAttribute("length")!=null  ){  //Is there attribute  length?
	
  					
                                       var actualValue = this.value;
                                     
   
                                       var len = this.getAttribute("length");

                                       var actualLength = parseInt(len);
                                       var lenActualValue = actualValue.length; 

                                       if (len.length > 0) {
                                         if (!isNaN(actualLength)) {

                                          // is Integer?
                                          if (lenActualValue >0 && lenActualValue != actualLength){
                                               
				                   _err.add(this, _validation.LENGTH, null);
	                                       return false;
                                          }

                                        } 

                                      }
                                    } // End Is there attribute  length?

   
                                    
                                    
                                    
                                    
                                                                        
                                    // **************************** End New attributes(CHECK,OPERATOR)  (SGO Cuba) **************************************************

						
						
						// INTEGER
						if (this.getAttribute("integer")!=null && this.value){
							var re=new RegExp("^"+((bSigned)?"[\\-\\+]?":"")+"\\d+$");
							if (!re.test(this.value)){
							     
								_err.add(this, _validation.INTEGER, null);
								return false;
							}
						}
						
						
					
						
						// DATE
						var sFormat=this.getAttribute("date");
						if (sFormat!=null && this.value) {
							// Set default date format
							sFormat = _validation.setDefault(sFormat, "DD/MM/YYYY");
							if (!_validation.isDate(this,sFormat)){
								_err.add(this, _validation.DATE, sFormat.toUpperCase());
								return false;
							}
						}
						// MASK
						var sMask=this.getAttribute("mask");
						if(sMask && this.value){
							var sPattern=sMask.replace(
								/(\$|\^|\*|\(|\)|\+|\.|\?|\\|\{|\}|\||\[|\])/g,"\\$1");
							sPattern=sPattern.replace(/9/g ,"\\d");
							sPattern=sPattern.replace(/x/ig,".");
							sPattern=sPattern.replace(/z/ig,"\\d?");
							sPattern=sPattern.replace(/a/ig,"[A-Za-z]");
							var re=new RegExp("^"+sPattern+"$");
							if(!re.test(this.value)){
								_err.add(this, _validation.MASK, sMask);
								return false;
							}
						}
						// REGEXP
						var sRegexp=this.getAttribute("regexp");
						if(sRegexp && this.value){
							var re=new RegExp(sRegexp);
							if(!re.test(this.value)){
								_err.add(this, _validation.MASK, sRegexp);
								return false;
							}
						}
						// AND
						var sAnd=this.getAttribute("and");
						if(sAnd && this.value){
							var aAnd = sAnd.split(/,/);
							var i, iFields=aAnd.length;
							// Require each element in the list if this element is valued
							for(i=0; i<iFields; i++){
								var oNewElement=this.form.elements[aAnd[i]];
								if(oNewElement && oNewElement.value.trim()==""){
									_err.add(oNewElement, _validation.REQUIRED, null);
									return false;
								}
							}
						}
						// OR
						var sOr=this.getAttribute("or");
						if(sOr && this.value==""){
							var aOr=sOr.split(/,/);
							var i, iFields=aOr.length;
							var oNewElement, bAccum=false;
							for(i=0; i<iFields; i++){
								oNewElement=this.form.elements[aOr[i]];
								if(oNewElement)
									bAccum |= !!oNewElement.value.trim();
							}
							if(!bAccum){
								_err.add(this, _validation.REQUIRED, null);
								return false;
							}
						}
						// NOSPACE
						if (this.getAttribute("nospace")!=null)
							this.value=this.value.replace(/\s/g,"");
						// UPPERCASE
						if (this.getAttribute("uppercase")!=null)
							this.value=this.value.toUpperCase();
						// LOWERCASE
						if (this.getAttribute("lowercase")!=null)
							this.value=this.value.toLowerCase();
						// Perform onvalidate event handler
						if(this.onvalidate && this.onvalidate()==false)
							return false;

						return true;
					}
					oElement.bProcessed=true;
				}
			}
		}
	}
	// Limit use of script to valid environments
	if("".replace && document.body && document.body.getAttribute){
		/*********************************************************************
		Method:   String.trim
		Purpose:  Removing leading and trailing spaces
		Inputs:   none
		Returns:  string
		*********************************************************************/
		String.prototype.trim=function (){
			return this.replace(/^\s+|\s+$/g,"");
		}
		/*********************************************************************
		Method:   String.reformat
		Purpose:  Translate the date format into the correct language
		Inputs:   sLang - language of error message to display
		          iType - type of failed validation
		Returns:  string
		*********************************************************************/
		String.prototype.reformat=function (sLang,iType){
			var sString=this.valueOf();
			if (iType==_validation.DATE && _validation.messages[sLang]) {
				sString=sString.replace(/MM/,_validation.messages[sLang].MM);
				sString=sString.replace(/DD/,_validation.messages[sLang].DD);
				sString=sString.replace(/YYYY/,_validation.messages[sLang].YYYY);
			}
			return sString;
		}
		// Form setup
		if(document.forms){
			// Process forms and elements
			this.setup();

			var i, iForms=document.forms.length;
			for(i=0; i<iForms; i++){
				var oForm=document.forms[i];
				if(oForm.getAttribute("mark")!=null)
					oForm.markRequired();
			}
		}
	}
}
_validation=new Validation;
_err=new Err;

