﻿/**
 * @author Márcio d'Ávila
 * @version 1.03, 2004-2008
 *
 * Adaptado por Marcos Guedes
 * Data: 21/04/2010
 *
 * Este script foi retirado de:
 * http://www.mhavila.com.br/topicos/web/cpf_cnpj.html
 *
 * Licenciado sob os termos da licença Creative Commons,
 * Atribuição - Compartilhamento pela mesma licença 2.5:
 * http://creativecommons.org/licenses/by-sa/2.5/br/
 * Qualquer outra forma de uso requer autorização expressa do autor.
 *
 * PROTÓTIPOS:
 * método String.lpad(int pSize, char pCharPad)
 * método String.trim()
 *
 * String unformatNumber(String pNum)
 * String formatCpfCnpj(String pCpfCnpj, boolean pUseSepar, boolean pIsCnpj)
 * String dvCpfCnpj(String pEfetivo, boolean pIsCnpj)
 * boolean isCpf(String pCpf)
 * boolean isCnpj(String pCnpj)
 * boolean isCpfCnpj(String pCpfCnpj)
 */


function Validacao()
{
	NUM_DIGITOS_CPF  = 11;
	NUM_DIGITOS_CNPJ = 14;
	NUM_DGT_CNPJ_BASE = 8;


	/**
	 * Adiciona método lpad() à classe String.
	 * Preenche a String à esquerda com o caractere fornecido,
	 * até que ela atinja o tamanho especificado.
	 */
	String.prototype.lpad = function(pSize, pCharPad)
	{
		var str = this;
		var dif = pSize - str.length;
		var ch = String(pCharPad).charAt(0);
		for (; dif>0; dif--) str = ch + str;
		return (str);
	} //String.lpad


	/**
	 * Adiciona método trim() à classe String.
	 * Elimina brancos no início e fim da String.
	 */
	String.prototype.trim = function()
	{
		return this.replace(/^\s*/, "").replace(/\s*$/, "");
	} //String.trim


	/**
	 * Elimina caracteres de formatação e zeros à esquerda da string
	 * de número fornecida.
	 * @param String pNum
	 * 	String de número fornecida para ser desformatada.
	 * @return String de número desformatada.
	 */
	function unformatNumber(pNum)
	{
		return String(pNum).replace(/\D/g, "").replace(/^0+/, "");
	} //unformatNumber


	/**
	 * Formata a string fornecida como CNPJ ou CPF, adicionando zeros
	 * à esquerda se necessário e caracteres separadores, conforme solicitado.
	 * @param String pCpfCnpj
	 * 	String fornecida para ser formatada.
	 * @param boolean pUseSepar
	 * 	Indica se devem ser usados caracteres separadores (. - /).
	 * @param boolean pIsCnpj
	 * 	Indica se a string fornecida é um CNPJ.
	 * 	Caso contrário, é CPF. Default = false (CPF).
	 * @return String de CPF ou CNPJ devidamente formatada.
	 */
	function formatCpfCnpj(pCpfCnpj, pUseSepar, pIsCnpj)
	{
		if (pIsCnpj==null) pIsCnpj = false;
		if (pUseSepar==null) pUseSepar = true;
		var maxDigitos = pIsCnpj? NUM_DIGITOS_CNPJ: NUM_DIGITOS_CPF;
		var numero = unformatNumber(pCpfCnpj);
	
		numero = numero.lpad(maxDigitos, '0');
	
		if (!pUseSepar) return numero;
	
		if (pIsCnpj)
		{
			reCnpj = /(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/;
			numero = numero.replace(reCnpj, "$1.$2.$3/$4-$5");
		}
		else
		{
			reCpf  = /(\d{3})(\d{3})(\d{3})(\d{2})$/;
			numero = numero.replace(reCpf, "$1.$2.$3-$4");
		}
		return numero;
	} //formatCpfCnpj


	/**
	 * Calcula os 2 dígitos verificadores para o número-efetivo pEfetivo de
	 * CNPJ (12 dígitos) ou CPF (9 dígitos) fornecido. pIsCnpj é booleano e
	 * informa se o número-efetivo fornecido é CNPJ (default = false).
	 * @param String pEfetivo
	 * 	String do número-efetivo (SEM dígitos verificadores) de CNPJ ou CPF.
	 * @param boolean pIsCnpj
	 * 	Indica se a string fornecida é de um CNPJ.
	 * 	Caso contrário, é CPF. Default = false (CPF).
	 * @return String com os dois dígitos verificadores.
	 */
	function dvCpfCnpj(pEfetivo, pIsCnpj)
	{
		if (pIsCnpj==null) pIsCnpj = false;
		var i, j, k, soma, dv;
		var cicloPeso = pIsCnpj? NUM_DGT_CNPJ_BASE: NUM_DIGITOS_CPF;
		var maxDigitos = pIsCnpj? NUM_DIGITOS_CNPJ: NUM_DIGITOS_CPF;
		var calculado = formatCpfCnpj(pEfetivo + "00", false, pIsCnpj);
		calculado = calculado.substring(0, maxDigitos-2);
		var result = "";
	
		for (j = 1; j <= 2; j++)
		{
			k = 2;
			soma = 0;
			for (i = calculado.length-1; i >= 0; i--)
			{
				soma += (calculado.charAt(i) - '0') * k;
				k = (k-1) % cicloPeso + 2;
			}
			dv = 11 - soma % 11;
			if (dv > 9) dv = 0;
			calculado += dv;
			result += dv
		}
	
		return result;
	} //dvCpfCnpj


	/**
	 * Testa se a String pCpf fornecida é um CPF válido.
	 * Qualquer formatação que não seja algarismos é desconsiderada.
	 * @param String pCpf
	 * 	String fornecida para ser testada.
	 * @return <code>true</code> se a String fornecida for um CPF válido.
	 */
	this.isCpf = function(pCpf)
	{
		var numero = formatCpfCnpj(pCpf, false, false);
		if (numero.length > NUM_DIGITOS_CPF) return false;

		var base = numero.substring(0, numero.length - 2);
		var digitos = dvCpfCnpj(base, false);
		var algUnico, i;

		// Valida dígitos verificadores
		if (numero != "" + base + digitos) return false;

		/* Não serão considerados válidos os seguintes CPF:
		 * 000.000.000-00, 111.111.111-11, 222.222.222-22, 333.333.333-33, 444.444.444-44,
		 * 555.555.555-55, 666.666.666-66, 777.777.777-77, 888.888.888-88, 999.999.999-99.
		 */
		algUnico = true;
		for (i=1; algUnico && i<NUM_DIGITOS_CPF; i++)
		{
			algUnico = (numero.charAt(i-1) == numero.charAt(i));
		}
		return (!algUnico);
	} //isCpf


	/**
	 * Testa se a String pCnpj fornecida é um CNPJ válido.
	 * Qualquer formatação que não seja algarismos é desconsiderada.
	 * @param String pCnpj
	 * 	String fornecida para ser testada.
	 * @return <code>true</code> se a String fornecida for um CNPJ válido.
	 */
	this.isCnpj = function(pCnpj)
	{
		var numero = formatCpfCnpj(pCnpj, false, true);
		if (numero.length > NUM_DIGITOS_CNPJ) return false;

		var base = numero.substring(0, NUM_DGT_CNPJ_BASE);
		var ordem = numero.substring(NUM_DGT_CNPJ_BASE, 12);
		var digitos = dvCpfCnpj(base + ordem, true);
		var algUnico;
	
		// Valida dígitos verificadores
		if (numero != "" + base + ordem + digitos) return false;

		/* Não serão considerados válidos os CNPJ com os seguintes números BÁSICOS:
		 * 11.111.111, 22.222.222, 33.333.333, 44.444.444, 55.555.555,
		 * 66.666.666, 77.777.777, 88.888.888, 99.999.999.
		 */
		algUnico = numero.charAt(0) != '0';
		for (i=1; algUnico && i<NUM_DGT_CNPJ_BASE; i++)
		{
			algUnico = (numero.charAt(i-1) == numero.charAt(i));
		}
		if (algUnico) return false;

		/* Não será considerado válido CNPJ com número de ORDEM igual a 0000.
		 * Não será considerado válido CNPJ com número de ORDEM maior do que 0300
		 * e com as três primeiras posições do número BÁSICO com 000 (zeros).
		 * Esta crítica não será feita quando o no BÁSICO do CNPJ for igual a 00.000.000.
		 */
		if (ordem == "0000") return false;
		return (base == "00000000"
			|| parseInt(ordem, 10) <= 300 || base.substring(0, 3) != "000");
	} //isCnpj


	/**
	 * Testa se a String pCpfCnpj fornecida é um CPF ou CNPJ válido.
	 * Se a String tiver uma quantidade de dígitos igual ou inferior
	 * a 11, valida como CPF. Se for maior que 11, valida como CNPJ.
	 * Qualquer formatação que não seja algarismos é desconsiderada.
	 * @param String pCpfCnpj
	 * 	String fornecida para ser testada.
	 * @return <code>true</code> se a String fornecida for um CPF ou CNPJ válido.
	 */
	//function isCpfCnpj(pCpfCnpj)
	this.isCpfCnpj = function(pCpfCnpj)
	{
		var numero = pCpfCnpj.replace(/\D/g, "");
		if (numero.length > NUM_DIGITOS_CPF)
			return this.isCnpj(pCpfCnpj)
		else
			return this.isCpf(pCpfCnpj);
	} //isCpfCnpj
	
	/**
	 * = Adaptado por Marcos Guedes =
	 * Verifica se um valor especificado é uma data válida
	 * @param String strData
	 * 	String fornecida para ser testada.
	 * @return <code>true</code> se a String fornecida for uma data válida.
	 */
	this.isData = function(strData)	
	{
		var ardt=new Array;
		var ExpReg=new RegExp("(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/[12][0-9]{3}");
	
		ardt=strData.split("/");	
	
		if ( strData.search(ExpReg)==-1)
			return false;
		
		if (((ardt[1]==4)||(ardt[1]==6)||(ardt[1]==9)||(ardt[1]==11))&&(ardt[0]>30))
			return false;

		if ( (ardt[1]==2) && ( ((ardt[0]>28)&&((ardt[2]%4)!=0)) || ((ardt[0]>29)&&((ardt[2]%4)==0)) ) )
			return false;

		return true;
	} //isData
	
	this.isEmail = function(str){
		var filter = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
	
		if(filter.test(str))
			return true;

    	return false;
	}
}
