var validators = {};
var validatorsI18N = 
{
    'en': {},
    'es': {}
};

// FECHA_DD_MM_AAAA

validators['DATE_DD_MM_AAAA_FUTURE'] = function (date )
{
  var aoDate = date.split("/");
  if (aoDate.length !== 3) return false;
  var day = parseInt(aoDate[0], 10);
  var month = parseInt(aoDate[1], 10) - 1;
  var year = parseInt(aoDate[2], 10);
  var ms = (new Date(year, month, day)).getTime();
  aoDate = new Date();
  aoDate.setTime(ms);
  // Lo obtenido es igual a lo pasaso
  if (aoDate.getFullYear() !== year || aoDate.getMonth() !== month || aoDate.getDate() !== day) {
    return false;
  }
  // Tiene que ser posterior a hoy
  if (ms < (new Date()).getTime()) return false;
  return true;
}
validatorsI18N['en']['DATE_DD_MM_AAAA_FUTURE'] = 'It has to be a date after today in dd/mm/aaaa format';
validatorsI18N['es']['DATE_DD_MM_AAAA_FUTURE'] = 'Tiene que ser una fecha posterior a hoy en formato dd/mm/aaaa';

validators['DATE_DD_MM_AAAA_FUTURE_HOY'] = function (date )
{
  var aoDate = date.split("/");
  if (aoDate.length !== 3) return false;
  var day = parseInt(aoDate[0], 10);
  var month = parseInt(aoDate[1], 10) - 1;
  var year = parseInt(aoDate[2], 10);
  var ms = (new Date(year, month, day, 23 , 59, 59)).getTime();
  aoDate = new Date();
  aoDate.setTime(ms);
  // Lo obtenido es igual a lo pasaso
  if (aoDate.getFullYear() !== year || aoDate.getMonth() !== month || aoDate.getDate() !== day) {
    return false;
  }
  // Tiene que ser posterior a hoy
  if (ms < (new Date()).getTime()) return false;
  return true;
}
validatorsI18N['en']['DATE_DD_MM_AAAA_FUTURE_HOY'] = 'It has to be a date after yesterday in dd/mm/aaaa format';
validatorsI18N['es']['DATE_DD_MM_AAAA_FUTURE_HOY'] = 'Tiene que ser una fecha posterior o igual a hoy en formato dd/mm/aaaa';

validators['DATE_DD_MM_AAAA_PAST'] = function (date )
{
  var aoDate = date.split("/");
  if (aoDate.length !== 3) return false;
  var day = parseInt(aoDate[0], 10);
  var month = parseInt(aoDate[1], 10) - 1;
  var year = parseInt(aoDate[2], 10);
  var ms = (new Date(year, month, day)).getTime();
  aoDate = new Date();
  aoDate.setTime(ms);
  // Lo obtenido es igual a lo pasaso
  if (aoDate.getFullYear() !== year || aoDate.getMonth() !== month || aoDate.getDate() !== day) {
    return false;
  }
  // Tiene que ser posterior a hoy
  if (ms > (new Date()).getTime()) return false;
  return true;
}
validatorsI18N['en']['DATE_DD_MM_AAAA_PAST'] = 'It has to be a date before today in dd/mm/aaaa format';
validatorsI18N['es']['DATE_DD_MM_AAAA_PAST'] = 'Tiene que ser una fecha anterior a hoy en formato dd/mm/aaaa';

validators['DATE_DD_MM_AAAA'] = function (date )
{
  var aoDate = date.split("/");
  if (aoDate.length !== 3) return false;
  var day = parseInt(aoDate[0], 10);
  var month = parseInt(aoDate[1], 10) - 1;
  var year = parseInt(aoDate[2], 10);
  var ms = (new Date(year, month, day)).getTime();
  aoDate = new Date();
  aoDate.setTime(ms);
  // Lo obtenido es igual a lo pasaso
  if (aoDate.getFullYear() !== year || aoDate.getMonth() !== month || aoDate.getDate() !== day) {
    return false;
  }
  return true;
}
validatorsI18N['en']['DATE_DD_MM_AAAA'] = 'It has to be a date in dd/mm/aaaa format';
validatorsI18N['es']['DATE_DD_MM_AAAA'] = 'Tiene que ser una fecha en formato dd/mm/aaaa';

// EMAIL

validators['EMAIL'] = function ( email )
{
  var re = /^[a-zA-Z0-9\-\_\.]+\@([a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4})$/;
  if ( !re.test ( email ) )
  {
    return false;
  }
  else
  {
    return true;
  }
}
validatorsI18N['en']['EMAIL'] = 'It has to be a valid email';
validatorsI18N['es']['EMAIL'] = 'Tiene que ser un email válido';

// PHONENUMBER
validators['PHONENUMBER'] = function( tlf )
{
  tlf = tlf.replace ( /\s/g , '' );
  if ( !/^\d{9}$/.test ( tlf ) && !/^\+\d{1,3}\d{9}$/.test ( tlf ) )
  {
    return false;
  }
  else
  {
    return true;
  }
}
validatorsI18N['en']['PHONENUMBER'] = 'It has to ve a valid phone number';
validatorsI18N['es']['PHONENUMBER'] = 'Tiene que ser un número de teléfono válido';

// CIFNIF
validators['CIFNIF'] = function( doc )
{
  return validators['NIF'] ( doc ) || validators['CIF'] ( doc ) ;
}
validatorsI18N['en']['CIFNIF'] = 'It has to be a valid NIF/NIE or CIF';
validatorsI18N['es']['CIFNIF'] = 'Tiene que ser un NIF/NIE o CIF válido';

