//****************************************************************************************************
// PARAMETERS
//****************************************************************************************************
var LONG          = "0";
var EMPTY         = "1";
var INTEGER       = "2";
var NIF           = "3";
var NIE           = "4";
var CIF           = "5";
var TELEPHONE     = "6";
var DNI           = "7";
var EMAIL         = "8";
var DATE          = "10";
var TIME          = "11";
var BANK          = "12";
var NIFNIECIF     = "13";
var NIFNIE        = "14";
var DNINIF        = "15";
var CP			  = "16";

var MSG_LONG         = " debe tener ";
var MSG_EMPTY        = " no puede estar vacío\n";
var MSG_INTEGER      = " no es un número válido\n";
var MSG_NIF          = " no es un NIF válido\n";
var MSG_NIE          = " no es un NIE válido\n";
var MSG_CIF          = " no es un CIF válido\n";
var MSG_EMAIL        = " no es un e-mail válido\n";
var MSG_TELEPHONE    = " no es un teléfono válido\n";
var MSG_DNI          = " no es un DNI válido\n";
var MSG_DATE         = " no es una fecha válida\n";
var MSG_TIME         = " no es un hora válida\n";
var MSG_BANK         = " no es un número de cuenta válido\n";
var MSG_NIFNIECIF    = " no es un NIF/CIF válido\n";
var MSG_NIFNIE       = " no es un NIF válido\n";
var MSG_DNINIF       = " no es un DNI/NIF válido\n";
var MSG_CP			 = " no es un código postal válido\n";


//CONFIGURACIÓN
var whitespace = " \t\n\r";         //Caracteres de espacio en blanco

//****************************************************************************************************
//CLASS FORMVALIDATOR
//****************************************************************************************************
function FormValidator(form)
{
   //DATA
   this.form = form
   this.fields = new Array
   this.checkAll = false
   this.focus = true

   //METHODS
   this.addField = addField
   this.validateAll = validateAll
   this.focusField = focusField
   this.checkForm = checkForm
   this.checkonlyForm = checkonlyForm
}

function addField(field,etiqueta,tipo,numero)
{
   this.fields[this.fields.length] = new FieldValidator(this.form + "." + field,etiqueta,tipo,numero);
}

function validateAll(value) { this.checkAll = value; }

function focusField(value) { this.focus = value; }

function checkForm()
{
   var msgError='';
   
   j=0;
   while ((j<this.fields.length) && ((msgError==''||this.checkAll==true)))
   {
      msgError+=this.fields[j].checkField();
      j++;
   }
   if (msgError!="") 
   {
      if ((j<=this.fields.length) && (this.focus==true) && (this.checkAll==false) && this.fields[j-1].validation!=BANK) obj=eval(this.fields[j-1].obj + ".focus()")
      alert(msgError);
   }
   else {eval(this.form + ".submit()")}
}

function checkonlyForm()
{
   var msgError='';
   var lbReturn;
   
   j=0;
   while ((j<this.fields.length) && ((msgError==''||this.checkAll==true)))
   {
      msgError+=this.fields[j].checkField();
      j++;
   }
   if (msgError!="") 
   {
      alert(msgError);
	  lbReturn = false;
   } else { 
      lbReturn = true; 
   }
   
   return lbReturn;
}

//****************************************************************************************************
//CLASSE FIELDVALIDATOR
//****************************************************************************************************
function FieldValidator(field,etiqueta,validation,numero)
{
   //DATA
   this.obj = field                 //Identificador del campo a validar
   this.field = etiqueta
   this.validation = validation     //Tipo de validación a realizar al campo
   this.number = numero             //Número de caracteres que debe contener el campo
   //METHODS
   this.checkField = checkField     //Función que devuelve un string con el mensaje de error
}

