/***
*	:: Validação Genérica ::
*
*	Validação genérica para formulários. Para adicionar uma validação em um campo, atribuir a classe
*	"validar" e no atributo "title", acrescentar as regras.
*
*	Regras:
*	-------
*		min:<inteiro>
*			Quantidade mínima de caracteres.
*			{min:1}
*
*		max:<inteiro>
*			Quantidade máxima de caracteres
*			{max:5}
*
*		igualA:<string>
*			Igual a valor de um outro campo ou a string
*			{igualA:'teste'} ou {igualA:'#texte'}
*		
*		diferenteDe:<string>
*			Diferente do valor de um outro campo ou a string
*			{diferenteDe:'teste'} ou {diferenteDe:'#texte'}
*		
*		tipo:<string>
*			Define o tipo obrigatório
*			"inteiro" / "int": Numérico inteiro
*			"email" / "e-mail": E-mail
*			"data": Data tipo dd/mm/aaaa
*			"obrigatório": Preenchimento obrigatório
*	
*	Ex.:
*	----
*		<input id="teste" name="teste" type="text" class="validar" title="Teste{min:5,tipo:'email',max:50,diferenteDe:'exemplo@dominio.com.br'}" />
*	
*	Métodos:
*	--------
*		validar.init()
*			Inicializa a validação aplicando os eventos.
*		validar.form(<string opcional>)
*			Executa a validação em um determinado formulário.
*		validar.verificaCampos(<objetos>)
*			Executa a validação em um conjunto de objetos específicos.
***/
validar = {
	versao: "2.15.8.2008",
	
	// Variáveis
	obj: null,
	nome: null,
	valor: null,
	valido: true,
	msg: null,
	campos: new Object(),
	timeout: null,
	
	// Inicialização
	init: function(){
		$(".validar").each(function(){
			
			var regras = $(this).attr("title");
			var obj = $(this);
			
			if(typeof(regras) != "undefined"){
				if(regras.indexOf("{") > 0){

					// Gera as regras
					var opcoes = new Object();
					regras = regras.substring(regras.indexOf("{"),regras.length).replace("{","").replace("}","").split(",");
					
					$.each(regras,function(i,val){
						var nome = val.split(":")[0];
						var valor = eval(val.split(":")[1].replace(/\(doispontos\)/g,":"));
						opcoes[nome] = valor;
					});
					
					// Cria uma biblioteca com os campos e as regras
					validar.campos[$(this).attr("id")] = opcoes;

					// Eventos
					var validacaoBlur = function(){
						validar.obj = $(this);
						validar.valor = $(this).val();
						validar.valido = true;
						validar.verifica();
					}
					$(this).not(".calendario").unbind('blur',validacaoBlur).blur(validacaoBlur);
					
					// Máscaras
					if($(this).attr("title").indexOf("mascara") != -1){
						switch(opcoes.mascara){
							case "R$": $(this).maskMoney({symbol:"R$",decimal:",",thousands:"."}); break;
							case "peso": $(this).maskMoney({symbol:"",decimal:",",thousands:".",precision:3}); break;
							case "decimal": $(this).maskMoney({decimal:",",thousands:"",showSymbol:false}); break;
							default: $(this).mask(opcoes.mascara); break;
						}
					}
					
					if($(this).attr("title").indexOf("inteiro") != -1){
						
						$(this).keypress(function(e){
							
							if ($.browser.msie){
								var char = e.keyCode;
								if (char < 48 || char > 57 && char != 8 && char != 9) return false;
							}else{
								var char = e.which
								if (char && char != 8 && (char < 48 || char > 57)) { e.preventDefault(); }
							}
			
						})
		
					}		
				}
			}
			
			var titulo = $(this).attr("title");
			$(this).attr("title",titulo.split("{")[0]);

		});
		
		if($(".validar:enabled").length > 0){
			$("form").unbind('submit',validar.form).submit(validar.form);
		}
	},
	
	form: function(form){
		var valido = true;
		obj = typeof(form) == "string" ? $(form) : typeof(form) == "object" ? form : this;
		
		$("li:visible .validar:enabled",obj).each(function(){
			if(valido){
				validar.obj = $(this);
				validar.valor = $(this).val();
				validar.valido = true;
				validar.verifica();
				valido = validar.valido;
				if(!validar.valido) $(validar.obj).focus();
			}
		});
		
		return valido;
	},
	
	// Função que faz as verificações
	verifica: function(){
		if($(validar.obj).hasClass("validar") && $(validar.obj).is(':enabled')) {
			var id = $(validar.obj).attr("id");
			$.each(validar.campos[id],function(funcao,val){
				if(validar.valido && funcao != "mascara") validar[funcao](val);
			});
			if(!validar.valido){
				$(validar.obj).removeClass("form_ok").addClass("form_erro");
				validar.nome = $(validar.obj).attr("title");
				validar.exibeMsg();
			}else{
				$(validar.obj).removeClass("form_erro").addClass("form_ok");
				$(".boxMsg").remove();
			}
		}
	},
	
	// Exibir mensagem
	exibeMsg: function(){

		var msg = "O campo <strong>\""+validar.nome+"\"</strong> "+validar.msg // Mensagem

		// Gera Box da mensagem
		var posicaoBox = function(){
			$(".boxMsg").css($(validar.obj).offset());
			$(".boxMsg").css({
				opacity: "0.9",
				top: parseInt($(".boxMsg").css("top")) + parseInt($(validar.obj).outerHeight()),
				left: parseInt($(".boxMsg").css("left")) //+ parseInt($(validar.obj).width()) + 7
			});
			/*setTimeout(function(){
				if($(".boxMsg").is("div")) posicaoBox();
			},100);*/
		}
		$(".boxMsg").remove();
		$("body").prepend("<div class=\"boxMsg\" style=\"display:none;\">"+msg+"</div>");
		$(".boxMsg").css($(validar.obj).offset());
			$(".boxMsg")
				.stop()
				.css({
					opacity: "0.9",
					top: parseInt($(".boxMsg").css("top")) + parseInt($(validar.obj).outerHeight()),
				left: parseInt($(".boxMsg").css("left")) //+ parseInt($(validar.obj).width()) + 7
				})
				.fadeIn("fast", function(){
					clearTimeout(validar.timeout);
					validar.timeout = setTimeout(function(){ validar.escondeMsg(); },3500);
					posicaoBox();
				})
				.click(validar.escondeMsg);
	},
	
	escondeMsg: function(){
		clearTimeout(validar.timeout);
		if($(".boxMsg").length > 0) $(".boxMsg").fadeOut("fast",function(){ $(".boxMsg").remove(); });
	},
	
	verificaCampos: function(objs){
		validar.valido = true;
		$(objs).filter(".validar:enabled").each(function(){
			if(validar.valido){
				validar.obj = $(this);
				validar.valor = $(this).val();
				validar.valido = true;
				validar.verifica();
				if(!validar.valido) $(validar.obj).focus();
			}
		});
		return validar.valido;
	},
	
	// Quantidade mínima de caracteres
	min: function(regra){
		if(validar.valor.length < regra){
			validar.valido = false;
			validar.msg = "deve ser preenchido com no mínimo <strong>"+regra+"</strong> caracteres.";
		}
	},
	
	// Quantidade máxima de caracteres
	max: function(regra){
		if(validar.valor.length > regra){
			validar.valido = false;
			validar.msg = "deve ser preenchido com no máximo <strong>"+regra+"</strong> caracteres.";
		}
	},
	
	// Maior que inteiro ou data
	maiorQue: function(regra){
		if(validar.valor != ""){
			if(typeof(regra) == "number"){
				if(validar.valor < regra){
					validar.valido = false;
					validar.msg = "deve ser maior que <strong>"+regra+"</strong>.";
				}
			}else{
				if(regra == "hoje"){
					var hoje = new Date();
					hoje = hoje.getDate() + "/" + (hoje.getMonth() + 1) + "/" + hoje.getFullYear();
					if(dmDate.dateDiff(hoje,validar.valor) < 0){
						validar.valido = false;
						validar.msg = "deve ser maior que <strong>"+hoje+"</strong>.";
					}
				}
			}
		}
	},
	
	// Igual a campo ou string
	igualA: function(regra){
		var valor = regra.indexOf("#") == -1 ? regra : $(regra).val();
		if(validar.valor != valor){
			validar.valido = false;
			validar.msg = ' e <strong>"'+$(regra).attr('title')+'"</strong> não conferem.';
		}
	},
	
	// Diferente de campo ou string
	diferenteDe: function(regra){
		var valor = regra.indexOf("#") == -1 ? regra : $(regra).val();
		if(validar.valor == valor){
			validar.valido = false;
			validar.msg = "não foi preenchido corretamente.";
		}
	},
	
	// Definições de tipos
	tipo: function(regra){
		switch(regra){
			
			// Numérico inteiro
			case "inteiro": case "int":
				if(validar.valor != ""){
					var expressao = /^\d+$/;
					if(!expressao.test(validar.valor)){
						validar.valido = false;
						validar.msg = "deve ser preenchido com um <strong>número inteiro</strong>!";
					}
				}
			break;
			
			// E-mail
			case "email": case "e-mail":
				if(validar.valor != ""){
					var expressao = /^[a-zA-Z0-9]{1}([\._a-zA-Z0-9-]+)(\.[_a-zA-Z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+){1,3}$/;
					if(!expressao.test(validar.valor)){
						validar.valido = false;
						validar.msg = "não é um <strong>e-mail válido</strong>!";
					}
				}
			break;
			
			// Data tipo dd/mm/aaaa
			case "data":
				if(validar.valor != ""){
					var expressao = /^((0?[1-9]|[12]\d)\/(0?[1-9]|1[0-2])|30\/(0?[13-9]|1[0-2])|31\/(0?[13578]|1[02]))\/(19|20)\d{2}$/;
					if(!expressao.test(validar.valor)){
						validar.valido = false;
						validar.msg = "não é uma data válida, utilize o formato <strong>dd/mm/aaaa</strong>!";
					}
				}
			break;
			
			// Obrigatorio
			case "obrigatório": case "obrigatorio":
				if(validar.valor.replace(/[\s\.,()_-]/g,"").length == 0){
					validar.valido = false;
					validar.msg = "deve ser preenchido!";
				}
			break;
			
			// Select
			case "select":
				if( validar.valor == 0 || validar.valor == "" || validar.valor == null){
					validar.valido = false;
					validar.msg = "deve ser selecionado!";
				}
			break;
		}
	},
	
	// Validação de tipos
	validacao: function(regra){
		switch(regra){
			
			// CPF
			case "cpf": case "CPF":
				cpf = validar.valor.replace(/[^0-9]/g,"");
				erro = new String;
				if(cpf.length >= 11){
					if(cpf == "00000000000" || cpf == "11111111111" || cpf == "22222222222" || cpf == "33333333333" || cpf == "44444444444" || cpf == "55555555555" || cpf == "66666666666" || cpf == "77777777777" || cpf == "88888888888" || cpf == "99999999999"){
						erro += " é um número de CPF invalido!";
					}else{
						var a = [];
						var b = new Number;
						var c = 11;
						for(i=0; i<11; i++){
							a[i] = cpf.charAt(i);
							if(i < 9) b += (a[i] * --c);
						}
						if((x = b % 11) < 2){ a[9] = 0; }else{ a[9] = 11-x; }
						b = 0;
						c = 11;
						for(y=0; y<10; y++) b += (a[y] * c--);
						if((x = b % 11) < 2) { a[10] = 0; }else{ a[10] = 11-x; }
						if((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10])) erro += " é um número de CPF invalido!";
					}
					if (erro.length > 0){
						validar.msg = erro;
						validar.valido = false;
					}else{
						validar.valido = true;
					}
				}
			break;
			
			//CNPJ
			case "cnpj":
			
			cnpj = validar.valor.replace(/[^0-9]/g,"");
			erro = new String;
			
			function valida_cnpj(cnpj)
				{
				var numeros, digitos, soma, i, resultado, pos, tamanho, digitos_iguais;
				digitos_iguais = 1;
				if (cnpj.length < 14 && cnpj.length > 15)
					return false;
				for (i = 0; i < cnpj.length - 1; i++)
					if (cnpj.charAt(i) != cnpj.charAt(i + 1))
						  {
						  digitos_iguais = 0;
						  break;
						  }
				if (!digitos_iguais)
					{
					tamanho = cnpj.length - 2
					numeros = cnpj.substring(0,tamanho);
					digitos = cnpj.substring(tamanho);
					soma = 0;
					pos = tamanho - 7;
					for (i = tamanho; i >= 1; i--)
						  {
						  soma += numeros.charAt(tamanho - i) * pos--;
						  if (pos < 2)
								pos = 9;
						  }
					resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
					if (resultado != digitos.charAt(0))
						  return false;
					tamanho = tamanho + 1;
					numeros = cnpj.substring(0,tamanho);
					soma = 0;
					pos = tamanho - 7;
					for (i = tamanho; i >= 1; i--)
						  {
						  soma += numeros.charAt(tamanho - i) * pos--;
						  if (pos < 2)
								pos = 9;
						  }
					resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
					if (resultado != digitos.charAt(1))
						  return false;
					return true;
					}
				else
					return false;
				} 
				
				if(cnpj.length >= 14) validar.valido = valida_cnpj(cnpj)
				validar.msg = " é um número de CNPJ inválido!";
			break;
			
			//Hora
			case "hora":
				var hora = validar.valor.split(':')[0];
				var minuto = validar.valor.split(':')[1];
				
				if (hora > 23 || minuto > 59){
					validar.msg = " &eacute; um hor&aacute;rio inv&aacute;lido";
					validar.valido = false;
				}else{
					validar.valido = true;
				}
				
			break;
			
			//Data
			case "data":
				var bissexto = 0;
				var data = validar.valor;
				var tam = data.length;
				var dia = data.substr(0,2);
				var mes = data.substr(3,2);
				var ano = data.substr(6,4);
				
				validar.valido = false;
				validar.msg = " &eacute; uma data inv&aacute;lida";
				if ((ano > 1900)||(ano < 2100))
				{
						switch (mes) 
						{
								case '01': case '03': case '05': case '07': case '08': case '10': case '12':
									if  (dia <= 31) validar.valido = true;
								break;
								
								case '04': case '06': case '09': case '11':
									if  (dia <= 30) validar.valido = true;
								break;
								
								case '02':
									/* Validando ano Bissexto / fevereiro / dia */ 
									if ((ano % 4 == 0) || (ano % 100 == 0) || (ano % 400 == 0)) bissexto = 1; 
									if ((bissexto == 1) && (dia <= 29)) validar.valido = true;                             
									if ((bissexto != 1) && (dia <= 28)) validar.valido = true; 
								break;
						}
				}
				
			break;
			
			//verifica se já existe no banco
			case "naoRepete":
				var form = $(validar.obj).parents("form:eq(0)");
				var arquivo = $('input:hidden[name="pagina"]', form).val().split("_");
				arquivo.pop();
				
				function mensagem(texto){
					validar.msg = texto
					if(texto == '') 
						validar.valido = true
					else
						validar.valido = false
				}
				
				$.ajax({
					url:"biblioteca/ajax/" + arquivo + ".asp?acao=verifica",
					data:"campo=" + $(validar.obj).attr("name") + "&valor=" + validar.valor,
					type:'POST',
					async:false,
					success:function(r){
						
						if(r == "existe")
							mensagem(" j&aacute; está cadastrado. Digite um valor diferente.");
						else
							mensagem("");
						
					},
					error:function(){
						mensagem(" n&atilde;o p&ocirc;de ser verificado. Tente novamente.");
					}
				});
									
			break;
		}
	}
}