validators['CIF'] = function ( cif ) 
{
  cif = cif.toUpperCase(); 
  
  if ( !/^[A-Za-z0-9]{9}$/.test ( cif ) ) // Son 9 dígitos?
   {
     return false;
   }
   if ( !/^[ABCDEFGHJKLMNPRQSUVW]/.test ( cif ) ) 
   {
     return false;
   }
   
   var v1 = new Array ( 0 , 2 , 4 , 6 , 8 , 1 , 3 , 5 , 7 , 9 ); 
   var temp = 0;
   
   for( i = 2; i <= 6; i += 2 ) 
   {
     temp = temp + v1 [ parseInt ( cif.substr ( i-1 , 1 ) ) ];
     temp = temp + parseInt ( cif.substr ( i , 1 ) );
   };
   
   temp = temp + v1 [ parseInt ( cif.substr ( 7 , 1 ) ) ];
   temp = ( 10 - ( temp % 10 ) );
   
   if( temp == 10 )
   {
     if ( cif.charAt ( cif.length - 1 ) == 'J' || cif.charAt ( cif.length - 1 ) == '0' )
     {
       return true;
     }
     else
     {
       return false;
     }
   }
   else
   {
     if ( cif.charAt ( cif.length - 1 ) ==  temp || cif.charAt ( cif.length - 1 ) == String.fromCharCode ( 64 + temp ) )
     {
       return true;
     }
     else
     {
       return false;
     }
   }
   return false;
}
validatorsI18N['en']['CIF'] = 'It has to be a valid CIF';
validatorsI18N['es']['CIF'] = 'Tiene que ser un CIF válido';

validators['NIF'] = function ( nif )
{
  nif = nif.toUpperCase();
  var exp = new RegExp ( "^(\\d+)\-?([A-Z])$" );
  if ( 'TXYZ'.indexOf ( nif.charAt ( 0 ) ) != -1 )
  {
    if ( nif.charAt ( 0 ) == 'Y' )
    {
      nif = '1' + nif.substr ( 1 );
    }
    else if ( nif.charAt ( 0 ) == 'Z' )
    {
      nif = '2' + nif.substr ( 1 );
    }
    else
    {
      nif = nif.substring ( 1 );
    }
  }
  var res = exp.exec ( nif );
  if ( res == null || res.index != 0 )
  {
    return false;
  }
  var numero = parseInt ( res[1] , 10 );
  var letra = res[2];
  return 'TRWAGMYFPDXBNJZSQVHLCKET'.charAt ( numero % 23 ) == letra;
}
validatorsI18N['en']['NIF'] = 'It has to be a valid NIF/NIE';
validatorsI18N['es']['NIF'] = 'Tiene que ser un NIF/NIE válido';

// CC

validators['CCSum'] = function ( cad )
{
  var pesos = [ 6 , 3 , 7 , 9 , 10 , 5 , 8 , 4 , 2 , 1 ];
  var sum = 0;
  var nums = cad.split ( '' );
  for ( i = 0 ; i < nums.length ; i++ )
  {
    sum += parseInt ( nums[nums.length - 1 - i ] , 10 ) * pesos[i];
  }
  var dc = 11 - ( sum % 11 );
  if ( dc == 11 )
  {
    dc = 0;
  }
  else if ( dc == 10 )
  {
    dc = 1;
  }
  return dc;
}

validators['CC'] = function ( cuenta )
{
  cuenta = cuenta.replace ( /\D/g , "" );
  
  if ( !/^\d{20}$/.test ( cuenta ) )
  {
    return false;
  }
  var ent = cuenta.substr ( 0 , 4 );
  var ofi = cuenta.substr ( 4 , 4 );;
  var dc = cuenta.substr ( 8 , 2 );
  var cc = cuenta.substr ( 10 );
  if ( dc == String ( validators['CCSum'] ( ent + ofi ) ) + String ( validators['CCSum'] ( cc ) ) )
  {
    return true;
  }
  else
  {
    return false;
  }
}
validatorsI18N['en']['CC'] = 'It has to be a valid bank account';
validatorsI18N['es']['CC'] = 'Tiene que ser un número de cuenta válido';

validators['IBAN'] = function ( iban )
{
    iban = iban.toUpperCase();
    iban = iban.replace(/^IBAN/, "");
    iban = iban.replace(/[^0-9A-Z]/g, "");
    if ( iban.length != 24 )
    {
        return false;
    }
  
    var num1  = iban.charCodeAt ( 0 ) - 55;
    var num2  = iban.charCodeAt ( 1 ) - 55;
    var check = iban.substring ( 2 , 4 );
    var tmp   = "" + iban.substring ( 4 , iban.length ) + String ( num1 ) + String ( num2 ) + String ( check );
    var resto = mod97(tmp);
    if ( iban.substring ( 0 , 2 ) == 'ES' && resto == 1 )
    {
        return validators['CC'] ( iban.substring ( 4 ) );
    }
    else
    {
        return (resto == 1);
    }
}
validatorsI18N['en']['CC'] = 'It has to be a valid iban';
validatorsI18N['es']['CC'] = 'Tiene que ser un iban válido';

// NUMERIC
validators['NUMERIC'] = function ( num )
{
  return /^\d+\%?$/.test ( num );
}
validatorsI18N['en']['NUMERIC'] = 'It has to be an integer number';
validatorsI18N['es']['NUMERIC'] = 'Tiene que ser un número entero';

// REAL
validators['REAL'] = function ( num )
{
  return /^\d+[\.\,]?\d*\%?$/.test ( num );
}
validatorsI18N['en']['REAL'] = 'It has to be a number';
validatorsI18N['es']['REAL'] = 'Tiene que ser un número';

