/****************************************************************************************************************************
:: Autor: Paulo Segundo
:: Email: paulosegundo@gmail.com
:: Data: 10/01/2006
/****************************************************************************************************************************

/****************************************************************************************************************************
:: Classe: Mascaras
:: Descrição: Classe utilizada para a aplicação de máscaras e validação de formulário.
			  A utlização é feita por atributos que são colocados nos elementos do
			  formulário.
:: Pré-Condições:  O método onload do elemento body deve chamar o método carregar
					da classe Mascaras.
					Ex: <body onload="Mascaras.carregar()">
:: Atributos:
	- mascara="" 										O caracter # (sustenido) da máscara será substituído pelos  caracteres
														digitados pelo usuário.

	- orientacao="Esquerda|Direita"						Define a orientação do texto.
	
	- tipo="Numerico|Decimal|Caracter|Data|CPF|CNPJ" 	Numerico: Campo que aceita apenas caracteres numéricos.
														Decimal: Campo que aceita valores decimais. Não aceita o atributo Mascara.
														Caracter: Campo que aceita apenas caracteres, não aceitando números.
														Data: Campo tipo Data. Não aceita o atributo Mascara.
														CPF: Campo do tipo CPF. Não aceita o atributo Mascara.
														CNPJ: Campo do tipo CNPJ. Não aceita o atributo Mascara.

	- negativo											Permite o usuário a digitar o Hífen (-). Usar apenas em campo Numerico|Decimal.

	- casasdecimais										Para campo Decimal. Define a quantidade de casas decimais.

	- validacao="Form|Campo"							Ativa a validação para campos: Data|CPF|CNPJ. 
														Form: A validação é realizada no submit do form.*
														Campo: A validação é realizada no momento que o campo perde o foco.
	
	- valormax=""										Para campo Numerico|Decimal, define o valor máximo do campo.
	
	- obrigatorio										Define se o campo é obrigatório.*
	- obrigatorio=""									Define se o campo é obrigatório. O valor atribuído será utilizado no lugar do nome
														do campo na mensagem padrão.*

	* (Necessário usar a método validaCampos da classe Validacoes).
:: Exemplos:
	- Campo numérico = <input type="text" tipo="numerico" value="" name="Campo">
	- Campo Data Obrigatório com validação no submit= <input type="text" tipo="data"  obrigatorio="Data" value="" name="Campo" validacao="form">
	- Campo CPF com Validacao no campo= <input type="text" tipo="cpf" name="Campo" value="" validacao="campo">
***************************************************************************************************************************/
Mascaras = {
	IsIE: navigator.appName.toLowerCase().indexOf('microsoft')!=-1,
	AZ: /[A-Z]/i,
	Acentos: /[À-ÿ]/i,
	Num: /[0-9]/,

	carregar: function(parte){
		var Tags = ['input','textarea'];
		if (typeof parte == "undefined") parte = document;
		for(var z=0;z<Tags.length;z++){
			Inputs=parte.getElementsByTagName(Tags[z]);
			for(var i=0;i<Inputs.length;i++)
				if(('button,image,hidden,submit,reset').indexOf(Inputs[i].type.toLowerCase())==-1)
			this.aplicar(Inputs[i]);
		}
	},

	aplicar: function(campo){
		var tipo = campo.getAttribute('tipo');
		if (!tipo || campo.type == "select-one") return;
		var orientacao = campo.getAttribute('orientacao');
		var mascara = campo.getAttribute('mascara');
		var validacao = campo.getAttribute('validacao');
		if (tipo.toLowerCase() == "decimal") {
			var orientacao = "esquerda";
			var casasdecimais = campo.getAttribute('casasdecimais');
			var tamanho = campo.getAttribute('maxLength');
			if (!tamanho || tamanho > 50)
				tamanho = 18;
			if (!casasdecimais)
				casasdecimais = 2;
			mascara = this.geraMascaraDecimal(tamanho, casasdecimais);
			campo.setAttribute("mascara", mascara);
			campo.setAttribute("tipo", "numerico");
			campo.setAttribute("orientacao", orientacao);
		}
		if (tipo.toLowerCase() == "medida") {
			var orientacao = "esquerda";
			var casasdecimais = campo.getAttribute('casasdecimais');
			var tamanho = campo.getAttribute('maxLength');
			if (!tamanho || tamanho > 50)
				tamanho = 18;
			if (!casasdecimais)
				casasdecimais = 3;
			mascara = this.geraMascaraMedida(tamanho-casasdecimais);
			campo.setAttribute("mascara", mascara);
			campo.setAttribute("tipo", "numerico");
			campo.setAttribute("orientacao", orientacao);
		}
		if (tipo.toLowerCase() == "data") {
			mascara = "##/##/####";
			campo.setAttribute("mascara", mascara);
			campo.setAttribute("tipo", "numerico");
			campo.setAttribute("orientacao", orientacao);
			if (validacao) {
				if (validacao.toLowerCase() == "campo") {
					if(this.IsIE)
						campo.onblur = function(e){ Mascaras.onblurData(e?e:event); };
					else
						campo.setAttribute("validacao", "form");
				}
				else
					campo.setAttribute("tipovalidacao", "data");
			}
		}
		if (tipo.toLowerCase() == "cpf") {
			mascara = "###.###.###-##";
			campo.setAttribute("mascara", mascara);
			campo.setAttribute("tipo", "numerico");
			campo.setAttribute("orientacao", orientacao);
			if (validacao) {
				if (validacao.toLowerCase() == "campo") {
					if(this.IsIE)
						campo.onblur = function(e){ Mascaras.onblurCPF(e?e:event); };	  
					else
						campo.setAttribute("validacao", "form");
				}
				else
					campo.setAttribute("tipovalidacao", "cpf");
			}
		}
		if (tipo.toLowerCase() == "cnpj") {
			mascara = "##.###.###/####-##";
			campo.setAttribute("mascara", mascara);
			campo.setAttribute("tipo", "numerico");
			campo.setAttribute("orientacao", orientacao);
			if (validacao) {
				if (validacao.toLowerCase() == "campo") {
					if(this.IsIE)
						campo.onblur = function(e){ Mascaras.onblurCNPJ(e?e:event); };	  
					else
						campo.setAttribute("validacao", "form");
				}
				else
					campo.setAttribute("tipovalidacao", "cnpj");
			}
		}
		if (orientacao && orientacao.toLowerCase() == "esquerda") campo.style.textAlign = "right";
		if (mascara) campo.setAttribute("maxLength", mascara.length);
		if (tipo){
			campo.onkeypress = function(e){ return Mascaras.onkeypress(e?e:event); };
			campo.onkeyup = function(e){ Mascaras.onkeyup(e?e:event, campo) };
		}
		campo.setAttribute("snegativo", ((campo.value).substr(0,1) == "-" ? "s" : "n"));
	},

	onblurData: function(e){
		var campo = this.IsIE ? event.srcElement : e.target;
		var valor = trim(campo.value);
		if (valor.length>0)
			Validacoes.validaData(campo)
	},

	onblurCPF: function(e){
		var campo = this.IsIE ? event.srcElement : e.target;
		var valor = trim(campo.value);
		if (valor.length>0)
			Validacoes.validaCPF(campo);
	},
	
	onblurCNPJ: function(e){
		var campo = this.IsIE ? event.srcElement : e.target;
		var valor = trim(campo.value);
		if (valor.length>0)
			Validacoes.validaCNPJ(campo);
	},
	
	onkeypress: function(e) {
		var KeyCode = this.IsIE ? event.keyCode : e.which;
		var campo =  this.IsIE ? event.srcElement : e.target;
		readonly = campo.getAttribute('readonly');
		if (readonly) return;
		var maxlength = campo.getAttribute('maxlength');
		var selecao = this.selecao(campo);
		if (campo.value.length == maxlength)
		{
			if (selecao.length > 0 && KeyCode != 0)
			{
				campo.value = "";
				if (tipo == "numerico" && Char.search(this.Num) == -1) return false;
				if (KeyCode != 32 && tipo == "caracter" && Char.search(this.AZ) == -1 && Char.search(this.Acentos) == -1) return false;
			}
			else
				return true;
		}
		if (selecao.length > 0 && KeyCode != 0)
		{
			campo.value = "";
			if (tipo == "numerico" && Char.search(this.Num) == -1) return false;
			if (KeyCode != 32 && tipo == "caracter" && Char.search(this.AZ) == -1 && Char.search(this.Acentos) == -1) return false;
		}
		if (KeyCode == 0) return true;
		var Char = String.fromCharCode(KeyCode);
		var valor = trim(campo.value);
		var mascara = campo.getAttribute('mascara');
		if (KeyCode != 8) {
			var tipo = campo.getAttribute('tipo').toLowerCase();
			var valorMax = Number(campo.getAttribute('valormax'));
			var negativo = campo.getAttributeNode('negativo');
			if(negativo && KeyCode == 45) {
				snegativo = campo.getAttribute('snegativo');
				snegativo = (snegativo == "s" ? "n" : "s");
				campo.setAttribute("snegativo", snegativo);
			}
			else {
				valor += Char
				if (tipo == "numerico" && Char.search(this.Num) == -1) return false;
				if (KeyCode != 32 && tipo == "caracter" && Char.search(this.AZ) == -1 && Char.search(this.Acentos) == -1) return false;
				if (valorMax && tipo == "numerico" && Number(valor)>valorMax)
				{
					campo.value = valorMax;
					return false;
				}
			}
		}
		if (mascara){
			this.aplicarMascara(campo, valor);
			return false;
		}
		return true;
	},

	onkeyup: function(e, campo){
		var KeyCode = this.IsIE ? event.keyCode : e.which;
		if (KeyCode != 9 && KeyCode != 16 && KeyCode != 109){
			var valor = trim(campo.value);
			if (KeyCode == 8 && !this.IsIE) valor = valor.substr(0,valor.length-1);
			this.aplicarMascara(campo, valor);
		}
	},

	aplicarMascara: function(campo, valor){
		var mascara = campo.getAttribute('mascara');
		if (!mascara) return;
		var negativo = campo.getAttributeNode('negativo');
		var snegativo = campo.getAttribute('snegativo');
		if (negativo && valor.substr(0,1) == "-")
			var valor = valor.substr(1,valor.length-1);
		var orientacao = campo.getAttribute('orientacao');
		var i = 0;
		for(i=0;i<mascara.length;i++){
			caracter = mascara.substr(i,1);
			if (caracter != "#") valor = valor.replace(caracter, "");
		}
		var retorno = "";
		if (orientacao != "esquerda"){
			var contador = 0;
			for(i=0;i<mascara.length;i++){
				caracter = mascara.substr(i,1);
				if (caracter == "#"){
					retorno += valor.substr(contador,1);
					contador++;
				}
				else
					retorno += caracter;
				if(contador >= valor.length) break;
			}
		}
		else{
			var contador = valor.length-1;
			for(i=mascara.length-1;i>=0;i--){
				if(contador < 0) break;
				var caracter = mascara.substr(i,1);
				if (caracter == "#"){
					retorno = valor.substr(contador,1) + retorno;
					contador--;
				}
				else
					retorno = caracter + retorno;
			}
		}
		if (negativo && snegativo == "s")
			retorno = "-" + retorno;
		campo.value = retorno;
	},

	geraMascaraDecimal: function(tam, decimais){
		var retorno = ""; var contador = 0; var i = 0;
		var decimais = parseInt(decimais);
		for (i=0;i<(tam-(decimais+1));i++){
			retorno = "#" + retorno;
			contador++;
			if (contador == 3){
				retorno = "." + retorno;
				contador=0;
			}
		}
		retorno = retorno + ",";
		for (i=0;i<decimais;i++) retorno += "#";
		if (retorno.indexOf(".") == 0)
		retorno = retorno.substring(1,retorno.length);
		return retorno;
	},

	geraMascaraMedida: function(tam){
		return Array(tam+1).join("#") + ",##";
	},
	
	selecao: function(campo){
		if (this.IsIE)
		{
			var valor = document.selection.createRange().text;
			document.selection.clear();
			return valor;
		}
		else
			return (campo.value).substr(campo.selectionStart, (campo.selectionEnd - campo.selectionStart));
	},

	formataValor: function (valor, decimais){
		var valor = valor.split('.');
		if (valor.length == 1) valor[1] = "";
		for(var i=valor[1].length;i<decimais;i++)
			valor[1] += "0";
		valor[1] = valor[1].substr(0,2);
		return (valor[0] + "." + valor[1]);
	}
};

