/******************************************************
Arquivo para funções javascript que tenham como objetivo  
validação de dados dos formulários.

Lista de funções:
  - isCPF: Verifica se um CPF é válido.
  - isCNPJ: Verifica se um CNPJ é válido.
  - isEmail: Verifica se um Email é válido.
  - isDate: Verifica se uma Data é válida.
  - isTime: Verifica se uma Hora (hh:mm) é válida.
  - isTimeMenor: Verifica se uma hora é menor (ou igual) que a outra
  - isTituloEleitoral: Verifica se um Titulo Eleitoral é válido.
  - isDateMenor: Verifica se uma data é menor do que outra.
  - existeCheckboxMarcado: Verifica se pelo menos 1 opção dos checkbox foi marcada
  - hasOptions: Verifica se um objeto html do tipo Select possui options
  - isOptionValue: Verifica se um string é valor de uma opção de um combo do tipo Select e retorna true se sim ou false se não.
	
TODO:
  - Validar campos no onBlur para evitar que seja copiado valores invalidos para os campos.
    Hoje está passando.
  - Executar o evento de validação dos dados do formulário no onBlur.
    Hoje está validando no submit.
  - Fazer o MaskInput aceitar array, para executar ele apenas uma vez para vários campos.
    Hoje para cada campo precisa ser criado um MaskInput
******************************************************/

/******************************************************
Expressoes Regulares para validação 
******************************************************/


/******************************************************
isCPF(string): Boolean 
Retorna true se o CPF alertdo é válido, caso contrário, false.
******************************************************/
function isCPF(cpf){
    var c = cpf;
    if((c = c.replace(/[^\d]/g,"").split("")).length != 11) return false;
    if(new RegExp("^" + c[0] + "{11}$").test(c.join(""))) return false;
    for(var s = 10, n = 0, i = 0; s >= 2; n += c[i++] * s--);
    if(c[9] != (((n %= 11) < 2) ? 0 : 11 - n)) return false;
    for(var s = 11, n = 0, i = 0; s >= 2; n += c[i++] * s--);
    if(c[10] != (((n %= 11) < 2) ? 0 : 11 - n)) return false;
    return true;
};

/******************************************************
isCNPJ(string): Boolean 
Retorna true se o CNPJ alertdo é válido, caso contrário, false. 
******************************************************/
function isCNPJ(cnpj){
    var b = [6,5,4,3,2,9,8,7,6,5,4,3,2], c = cnpj;
    if((c = c.replace(/[^\d]/g,"").split("")).length != 14) return false;
    for(var i = 0, n = 0; i < 12; n += c[i] * b[++i]);
    if(c[12] != (((n %= 11) < 2) ? 0 : 11 - n)) return false;
    for(var i = 0, n = 0; i <= 12; n += c[i] * b[i++]);
    if(c[13] != (((n %= 11) < 2) ? 0 : 11 - n)) return false;
    return true;
};

/******************************************************
isEmail(string): Boolean 
Retorna true se o email passado é válido, caso contrário, false. 
******************************************************/
function isEmail(email) {
  email.replace(/[^A-Z0-9-\.@_]/gi,"");
  if (email.length<6) {
    return false;
  } else {
    if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) return email.toLowerCase();
    else  return false;
  }
}


