/**
@name CpfCnpj.js
@description Formata e valida cpfs e cnpjs
@methods pfnFormateCNPJ, pfnFormateCNPJOnBlur, pfnFormateValorCNPJ, pfnValideCNPJ, pfnValideFormatacaoCNPJ,
 pfnFormateCPF, pfnFormateCPFOnBlur, pfnFormateValorCPF, pfnValideCPF, pfnValideFormatacaoCPF
@created 12/12/2003
@author Jorge Bittencourt
*/


//*************************************************************************************************************
/**
@name pfnFormateCNPJ
@description Formata um cnpj à medida que o usuário digita os números
 Só permite que o usuário digite números
@created 12/12/2003
@param input: o campo onde o cnpj está sendo digitado
@return Não retorna nada
@author Jorge Bittencourt
*/
function pfnFormateCNPJ(input)
{
	var cnpj = input.value;
	
	if (cnpj.length != 0)
	{
			
		// só formate caso o usuário digite números
		if ((event.keyCode < 96 || event.keyCode > 105) && (event.keyCode < 48 || event.keyCode > 57))
			return;
			
		if (cnpj.length == 2 || cnpj.length == 6)
			cnpj = input.value + "." ;
		else if (cnpj.length == 10)
			cnpj = input.value + "/"
		else if (cnpj.length == 15)
			cnpj = input.value + "-" ;
			
		input.value = cnpj;
	}
}	


//*************************************************************************************************************
/**
@name pfnFormateCNPJOnBlur
@description Formata um cnpj quando o campo perde o foco. Leva em consideração que o cnpj pode já estar
 formatado, caso o usuário tenha digitado o número um a um. Mas caso o usuário tenha feito um
 paste no campo, o número poderá estar desformatado e será formatado por essa função
@created 12/12/2003
@param input: o campo onde o cpf está sendo digitado
@return Não retorna nada
@author Jorge Bittencourt
*/
function pfnFormateCNPJOnBlur(input)
{
	// recupere o valor do input e chame a função de formatação
	input.value = pfnFormateValorCNPJ(input.value)	
}
	

//*************************************************************************************************************
/**
@name pfnFormateValorCNPJ
@description Formata um número de cnpj fornecido
@created 07/01/2004
@param valorCnpj: o número de cnpj
@return Não retorna nada
@author Jorge Bittencourt
*/
function pfnFormateValorCNPJ(valorCnpj)
{
	// faça uma cópia do parâmetro
	var cnpj = valorCnpj;
	
	if (!pfnValideFormatacaoCNPJ(cnpj))
	{
		// retire todos os caracteres que não são inteiros do input
		cnpj = cnpj.replace(/\D/g, "");
		
		// se cnpj não tiver 14 caracteres, a validação falha
		if (cnpj.length != 14)
			return valorCnpj;
		
		// há 15 dígitos - formate o cpf
		cnpj = cnpj.substr(0, 2) + "." + cnpj.substr(2, 3) + "." + cnpj.substr(5, 3) + "/" + cnpj.substr(8, 4) + "-" +
			cnpj.substr(12, 2);
	}
	
	return cnpj;
}

				
//*************************************************************************************************************
/**
@name pfnValideCNPJ
@description Valida um número de cnpj (em um input). O número precisa estar formatado corretamente
@created 12/12/2003
@param input: o campo onde o cnpj está sendo digitado
@return true, caso o número seja válido, false, caso contrário
@author Jorge Bittencourt
*/
function pfnValideCNPJ(input)
{
	return pfnValideValorCNPJ(input.value);
}


//*************************************************************************************************************
/**
@name pfnValideValorCNPJ
@description Valida um número de cnpj. O número precisa estar formatado corretamente
@created 12/12/2003
@param s: o número cnpj
@return true, caso o número seja válido, false, caso contrário
@author Jorge Bittencourt
*/
function pfnValideValorCNPJ(s)
{
	if (!pfnValideFormatacaoCNPJ(s))
		return false;
		
	// retire todos os caracteres não-numéricos
	s = s.replace(/\D/g, "");

	var i;
	var c = s.substr(0,12);
	var dv = s.substr(12,2);
	var d1 = 0;

	for (i = 0; i < 12; i++)
		d1 += c.charAt(11-i)*(2+(i % 8));

	if (d1 == 0)
		return false;

	d1 = 11 - (d1 % 11);
	if (d1 > 9)
		d1 = 0;

	if (dv.charAt(0) != d1)
		return false;

	d1 *= 2;
	for (i = 0; i < 12; i++)
		d1 += c.charAt(11-i)*(2+((i+1) % 8));

	d1 = 11 - (d1 % 11);
	if (d1 > 9)
		d1 = 0;

	if (dv.charAt(1) != d1)
		return false;

	return true;
}