function checkField()
{

   obj = eval(this.obj);
   switch(obj.type)
   {
	case "select-one": 
		if (obj.selectedIndex == 0) valor = ""; 
		else valor = obj.options[obj.selectedIndex].value;
		break;
	default: valor = eval(this.obj + ".value")
   }
   
   switch(this.validation)
   {
		case "0": //LONG
         if (!(isLong(valor,this.number))) return(this.field + MSG_LONG + this.number + " caracteres o dígitos");
         else return("");
         break;
      case "1": //EMPTY
         if (isEmpty(valor)) return(this.field + MSG_EMPTY);
         else return("");
         break;
      case "2": //INTEGER
         if (!(isInteger(valor))) return(this.field + MSG_INTEGER);
         else return("");
         break;
      case "3": //NIF
         if (!(isNIF(valor))) return(this.field + MSG_NIF);
         else return("");
         break;
      case "4": //NIE
         if (!(isNIE(valor))) return(this.field + MSG_NIE);
         else return("");
         break;
      case "5": //CIF
         if (!(isCIF(valor))) return(this.field + MSG_CIF);
         else return("");
         break;
      case "6": //TELEPHONE
         if (!(isTelephone(valor))) return(this.field + MSG_TELEPHONE);
         else return("");
         break;
      case "7": //DNI
         if (!(isDNI(valor))) return(this.field + MSG_DNI);
         else return("");
         break;
      case "8": //EMAIL
         if (!(isEmail(valor))) return(this.field + MSG_EMAIL);
         else return("");
         break;
      case "10": //DATE
         if (!(isDate(valor))) return(this.field + MSG_DATE);
         else return("");
         break;
      case "11": //TIME
         if (!(isTime(valor))) return(this.field + MSG_TIME);
         else return("");
         break;
      case "12": //BANK
         if (!(isBank(valor))) return(this.field + MSG_BANK);
         else return("");
         break;
      case "13": //NIFNIECIF
         if (!(isNIF(valor)||isNIE(valor)||isCIF(valor))) return(this.field + MSG_NIFNIECIF);
         else return("");
         break;
      case "14": //NIFNIE
         if (!(isNIF(valor)||isNIE(valor))) return(this.field + MSG_NIFNIE);
         else return("");
         break;
      case "15": //DNINIF
         if (!(isDNI(valor)||isNIF(valor))) return(this.field + MSG_DNINIF);
         else return("");
         break;
      case "16": //CP
         if (!(isInteger(valor)&&isLong(valor,5))) return(this.field + MSG_CP);
         else return("");
         break; 
      default: return("");
   }
}


function isLong(value,number)
{
   if ((value == null) || (value.length == 0)) return true;
   if (value.length != number) return false;
   return true;
}

function isEmpty(value)
{
   if ((value == null) || (value.length == 0)) return true;

   for (i = 0; i < value.length; i++)
    {   
        // Miramos si el caracter es un espacio en blanco
        var car = value.charAt(i);
        if (whitespace.indexOf(car) == -1) return false;
    }
    return true;
}

function isInteger(value)
{
   if ((value == null) || (value.length == 0)) return true;
   var objRegExp  = /^\d+/;
   return objRegExp.test(value);
}

function isTelephone(value)
{
   if ((value == null) || (value.length == 0)) return true;
   var objRegExp  = new RegExp("^[69]\\d{8}$");
   return objRegExp.test(value);
}

function isDate(value)
{
   if ((value == null) || (value.length == 0)) return true;
   var objRegExp = /^[0-3][0-9]\/[0-1][0-9]\/[0-9]{4}$/
   if(!objRegExp.test(value)) 
   {
      return false;
   }
   else
   {
      var strSeparator = value.substring(2,3)
      var arrayDate = value.split(strSeparator);
      var arrayLookup = {'01' : 31,'03' : 31, '04' : 30,'05' : 31,'06' : 30,'07' : 31,'08' : 31,'09' : 30,'10' : 31,'11' : 30,'12' : 31}
      var intDay = parseInt(arrayDate[0],10); 
      if(arrayLookup[arrayDate[1]] != null) {
      	if(intDay <= arrayLookup[arrayDate[1]] && intDay != 0)
      	return true;
      }
      var intYear = parseInt(arrayDate[2],10);
      var intMonth = parseInt(arrayDate[1],10);
      if ((((intYear % 4 == 0) && (intYear % 100 != 0)) || intYear % 400 == 0) && intDay <= 29 && intDay !=0) return true;
      if ((((intYear % 4 != 0) && (intYear % 100 == 0)) || intYear % 400 != 0) && intDay <= 28 && intDay !=0) return true;
   }
   return false;
}

function isTime(value)
{
   if ((value == null) || (value.length == 0)) return true;
	var objRegExp = /^([0-2][0-3]:[0-5][0-9])|(1[0-9]:[0-5][0-9])$/;
	return objRegExp.test(value);			
}