/******************************************************
isDate(y: Integer, m: Integer, d: Integer): Integer 
Verifica uma data e retorna 0 se for válida ou um dos códigos de erro abaixo. 
- y: ano 
- m: mês 
- d: dia 
 
isDate(date: String, matcher: RegExp, map: Object): Integer 
Verifica uma data e retorna 0 se for válida ou um dos códigos de erro abaixo. 
- date: Data em forma de string 
- matcher: Expressão regular encarregada de achar e guardar o dia, mês e ano 
- map: Objeto contendo a posição onde se encontra cada componente da data na expressão regular. 
 
Seu formato é o seguinte: {d: posicaoDoDia, m: posicaoDoMes, y: posicaoDoAno} 
Códigos de retorno
0 = Data válida 
1 = Formato de data inválido (regular expression falhou ou quantidade de argumentos != 3) 
2 = Dia não está entre 1 e 31 
3 = Mês não está entre 1 e 12 
4 = Nos meses de abril, junho, setembro e novembro não existe o dia 31 
5 = O mês de fevereiro só tem 28 dias 
6 = Anos bissexto, o mês de fevereiro só tem 29 dias

Exemplos:
    isDate("22/07/1984", /^([0-9]{1,2})[\/]([0-9]{1,2})[\/]([0-9]{1,4})$/, {d: 1, m: 2, y: 3})
    isDate("1984-07-22", /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/, {d: 3, m: 2, y: 1})
    isDate("07-22-1984", /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/, {d: 3, m: 2, y: 1})
    isDate(2000, 1, 32)
    isDate(2000, 0, 1)
    isDate(2000, 4, 31)
    isDate(2001, 2, 29)
    isDate(2004, 2, 30)
******************************************************/
function isDate (y, m, d){
  if(typeof y == "string" && m instanceof RegExp && d){
  	if(!m.test(y)) return 1;
    y = RegExp["$" + d.y], m = RegExp["$" + d.m], d = RegExp["$" + d.d];
  }
  d = Math.abs(d) || 0, m = Math.abs(m) || 0, y = Math.abs(y) || 0;
  return arguments.length != 3 ? 1 : d < 1 || d > 31 ? 2 : m < 1 || m > 12 ? 3 : /4|6|9|11/.test(m) && d == 31 ? 4
    : m == 2 && (d > ((y = !(y % 4) && (y % 1e2) || !(y % 4e2)) ? 29 : 28)) ? 5 + !!y : 0;
};

