jQuery.kv = {};
jQuery.fn.kv = {};

jQuery.fn.kvform = function(P){
	// parametros da função padrão
	P = jQuery.extend({
		erroClass: "form-erro",
		success: function(json){ P.form.trigger('success',[json]); },
		validation: function(json){ P.form.trigger('validation',[json]); },
		error: function(json){ P.form.trigger('error',[json]); },
		beforeSend: function(json){ P.form.trigger('beforeSend',[json]); }
	}, P);
	// guarda o id do form junto aos parametros
	P.form = jQuery(this);
	// aplica a função ao executar o submit
	P.form.submit(function(){
		// Fecha todos os modais existentes na tela
		if(jQuery.fechaModalTodos)
			jQuery.fechaModalTodos(true);
		// verifica a existencia de erros no formulario
		// essa primeira verificação feira pelo JS
		if(!jQuery.kv.valida(P).length){
			P.form.ajaxSubmit({
				dataType: 'json',
				beforeSend: function(){
					jQuery("div.aviso_carregando").remove();
					jQuery("<div/>").addClass('aviso_carregando').html('<b>Carregando..</b>').appendTo(P.form);
					P.beforeSend();
				},
				success: function(json){
					jQuery("div.aviso_carregando",P.form).remove();
					if(json.call=='success'){
						jQuery.modal(json.msg,json.type,{log:json.log,centerIn:P.form});
						P.success(json);
					}else if(json.call=='validation'){
						jQuery.kv.marca(P,json.fields);
						P.validation(json);
					}else if(json.call=='error'){
						jQuery.modal(json.msg,json.type,{log:json.log,centerIn:P.form});
						P.error(json);
					}else{
                                            P.success(json);
                                        }
				}
			});
		}
		return false;
	});
	return true;
};

jQuery.fn.kvclear = function(P){
	jQuery(".form-erro",this).removeClass("form-erro");
};

jQuery.kv.valida = function(P){
	var erro = [];
	// seleciona todos os campos que possuem parametros kv dentro do form
	jQuery("*[kv]:not(:hidden)",P.form).each(function(ci, cval){
		// remove todas as marcações de erro do formulario
		jQuery(P.form).kvclear(P.erroClass);
		
		var validacoes = jQuery(cval).attr("kv").split(" ");
		jQuery.each(validacoes, function(vi, vval){
			if(jQuery.isFunction(jQuery.kv.regras[vval])){
				var txtErro = jQuery.kv.regras[vval](jQuery(cval));
				if(txtErro){
					erro.push({'name':jQuery(cval).attr('name'),'erro':txtErro});
				}
			}
		});
	});
	jQuery.kv.marca(P, erro);
	return erro;
};

jQuery.kv.marca = function(P,erro){
	var form = this;
	var camposErro = [];
	jQuery.each(erro, function(i, val){
		jQuery("*[name='"+val.name+"']",P.form).parents(".form-campo:first").addClass(P.erroClass);
		camposErro.push((jQuery("*[name='"+val.name+"']",P.form).attr("campo")||val.name)+" = "+val.erro);
	});
	if( camposErro.length > 0 )
		jQuery.modal('Os campos abaixo apresentaram problemas:','erro',{unico:true,log:camposErro,centerIn:P.form});
};


// Regras de de validação
// Rotinas independetes
// O retorno da função deve ser false caso a regra não possua erros,
// e o codigo da mensagem de erro casso possua algum tipo de erro.
jQuery.kv.regras = {
	//informação obrigatória
	obrigatorio: function(campo){
		var msg = 'Campo obrigatório';
		if(jQuery(campo).attr("type") == 'checkbox'){
			if(jQuery(campo).attr("checked")){
				return false;
			}else{
				return msg;
			}
		}
		if(jQuery(":radio",campo).length > 0){
			return jQuery(":radio:checked",campo).length?false:msg;
		}
		if(jQuery(":selected",campo).length > 0){
			if(jQuery(campo).val() == -1 || jQuery(campo).val() == ""){
				return msg;
			}else{
				return false;
			}
		}
		if(campo.val() != ''){
			return false //codigo da msg
		}
		return msg;
	},
	//somente numeros
	numerico: function(campo){
		if (/^[0-9]*$/.test(jQuery(campo).val())){
			return false;
		}
		return 'Somente números'; //codigo da msg
	},
	//cpf valido - necessario carregar cpf-cnpj.js
	cpf: function(campo){
		if( jQuery(campo).val() == '' || isCpf(jQuery(campo).val())){
			return false;
		}
		return 'CPF inválido'; //codigo da msg
	},
	//cnpj valido - necessario carregar cpf-cnpj.js
	cnpj: function(campo){
		if( jQuery(campo).val() == '' || isCnpj(jQuery(campo).val())){
			return false;
		}
		return 'CNPJ inválido'; //codigo da msg
	},
	email: function(campo){
		if ( jQuery(campo).val() == '' || /^[a-zA-Z0-9]{1}([\._a-zA-Z0-9-]+)(\.[_a-zA-Z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+){1,3}$/.test(jQuery(campo).val())){
			return false;
		}
		return 'E-mail inválido';
	},
	//compara ois campos de senha necessita o atributo "compara" com o selector do campo a ser comparado ex: #senha
	comparaSenha: function(campo){
		var compara = jQuery(campo).attr('compara');
		if(jQuery(compara).val() == jQuery(campo).val()){
			return false;
		}
		return 'As senhas não conferem';
	},
	//compara ois campos de senha necessita o atributo "compara" com o selector do campo a ser comparado ex: #senha
	comparaEmail: function(campo){
		var compara = jQuery(campo).attr('compara');
		if(jQuery(compara).val() == jQuery(campo).val()){
			return false;
		}
		return 'Os e-mails não conferem';
	},
	// verifica se o campo esta preenchido com uma hora correta
	hora: function(campo){
		if ( jQuery(campo).val() == '' || /([01]?[0-9]|2[0-3]):[0-5]?[0-9]/.test(jQuery(campo).val())){
			return false;
		}
		return 'Hora inválida';
	},
	// verifica se o campo esta preenchido com uma hora correta
	data: function(campo){
		var sqlData = jQuery(campo).val().split('/').reverse().join('-');
		if (sqlData == '' || /^(((19|20)([13579][26]|[02468][048])-02-([0][1-9]|[12][0-9]))|((19|20)([02468][12356]|[013579][13579])-02-([0][1-9]|[1][0-9]|[2][0-8]))|(((19|20)[0-9][0-9])-((0[469]|11)-([0][1-9]|[12][0-9]|30)|(0[13578]|1[02])-([0][1-9]|[12][0-9]|3[01]))))$/.test(sqlData)){
			return false;
		}
		return 'Data inválida';
	},
	maxLen: function(campo){
		if ( jQuery(campo).val().length < jQuery(campo).attr('max') ){
			return false;
		}
		return 'Número máximo de caracteres: '+jQuery(campo).attr('max');
	},
	minLen: function(campo){
		if ( jQuery(campo).val().length > jQuery(campo).attr('min') ){
			return false;
		}
		return 'Número mínimo de caracteres: '+jQuery(campo).attr('min');
	}
};