//*************************************************************************************************************
/**
@name pfnValideFormatacaoCNPJ
@description Valida se um número de cnpj está formatado corretamente
@created 12/12/2003
@param numCnpj: o valor a ser validado
@return true, caso o número esteja formatado corretamente, falso, caso contrário
@author Jorge Bittencourt
*/
function pfnValideFormatacaoCNPJ(numCnpj)
{
	if (numCnpj.length == 0 || numCnpj.length < 14 || numCnpj.length > 18)
		return false;
		
	var partes;
	var partes1;
	partes = numCnpj.split("/");
	// verifique se há duas partes - antes e depois da barra
	if (partes.length != 2)
		return false;
		
	// verifique se há três grupos de caracteres antes da barra separados por pontos
	partes1 = partes[0].split(".");
	if (partes1.length != 3)
		return false;
	
	// verifique se o número de caracteres entre cada ponto tem o tamanho certo
	if (partes1[0].length != 2 || partes1[1].length != 3 || partes1[2].length != 3)
		return false;
	// verifique se os caracteres são todos dígitos 
	if (isNaN(partes1[0]) || isNaN(partes1[1]) || isNaN(partes1[2]))
		return false;

	// verifique se há dois grupos de caracteres depois da barra separados por um traço
	partes1 = partes[1].split("-");
	if (partes1.length != 2)
		return false;
		
	// verifique se o número de caracteres entre o traço tem o tamanho certo
	if (partes1[0].length != 4 || partes1[1].length != 2)
		return false;
	// verifique se os caracteres são todos dígitos 
	if (isNaN(partes1[0]) || isNaN(partes1[1]))
		return false;
	
	return true;
}


//*************************************************************************************************************
/**
@name pfnFormateCPF
@description Formata um cpf à medida que o usuário digita os números
 Só permite que o usuário digite números
@created 12/12/2003
@param input: o campo onde o cpf está sendo digitado
@return Não retorna nada
@author Jorge Bittencourt
*/
function pfnFormateCPF(input)
{
	var cpf = input.value;
	
	if (cpf.length != 0)
	{			
		// só formate caso o usuário digite números
		if ((event.keyCode < 96 || event.keyCode > 105) && (event.keyCode < 48 || event.keyCode > 57))
			return;
			
		// acrescente os pontos e os dígitos aos números digitados
		if (cpf.length == 3 || cpf.length == 7)
			cpf = input.value + "." ;
		else if (cpf.length == 11)
			cpf = cpf + "-" ;
		
		input.value = cpf;
	}
}		


//*************************************************************************************************************
/**
@name pfnFormateCPFOnBlur
@description Formata um cpf quando o campo perde o foco. Leva em consideração que o cpf pode já estar
 formatado, caso o usuário tenha digitado o número um a um. Mas caso o usuário tenha feito um
 paste no campo, o número poderá estar desformatado e será formatado por essa função.
 Essa função remove todos os caracteres não-numéricos e verifica se há 11 dígitos. Caso haja,
 formata o cpf. Caso contrário, deixa os valores originais no campo e retorna falso
@created 12/12/2003
@param input: o campo onde o cpf está sendo digitado
@return Não retorna nada
@author Jorge Bittencourt
*/
function pfnFormateCPFOnBlur(input)
{
	// recupere o valor do campo e chame a função de formatação do cpf
	input.value = pfnFormateValorCPF(input.value);
}