/******************************************************
isTime(string): Boolean 
Retorna true se a hora passada é válida, caso contrário, false. 
@param string hora - hora no formato hh:mm ou hh:mm:ss
******************************************************/
function isTime(hora){  
  hora.replace(/\./gi,":");
  hora.replace(/[^0-9:]/gi,"");
  if (hora.length < 5 || hora.charCodeAt(2) != 58 || (hora.length > 5 && hora.charCodeAt(5) != 58 ) ) {
    return false;
  } else {
    if (hora.length==5 && /([01][0-9]|2[0-3]):[0-5][0-9]/.test(hora)) {
      	return true;
    } else if(/([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]/.test(hora)){
		return true;
    } else {
      	return false;
    }
  }
}

/******************************************************
isTimeMenor(string,string): Boolean 
Retorna true se a hora1 (hh:mm) é menor que (ou igual) a hora2 (hh:mm), caso contrário, false. 
* Somente funciona para horarios no formato 24h 
******************************************************/
function isTimeMenor(hora1, hora2){

  hora1.replace(/\./gi,":");
  hora1.replace(/[^0-9:]/gi,"");
  hora2.replace(/\./gi,":");
  hora2.replace(/[^0-9:]/gi,"");

  if(!isTime(hora1) || !isTime(hora2)) return false;
  
  var hora1_partes = hora1.split(":");
  var hora2_partes = hora2.split(":");

  if(Number(hora1_partes[0]) > Number(hora2_partes[0])) return false;
  
  if( (Number(hora1_partes[0]) == Number(hora2_partes[0])) && (Number(hora1_partes[1]) > Number(hora2_partes[1]))) return false;
  
  return true;
}

/******************************************************
isTituloEleitoral(string): Boolean 
Retorna true se o Titulo eleitoral é valido, caso contrário, false.
* Código retirado do site do TSE (Tribunal Superior Eleitoral) 
******************************************************/
function isTituloEleitoral(tit) { 

  var retorno2 = true;
  var titulo = tit;
  var multiplicador = 10;
  var soma = 0;
  var dv1 = 0;
  var dv2 = 0;
  var numAux = 0;
  var dv = "";
  var resto = 0;

  titulo.replace(/[^\d]/g,"");

  if(tit.length == 11) { titulo = "000" + titulo;}
  
  if(tit.length == 12) {titulo = "00" + titulo;}

  //INICIO DA VALIDACAO DO PRIMEIRO DIGITO
  for(i = 1; i <= 9; i++) {
    soma = soma + titulo.charAt(i) * multiplicador;
    multiplicador--;
  }

  resto = soma % 11;
  if((titulo.substring(10,12) == "01") || (titulo.substring(10,12) == "02") ) {
    if(resto == 0){dv1 = 1;}
    if(resto == 1){dv1 = 0;}
    if( (resto != 0) && (resto != 1) ) {dv1 = 11 - resto;}
  }
  else {
    if( (resto == 0) || (resto == 1) ) {dv1 = 0;}
    else {dv1 = 11 - resto;}
  }

  // INICIO DA VALIDACAO DO SEGUNDO DIGITO
  soma = (titulo.charAt(10) * 4) + (titulo.charAt(11) * 3) + (dv1 * 2);
  resto = soma % 11;

  if( (titulo.substring(10, 12) == "01") || (titulo.substring(10, 12) == "02") ) {
    if(resto == 0) {dv2 = 1;}
    if(resto == 1) {dv2 = 0;}
  }
  else {
    if( (resto == 0) || (resto == 1) ) {dv2 = 0;}
    else {dv2 = 11 - resto;}
  }

  //VERIFICA OS DOIS DIGITOS VERIFICADORES
  if( (dv1 == titulo.charAt(12) ) && (dv2 == titulo.charAt(13)) ) {
    retorno2 = true;
  }
  else {retorno2 = false;}

  return retorno2;
} 

/**
* Verifica se uma data Da é menor do que data data Db.
* @param mixed - Da Date ou String
* @param mixed - Db Date ou String
* @return bool - retorna true se Da for menor que Db ou false caso contrário e null caso os parametros não forem passados corretamente.
*/
function isDateMenor(Da,Db){
	if(Da instanceof Date && Db instanceof Date){
		//var ano = Da.getFullYear();var mes = Da.getMonth();var dia = Da.getDate();var Bano = Db.getFullYear();var Bmes = Db.getMonth();var Bdia = Db.getDate();alert('Da: '+dia+'/'+mes+'/'+ano+' Da: '+Bdia+'/'+Bmes+'/'+Bano);				
		if(Da-Db < 0) return true;
		else return false;
	}else if(typeof(Da)=="string" && typeof(Db)=="string"){
		var anoDa = parseInt(Da.substr(6,4),10);  
		var mesDa = parseInt(Da.substr(3,2),10); 
		var diaDa = parseInt(Da.substr(0,2),10);
		//alert(diaDa+"/"+mesDa+"/"+anoDa);
		var anoDb = parseInt(Db.substr(6,4),10);  
		var mesDb = parseInt(Db.substr(3,2),10); 
		var diaDb = parseInt(Db.substr(0,2),10);
		/*data menor quando
		1-> ano é menor que outro
		2-> ano é igual mas o mês é menor que outro
		3-> dia é menor que outro
		*/
		if(anoDa < anoDb) return true;
		else if(anoDa > anoDb) return false;
		else if(mesDa < mesDb) return true;
		else if(mesDa < mesDb) return false;
		else if(diaDa < diaDb) return true;
		else return false;		
	}else return null;
}

/**
* Função que verifica se pelo menos 1 opção dos checkbox foi marcada. Se nenhuma for marcada retorna false ou true caso contrário.
* @return boolean
*/
function existeCheckboxMarcado(f, chknome){

  for(i=0;i<f.elements.length;i++){
    if(f.elements[i].type== 'checkbox' ) {
    
      if( f.elements[i].name == chknome && f.elements[i].checked == true ) return true;
    }
  }

  return false;
}



function hasOptions(obj) {
	if (obj!=null && obj.options!=null) { return true; }
	return false;
}

/**
* Verifica se um string é valor de uma opção de um combo do tipo select e retorna true se sim ou false se não.
* @param string idSelect - propriedade id do objeto select
* @param string vlr      - string que se quer verificar se é valor de opção do objeto select.
* @return boolean
*/
function isOptionValue(idSelect,vlr){
	obj = document.getElementById(idSelect);
	if(hasOptions(obj)){
		for (var i=0; i<obj.options.length; i++) {
			if(obj.options[i].value==vlr)return true;	
		}
	}	
	return false;
}