/****************************************************************************************************************************
:: Classe: Validacoes
:: Descrição: Classe utilizada para as validações comuns.
:: Métodos:
	- validaData(Campo)			Utilizada para a validação de Datas.
	
	- validaCPF(Campo)			Utilizada para a validação de CPF.
	
	-validaCNPJ(Campo)			Utilizada para a validação de CNPJ.
	
	-validaCampos(Formulario)	Utilizada para a validação dos campos do formulário. Deve ser utilizada no onsubmit do formulário.
								O uso desse método é orbigatório para a utilização dos atributos Obrigatorio e Validacao="Form"
								da classe Mascaras.
								Ex: <form onsubmit="return Validacoes.validaCampos(this)">
***************************************************************************************************************************/
Validacoes = {

	validaData: function (campo){
		if(!Validacoes.verificaData(campo.value)) {
			alert("Data inválida");
			campo.focus();
			return false;
		}
		return true;
	},

	verificaData: function (valor){
		var data = valor.split("/");
		if (valor.length!=10)
			return(false);
		if ((data[2] < 1900) || (data[2] > 2079))
			return(false);
		if (data[0] > 31)
			return(false);
		if (data[1] > 12)
			return(false);
		if (data[0] == "31")
			if ((data[1] == "04") || (data[1] == "06") || (data[1] == "09") || (data[1] == "11"))
				return(false);
		if (data[1] == "02"){
			if (data[2]%4)
				if (data[0] > 29)
					return(false);
			else if (data[0] > 28)
				return(false);
		}
		return(true);
	},

	validaCPF: function (campo){
		var sCPF = trim(campo.value);
		if (sCPF.length != 0){
			sCPF = campo.value.replace(".","");
			sCPF = sCPF.replace(".","");
			sCPF = sCPF.replace("-","");

			if (!(Validacoes.verificaCPF(sCPF.substring(0,9),sCPF.substring(9,11)))) {
				alert("O CPF informado é inválido!");
				campo.focus();	
				return false;
			}
		}
		return true;
	},
	
	verificaCPF: function (Numero, Digito) { 
		var j = -1;
		var CPF = Numero;
		var peso1 = '100908070605040302';
		var peso2 = '111009080706050403';
		var soma1 = 0;
		var soma2 = 0;
		var digito1 = 0;
		var digito2 = 0;
		var CPFDigito = Numero+Digito
		if ((CPFDigito == '11111111111')||
			(CPFDigito == '22222222222')||
			(CPFDigito == '33333333333')||
			(CPFDigito == '44444444444')||
			(CPFDigito == '55555555555')||
			(CPFDigito == '66666666666')||
			(CPFDigito == '77777777777')||
			(CPFDigito == '88888888888')||
			(CPFDigito == '99999999999')||
			(CPFDigito == '00000000000'))
			return false;

		for (i = 1; i < 9 - Numero.length+1; i++) {
			CPF = eval("'" + 0 + CPF + "'");
		}
		    
		for (i = 1; i < CPF.length+1; i++) {
		    j = j + 2;
		    soma1 += CPF.substring(i, i-1) * peso1.substring(j-1, j+1);
		}
		soma1 %= 11;

		if (soma1  < 2)
		   digito1 = 0;
		else
		   digito1 = 11 - soma1;

		j = -1; 
		for (i = 1; i < CPF.length+1; i++) {
		    j = j + 2;
		    soma2 += CPF.substring(i, i-1) * peso2.substring(j-1, j+1);
		} 
		soma2 += digito1 * 2 
		soma2 %= 11;

		if (soma2  < 2)
		   digito2 = 0;
		else
		   digito2 = 11 - soma2;

		if (eval("'" + digito1 + digito2 + "'") != Digito)
		    return false;
		else
		    return true;
	},
	
	validaCNPJ: function (campo){
		valor = trim(campo.value);
		if (valor != "") {
			var bValido = Validacoes.verificaCNPJ(valor);
			if (bValido == false){
				alert("O CNPJ informado é inválido!");
				campo.focus();
				return false;
			}
		}
		return true;
	},
	
	verificaCNPJ: function (valor) {
		var strCNPJ = valor.replace(".","");
		strCNPJ = strCNPJ.replace("/","");
		strCNPJ = strCNPJ.replace("-","");
	    if (trim(strCNPJ) == "") return false;
		var strDV = strCNPJ.substr(12, 2);
		var intSoma;
		var intDigito = 0;
		var strControle = "";
		var strMultiplicador = "543298765432";
	    strCNPJ = strCNPJ.substr(0, 12);
	    for(var j = 1; j <= 2; j++) { 
			intSoma = 0; 
			for(var i = 0; i <= 11; i++) { 
			   intSoma += (parseInt(strCNPJ.substr(i, 1), 10) * parseInt(strMultiplicador.substr(i, 1), 10))
			} 
			if(j == 2){intSoma += (2 * intDigito)} 
				intDigito = (intSoma * 10) % 11; 
			if(intDigito == 10){intDigito = 0} 
				strControle += intDigito.toString(); 
			strMultiplicador = "654329876543"; 
	    } 
	    return(strControle == strDV); 	
	},
	
	validaCampos: function (pform) {
		for (i=0; i < pform.elements.length; i++) {
			var campo = pform.elements[i];
			var obrigatorio = campo.getAttributeNode('obrigatorio');
			var obrigatorioDesc = campo.getAttribute('obrigatorio');
			if((campo.type == "text") || (campo.type == "textarea") || (campo.type == "password")){
				var tipoValidacao = campo.getAttribute('tipovalidacao');
				var validacao = campo.getAttribute('validacao');
				var valor = trim(campo.value);
				if(validacao && (validacao.toLowerCase() == "form")){
					if (valor.length>0)
					{
						switch(tipoValidacao.toLowerCase()){
							case "data":
								if(!Validacoes.validaData(campo))
									return false;
								break;
							case "cpf":
								if(!Validacoes.validaCPF(campo))
									return false;
								break;
							case "cnpj":
								if(!Validacoes.validaCNPJ(campo))
									return false;
								break;
						}
					}
				}
				if((obrigatorio) && (valor.length == 0) ) {
					if(!obrigatorioDesc) obrigatorioDesc = campo.name;
					alert("O campo: " + obrigatorioDesc + ", é de preenchimento obrigatório.");
					campo.focus();
					return false;
				}
			}
			if((campo.type == "select") || (campo.type == "select-one")){
				if((obrigatorio) && (campo.value == "NULL") ) {
					if(!obrigatorioDesc) obrigatorioDesc = campo.name;
					alert("O campo: " + obrigatorioDesc + ", é de preenchimento obrigatório.");
					campo.focus();
					return false;
				}
			}
		}
		return true;
	}
	
}

/****************************************************************************************************************************
:: Assinatura: trim(string);
:: Descrição: Remove os espaços em branco antes e após a string enviada.
:: Ex: 
	var texto = "  Teste  ";
	var textoTrim = trim(texto);
:: Resultado textoTrim = "Teste";
****************************************************************************************************************************/

function trim(value) {
	var temp = value;
	var obj = /^(\s*)([\W\w]*)(\b\s*$)/;
	if (obj.test(temp))
		temp = temp.replace(obj, '$2'); 
	var obj = / +/g;
	temp = temp.replace(obj, " ");
	if (temp == " ")
		temp = "";
   return temp;
}