//*************************************************************************************************************
/**
@name pfnFormateValorCPF
@description Formata um número de cpf fornecido
@created 12/12/2003
@param valorCpf: o valor do cpf fornecido
@return o valor do cpf formatado - caso o número não tenha 11 dígitos, retorne o valor original (valorCpf)
@author Jorge Bittencourt
*/
function pfnFormateValorCPF(valorCpf)
{
	// faça uma cópia do parâmetro
	var cpf = valorCpf;
	
	// só formate caso o cpf não esteja formatado corretamente
	if (!pfnValideFormatacaoCPF(cpf))
	{
		// retire todos os caracteres que não são inteiros do input
		cpf = cpf.replace(/\D/g, "");
		
		// se cpf não tiver 11 caracteres, a validação falha
		if (cpf.length != 11)
			return valorCpf;
		
		// há 11 dígitos - formate o cpf
		cpf = cpf.substr(0, 3) + "." + cpf.substr(3, 3) + "." + cpf.substr(6, 3) + "-" + cpf.substr(9, 2);
	}
	
	return cpf;
}
				

//*************************************************************************************************************
/**
@name pfnValideCPF
@description Valida um número de cpf (contido em um input). O número precisa estar formatado corretamente
@created 12/12/2003
@param input: o campo onde o cpf está sendo digitado
@return true, caso o número seja válido, false, caso contrário
@author Jorge Bittencourt
*/
function pfnValideCPF(input)
{
	return pfnValideValorCPF(input.value);
}


//*************************************************************************************************************
/**
@name pfnValideValorCPF
@description Valida um número de cpf. O número precisa estar formatado corretamente
@created 12/12/2003
@param numcpf: o número de cpf (corretamente formatado)
@return true, caso o número seja válido, false, caso contrário
@author Jorge Bittencourt
*/
function pfnValideValorCPF(numcpf)
{
	var result = false;
	
	if (!pfnValideFormatacaoCPF(numcpf))
		return false;
	
	// retire os caracteres não-numéricos
	numcpf = numcpf.replace(/\D/g, "");

	var x = 0;
	var soma = 0;
	var dig1 = 0;
	var dig2 = 0;
	var texto = "";
	var numcpf1 = "";
	var len = numcpf.length;
	var totaligual = 0;

	for (var wx=0; wx <= len; wx++)
		if( numcpf.substring(wx,wx+1) == numcpf.substring(0,1)) { totaligual++;}

	if ( totaligual != 11 ) {
		x = len - 1;
		for (var i=0; i <= len - 3; i++)
		{
			y = numcpf.substring( i, i+1 );
			soma = soma + (y * x);
			x = x - 1;
			texto = texto + y;
      }
	}

	dig1 = 11 - (soma % 11);
	if (dig1 == 10)
		dig1=0 ;
	if (dig1 == 11)
		dig1=0 ;
	numcpf1 = numcpf.substring(0,len - 2) + dig1 ;
	x = 11; soma=0;
	for (var i=0; i <= len - 2; i++)
	{
		soma = soma + (numcpf1.substring(i,i+1) * x);
		x = x - 1;
	}
	dig2= 11 - (soma % 11);
	if (dig2 == 10)
		dig2=0;
	if (dig2 == 11)
		dig2=0;

	if ((dig1 + "" + dig2) == numcpf.substring(len,len-2))
		result = true;

	return result;
}


//*************************************************************************************************************
/**
@name pfnValideFormatacaoCPF
@description Valida se um número de cpf está formatado corretamente
@created 12/12/2003
@param numcpf: o valor a ser validado
@return true, caso o número esteja formatado corretamente, falso, caso contrário
@author Jorge Bittencourt
*/
function pfnValideFormatacaoCPF(numcpf)
{
	// se o número for uma string vazia, retorne erro
	if (numcpf.length == 0 && numcpf.length < 11 || numcpf.length > 14)
		return false;
		
	var partes;
	partes = numcpf.split("-");
	// verifique se há duas partes - antes e depois do traço
	if (partes.length != 2)
		return false;
	// verifique se os caracteres depois do traço são numéricos
	if (isNaN(partes[1]))
		return false;
		
	// verifique se há três grupos de caracteres antes do traço separados por pontos
	partes = partes[0].split(".");
	if (partes.length != 3)
		return false;
	
	// verifique se o número de caracteres entre cada ponto tem o tamanho certo
	if (partes[0].length != 3 || partes[1].length != 3 || partes[2].length != 3)
		return false;
	// verifique se os caracteres são todos dígitos 
	if (isNaN(partes[0]) || isNaN(partes[1]) || isNaN(partes[2]))
		return false;

	return true;
}