function isEmail(value)
{
   if ((value == null) || (value.length == 0)) return true;
   var objRegExp = new RegExp("^[^@]+@[^\\.]+(\\.[^\\.]+)+$");			
	return objRegExp.test(value);
	//if (valida) return true;
	//return false;
   
   //if ((value == null) || (value.length == 0)) return true;
   //var objRegExp  = /(^[A-Za-z0-9][A-Za-z_0-9_\.]*@([A-Za-z0-9][A-Za-z0-9_\.]*)([.][A-Za-z]{2,3})$)/;
   //return objRegExp.test(value);
}

function isDNI(value)
{
   if ((value == null) || (value.length == 0)) return true;
   var objRegExp  = /^[0-9]{8}$/;
   return objRegExp.test(value);
}

function isNIF(value)
{
   if ((value == null) || (value.length == 0)) return true;
   value = value.toUpperCase();
   var objRegExp  = /^[0-9]{8}[A-Z]{1}$|^[KLXM]{1}[0-9]{7}[A-Z]{1}$/;
   if (objRegExp.test(value))
   {
      var letras = "TRWAGMYFPDXBNJZSQVHLCKE";
      var letranif=value.substring(8,9);
      var numero=value.substring(0,8);
      var baremo = numero % 23;
      if (letranif == letras.charAt(baremo)) { return true; }
   }
   return false;
}

function isNIE(value)
{
   if ((value == null) || (value.length == 0)) return true;
   value = value.toUpperCase();
   var objRegExp  = /^[KLXM]{1}[0-9]{7}[A-Z]{1}$/;
   if (objRegExp.test(value))
   {
      var letras = "TRWAGMYFPDXBNJZSQVHLCKE";
      var letranif=value.substring(8,9);
      var numero=value.substring(1,8);
      var baremo = numero % 23;
      if (letranif == letras.charAt(baremo)) { return true; }
   }
   return false;
}

function isCIF(value)
{
   if ((value == null) || (value.length == 0)) return true;
   value = value.toUpperCase();
   var objRegExp  = /^[ABCDEFGHSPQ]{1}[0-9]{7}[A-Z0-9]{1}$/;
   if (objRegExp.test(value))
   {
      var c, R1=0, R2=0, R=0, n=0;
      var letras = "JABCDEFGHI";
      var letracif=value.charAt(8);
      var num = value.substring(1,8);
      R1=parseInt(num.charAt(1),10)+parseInt(num.charAt(3),10)+parseInt(num.charAt(5),10);    
      for (i=0;i<7;i+=2) {
           n=parseInt(num.charAt(i),10)*2;
           if(n>9) n=n-9;
           R2=R2+n;
      }
      R=R1+R2;
      R=(10-(R%10))%10;       
      c=R.toString(10);
      var objRegExp  = /^[0-9]{1}$/;
      if (objRegExp.test(letracif)){ if (letracif==c) return true; }
      else { if (letracif==letras.charAt(R)) return true; }
   }
   return false;
}

function isBank(value)
{
   if ((value == null) || (value.length == 0)) return true;
 
	var acumulador = 0;
	var resto      = 0;
	var digical 	= '';

	// coeficientes de cálculo del d.c. de la entidad+sucursal
	var coef_entsuc = Array(4,8,5,10,9,7,3,6);
	
	// coeficientes de cálculo del d.c. de la cuenta
	var coef_cta = Array(1,2,4,8,5,10,9,7,3,6);
	
	// digitos de control entrados por el usuario
   var entsuc 	= value.substr(0,8); 	
	var dc 		= value.substr(8,2);
	var cta 		= value.substr(10,10);
	
	for ( i = 0; i < entsuc.length; i++ ) {
		acumulador += (parseInt(entsuc.substr(i,1)) * coef_entsuc[i]);
	}
	resto = 11 - (acumulador % 11);
	switch ( resto )
	{
		case 11 : 
			digical = 0; 
			break;
		case 10 : 
			digical = 1; 
			break;
		default : 
			digical = resto; 
			break;
	}
	if ( digical != dc.substr(0,1) ) return false;
	
	// calcular el segundo digito a partir del numero de la cuenta
	acumulador = 0;
	for ( i = 0; i < cta.length; i++ ) {
		acumulador += (parseInt(cta.substr(i,1))  * coef_cta[i]);
	}
	resto = 11 - (acumulador % 11);
	switch ( resto )
	{
		case 11 : 
			digical = 0; 
			break;
		case 10 : 
			digical = 1; 
			break;
		default : 
			digical = resto; 
			break;
	}
	if ( digical != dc.substr(1,1) ) return false;
	
	return true;
}
