/******************************************************
Arquivo para funções javascript que tenham como objetivo o 
mascaramento e 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.
  - printException: Emite uma caixa de alerta com a exception gerada.
	- isDateMenor: Verifica se uma data é menor do que outra.
	
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 
******************************************************/
var regexSobrenome = new RegExp("^[a-zA-ZàáâãèéêìíîòóôõüùúûñçÇÀÁÂÃÈÉÊÌÍÎÒÓÔÕÜÙÚÛÑ]+( [a-zA-ZàáâãèéêìíîòóôõüùúûñçÇÀÁÂÃÈÉÊÌÍÎÒÓÔÕÜÙÚÛÑ]+)+$");
    


/******************************************************
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 alertdo é 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 (hh:mm) alertda é válida, caso contrário, false. 
******************************************************/
function isTime(hora){
  hora.replace(/\./gi,":");
  hora.replace(/[^0-9:]/gi,"");
  if (hora.length!=5 || hora.indexOf(":")<1) {
    return false;
  } else {
    if (/([01][0-9]|2[0-3]):[0-5][0-9]/.test(hora)) {
      return hora;
    } 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;
} 


/**
* Emite uma caixa de alerta com a exception gerada.
* @param e Exception 
*/
function printException(e){
	alert('Erro: '+e.message);
}



/**
* Função que verifica se pelo menos 1 opção da listagem de etiqueta foi marcada. Se nenhum 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;
}


/**
* Método para verificar se o telefoné válido.
* @param string f - número de telefone
* @return bool - true se válido e false se não válido.
*/
function isTelefone(f){
	var f ;
	if(f.length>=7) return true;
	else return false;
}

/**
* Verifica se uma data é menor do que outra.
* @param Date - Da
* @param Date - Db
* @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 return null;
}


/**
* Ordena combo-boxes sem caso sensitivo
* @param Object - obj com o objeto referente ao combo que deseja ordenar
*/
function hasOptions(obj) {
	if (obj!=null && obj.options!=null) { return true; }
	return false;
}
function sortSelect(obj) {
	var o = new Array();
	if (!hasOptions(obj)) { return; }
	for (var i=0; i<obj.options.length; i++) {
		o[o.length] = new Option( obj.options[i].text, obj.options[i].value, obj.options[i].defaultSelected, obj.options[i].selected) ;
		}
	if (o.length==0) { return; }
	o = o.sort( 
		function(a,b) { 
			if ((a.text.toLowerCase()+"") < (b.text.toLowerCase()+"")) { return -1; }
			if ((a.text.toLowerCase()+"") > (b.text.toLowerCase()+"")) { return 1; }
			return 0;
			} 
		);

	for (var i=0; i<o.length; i++) {
		obj.options[i] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
		}
}

