/**
 * Pacote geral de validadores. Todos os grupos de validação devem 
 * estar dentro deste pacote.
 * 
 * @author Artur Alves
 * @since 25/08/2008
 * 
 * Para Usar:
 * 
  
var valido = NET.validador.validar();
if(!valido) return false;
 
 */

NET.validador = {
	
	classesValidadoras: {
		campo_obrigatorio: ".v_obrigatorio",
		
		campo_letras: ".v_letras",
		campo_alfanumerico: ".v_alfanumerico",
		campo_numerico: ".v_numerico",
		campo_positivo: ".v_positivo",

		campo_data: ".v_data",
		campo_cpf_cnpj:".v_cpf_cnpj",
		campo_cep:".v_cep"
	},
	
	textosClasses: {
		campo_obrigatorio: "Campos obrigatório",
		
		campo_letras: "Deve conter apenas letras",
		campo_alfanumerico: "Deve conter apenas letras e números",
		campo_numerico: "Deve conter apenas números",
		campo_positivo: "Deve conter apenas números positivos",

		campo_data: "Deve conter uma data válida no formato dd/mm/aaaa",
		campo_cpf_cnpj:"Deve conter um documento válido, CPF ou CNPJ",
		campo_cep:"Devem conter um CEP válido"
	},
	
	classesTratamento: {
		campo_invalido: "v_campo_invalido"
	},
	
	_pegaValor: function(campo){
		var valor = false;
		if(campo.is(":checkbox") || campo.is(":radio")) {
			valor = campo.is(":checked");
		} else {
			valor = campo.val();
		}
		
		return valor;
	},
	
	metodosValidadores: {
		campo_obrigatorio: function(valor){
			return !!valor;
		},
		
		campo_letras: function(valor){
			var regex = /^[a-zA-Z\sáàâãÁÀÂÃéèêÉÈÊíìîÍÌÎóòôõÓÒÔÕúùûÚÙÛçÇñÑ]*$/;
			return regex.test(valor) || valor == "";
		},
		
		campo_alfanumerico:  function(valor){
			var regex = /^[a-zA-Z0-9\sáàâãÁÀÂÃéèêÉÈÊíìîÍÌÎóòôõÓÒÔÕúùûÚÙÛçÇñÑ]*$/;
			return regex.test(valor) || valor == "";
		},
		
		campo_numerico:  function(valor){
			var regex = /^\d*$/;
			return regex.test(valor) || valor == "";
		},

		campo_positivo:  function(valor){
			var regex = /^\d*$/;
			if (regex.test(valor)) {
				var saida = eval(valor) >= 0;
			}
			return saida || valor == "";
		},

		campo_data: function(valor){
			//regex = /^(\d{1,2})[\s\.\/-](\d{1,2})[\s\.\/-](\d{4})$/;
			var regex = /^(([0-2]?\d{1})|([3][0,1]{1}))\/[0,1]?\d{1}\/(([1]{1}[9]{1}[9]{1}\d{1})|([2-9]{1}\d{3}))$/;
			
			if (!regex.test(valor)) return (valor == "");
			
			var valido = false;
			var data = valor.split("/");
			
			var dia = parseInt(data[0], 10);
			var mes = parseInt(data[1], 10);
			var ano = parseInt(data[2], 10);
			
			if (mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8 || mes == 10 || mes == 12) {
				valido = (dia >= 1 && dia <= 31);
				
			} else if (mes == 4 || mes == 6 || mes == 9 || mes == 11) {
				valido = (dia >= 1 && dia <= 30);
				
			} else if (mes == 2) {
				// algoritimo ano bissexto
				if ( ((ano % 400 == 0) || (ano % 4 == 0)) && (ano % 100 != 0) ) {
					// ano bissexto, fevereiro 29 dias
					valido = (dia >= 1 && dia <= 29);
					
				} else {
					// ano não-bissexto, 28 dias
					valido = (dia >= 1 && dia <= 28);
				}
			}
			
			// verificar se é um dia válido 31/12/2049
			return valido || valor == "";
		},
		
		campo_cpf_cnpj:  function(valor){
			//regex = /((^\d{2}.\d{3}.\d{3}\/\d{4}-\d{2}$)|(^\d{14}$))|((^\d{3}.\d{3}.\d{3}-\d{2}$)|(^\d{11}$))/;
			
			if(!valor) return true;
			
/*			if(regex.test(valor)) {
				valor = valor.replace(/[^0-9]/g, "");
			} else {
				return false;
			}
*/
			valor = valor.replace(/[^0-9]/g, "");
			
			var validaCPF = function(cpf){
				if(cpf.length != 11) return false;

				cpf = cpf.split("");
				cpf.unshift(NaN);
				
				var primeiraSoma = 10*cpf[1]+9*cpf[2]+8*cpf[3]+7*cpf[4]+6*cpf[5]+5*cpf[6]+4*cpf[7]+3*cpf[8]+2*cpf[9];
				var primeiroDigitoVerificador = (primeiraSoma % 11) < 2 ? 0 : 11 - (primeiraSoma % 11);
				
				var segundaSoma = 11*cpf[1]+10*cpf[2]+9*cpf[3]+8*cpf[4]+7*cpf[5]+6*cpf[6]+5*cpf[7]+4*cpf[8]+3*cpf[9]+2*primeiroDigitoVerificador;
				var segundoDigitoVerificador = (segundaSoma % 11) < 2 ? 0 : 11 - (segundaSoma % 11);
				
				return (cpf[10] == primeiroDigitoVerificador) && (cpf[11] == segundoDigitoVerificador);
			};

			var validaCNPJ = function(cnpj){
				if(cnpj.length != 14) return false;

				cnpj = cnpj.split("");
				cnpj.unshift(NaN);
				
				var primeiraSoma = 5*cnpj[1]+4*cnpj[2]+3*cnpj[3]+2*cnpj[4]+9*cnpj[5]+8*cnpj[6]+7*cnpj[7]+6*cnpj[8]+5*cnpj[9]+4*cnpj[10]+3*cnpj[11]+2*cnpj[12];
				var primeiroDigitoVerificador = (primeiraSoma % 11) < 2 ? 0 : 11 - (primeiraSoma % 11);
				
				var segundaSoma = 6*cnpj[1]+5*cnpj[2]+4*cnpj[3]+3*cnpj[4]+2*cnpj[5]+9*cnpj[6]+8*cnpj[7]+7*cnpj[8]+6*cnpj[9]+5*cnpj[10]+4*cnpj[11]+3*cnpj[12]+2*primeiroDigitoVerificador;
				var segundoDigitoVerificador = (segundaSoma % 11) < 2 ? 0 : 11 - (segundaSoma % 11);
				
				return (cnpj[13] == primeiroDigitoVerificador) && (cnpj[14] == segundoDigitoVerificador);
			};
			
			return validaCPF(valor) || validaCNPJ(valor) || valor == "";
		},
		
		campo_cep:  function(valor){
			var regex = /(^\d{5}-\d{3}|^\d{2}.\d{3}-\d{3}|\d{8})/;
			return regex.test(valor) || valor == "";
		},
		
		campo_email:  function(valor){
			var regex = /^\w+[\w-\.]*\@\w+((-\w+)|(\w*))\.[a-z]{2,3}$/;
			return regex.test(valor) || valor == "";
		}
	},
	
	avisaUsuario: function(camposInvalidos){
		saida = "Os seguintes campos devem ser preenchidos corretamente:";
		alert(saida + camposInvalidos);
	},

	_focarCampo: "",
	_camposInvalidos: "",
	_formatarCampos: true,
	_mostraMsgPadrao: true,
	
	_trataCampos: function(campo, classe){
		var v = NET.validador;
		var classeCampoInvalido = v.classesTratamento.campo_invalido;

		var valido = false
		
		if (campo.is(":visible")) {
			valido = v.metodosValidadores[classe](v._pegaValor(campo));
		} else {
			valido = true;
		}

		if (!valido) {
			if (!v._focarCampo) {
				v._focarCampo = campo;
			}

			if (v._formatarCampos) {
				campo.addClass(classeCampoInvalido);
			}

			var campoLabel = $("label[for="+campo.attr("id")+"]").text() || campo.attr("id");
			v._camposInvalidos += "\n - " + campoLabel + " (" + v.textosClasses[classe] + ")";
		}
	},
	
	_iteraSobreValidacoes: function(campos){
		var v = NET.validador;
		var listaCampos = ""
		for(var classe in v.classesValidadoras) {
			listaCampos = campos ? campos : $(v.classesValidadoras[classe]);
			$.each(listaCampos, function(){
				var campoAtual = $(this);
				
				if (campoAtual.is(v.classesValidadoras[classe])) {
					v._trataCampos(campoAtual, classe);
				}
			});
		}
		
		camposInvalidos = v._camposInvalidos;
		v._camposInvalidos = "";
		
		return camposInvalidos;
	},
	
	_retornoValidacao: function(camposInvalidos){
		var v = NET.validador;
		if(camposInvalidos.length != "") {
			
			if (v._mostraMsgPadrao) {
				v.avisaUsuario(camposInvalidos);
			}
			
			v._focarCampo.focus();
			return false;
		} else {
			return true;
		}
	},
	
 	validar: function() {
		var v = NET.validador;
		var campos = ""; 
		v._camposInvalidos = "";
		var classeCampoInvalido = v.classesTratamento.campo_invalido;
		
		// limpa a formatação dos campos invalidos para a nova validação
		$("."+classeCampoInvalido).each(function(){
			$(this).removeClass(classeCampoInvalido);
		});
		
		var listaCampos = arguments[0];
		
 		// formatar campos invalidos?
 		if (listaCampos == false) {
 			v._formatarCampos = false;
 			listaCampos = arguments[1];
	 		
	 		// mostra mensagem padrão?
	 		if (listaCampos == false) {
	 			v._mostraMsgPadrao = false;
	 			listaCampos = arguments[2];
	 		}
 		}
 				
 		
 		// recebe uma array, para validar campos especificos
 		if(listaCampos) {
 			if(listaCampos.constructor.toString().indexOf("Array") != -1) {
 				campos = listaCampos; 
 			
 			} else {
 				throw("É necessário que os campos a serem validados sejam passados como Array");
 				return false;
 			}
 		}
		
		var camposInvalidos = v._iteraSobreValidacoes(campos);
		
		return v._retornoValidacao(camposInvalidos);
	}
};