$(document).ready(function(){

	$( '*.obrigatorio' ).each(
		function()
		{
			if( $(this).val() != "" )
			{
				$(this).focus().blur();
			}
		}
	);

});

/**
 * Script de validação para o framework
 *
 * @example - Validacao.checar(this); Validacao.checar(this, 'validarCep');
 * @version - 1.0.5
 *
 * 1.0.5 - Bug fix : Ao chamar o método chamar o testarValidacao em conjunto com
 * o método enviar quando ocorria um erro de validação a fila era mantida e era
 * executa o restante dela depois que o ator preenchia o campo incialmente com o
 * erro, isso gerava uma validação desnecessária, resolvido resetando atributos
 * proximo e funcao quando um erro de validação ocorre.
 *
 * 1.0.4 - Bug fix : Ao chamar o testarValidacao ele não testava quando o campo
 * não tinha dados. Em todo a validação tinha o return; sendo que quando se
 * trata de um each do jquery o cancelamento da execução funciona apenas quando
 * se chamada return false;
 *
 * 1.0.3 - Implementada fila para tratamento de validação.
 *
 * 1.0.2 - Reescrita a validação para suporte ao IE e otimizações para loops.
 *
 * 1.0.1 - Foi feita a documentação da validação.
 *
 * 1.0.0 - Versão inicial
 */
var Validacao = {

	/**
	 * Contém um array com os campos de serão validados em fila.
	 */
	proximo : undefined,
	/**
	 * Função que será chamada logo em seguinda após execução do script.
	 */
	funcao : false
	/**
	 * Efetua a validação de um campo específico.
	 *
	 * @param object
	 *            obj - O objeto que será validado.
	 * @param string
	 *            tipoValidacao - Determina o tipo da validação que será
	 *            utilizada.
	 */
	,
	checar : function(obj, tipoValidacao) {

		obj = Validacao.setJquery(obj);

		if (tipoValidacao == undefined) {

			if (obj.val() == "") {

				Validacao.criarHint(obj, "FAIL",
						"O campo não pode estar vazio.");

			} else {

				Validacao.criarHint(obj, "OK");

			}
			Validacao.proximaValidacao();
			return false;

		}

		if (obj.val() != "") {

			switch (tipoValidacao) {

				case "validarCepPreencher" :

					tipoValidacao = "validarCep";
					Dne.selecionaCep(obj.val());

				default :
					valor = obj.val();

					break;

			}
			$.post(URL_ROOT + 'validacao/efetuarValidacao/', {
				type : tipoValidacao.split("validar")[1].toLowerCase(),
				value : encodeURIComponent(valor)
			}, function(response) {
				objJSON = eval('(' + response + ')');
				Validacao.criarHint(obj, objJSON.tipoMensagem,
						objJSON.mixedMensagem);
				Validacao.proximaValidacao();

			});

		} else {

			if(!obj.hasClass('obrigatorio')){

				Validacao.removerHint(obj);

			}else{

				Validacao.criarHint(obj, "FAIL", "O campo não pode estar vazio.");

			}
			if (Validacao.funcao) {

				Validacao.funcao();
				Validacao.funcao = undefined;

			}

		}

	}

	/**
	 * Verifica se existe uma próxima validação na fila, caso exista chama, caso
	 * contrário finaliza e chama a função de término da fila caso exista
	 * também.
	 */
	,
	proximaValidacao : function() {

		if (Validacao.proximo != undefined) {

			if (Validacao.proximo.length > 0) {

				$(Validacao.proximo.shift()).focus().blur();

			} else {

				Validacao.proximo = undefined;
				if (Validacao.funcao !== false) {

					try{

						Validacao.funcao();

					}catch(e){}

				}
				Validacao.funcao = false;

			}

		}

	}

	/**
	 * Pega o obj específico e transforma num objeto jquery.
	 *
	 * @param object
	 *            obj - Objeto que será setado no jquery.
	 */
	,
	setJquery : function(obj) {

		return $("#" + obj.id);

	}

	/**
	 * Verifica se o dado é obrigatório, caso esteja ok, pega e dá o submit
	 * automático.
	 *
	 * @param array
	 *            arrIgnorar - Matriz de dados que serão verificados para poder
	 *            ser efetuado o submit.
	 */
	,
	enviar : function(arrCampos, idForm, inverterSelecao) {

		inverterSelecao = inverterSelecao || false;
		idForm = idForm || 'form';
		validarGeral = Validacao.verificarObrigatorio(arrCampos,
				inverterSelecao);

		if (validarGeral !== true) {

			Validacao.funcao = false;
			Validacao.proximo = undefined;
			alert(validarGeral);

		} else {

			$(idForm).submit();

		}

	}

	/**
	 * Cria o hint do aviso de erro utilizando o brTip ( plugin do jquery para
	 * criação de tips ).
	 *
	 * @param object
	 *            obj - Objeto que será usado para criar o hint ( sempre vai ser
	 *            uma imagem ).
	 * @param string
	 *            retorno - O retorno do JSON ( vindo do object Mensagem do
	 *            server ) determinando se teve ou não sucesso na validação.
	 * @param string
	 *            mensagem - A mensagem de retorno, caso esteja vazia, não cria
	 *            o hint da imagem.
	 */
	,
	criarHint : function(obj, retorno, mensagem) {

		mensagem = mensagem || "";

		$('.errada-hint').hide();
		$("#validacao-" + obj.attr("id")).remove();

		if (retorno == "FAIL") {

			strImagem = "Errada";

		} else {

			strImagem = "Correta";

		}

		img = $("#validacao" + strImagem).clone();
		img.attr("rel", mensagem);

		if (obj.attr("tagName").toUpperCase() != "SELECT") {

			img.css("padding-top", "3");

		}

		if (mensagem != "") {

			img.brTip(strImagem.toLowerCase());

		}

		obj.removeClass("correta").removeClass("errada")
				.removeClass("obrigatorio").addClass(strImagem.toLowerCase());
		img.attr("id", "validacao-" + obj.attr("id")).insertAfter(obj).css(
				"display", "");

	}

	/**
	 * Remove todos os hints.
	 *
	 * @param object
	 *            obj - O objeto que será passado para remover os hints
	 *            vínculados a ele.
	 */
	,
	removerHint : function(obj) {

		obj = obj || alert("Programador passe um objeto por parâmetro!!!");
		$("#validacao-" + obj.attr("id")).remove();
		return obj.removeClass("correta").removeClass("errada");

	}

	/**
	 * Testa a validação de determinados campos ou de todos os campos
	 * obrigatórios.
	 *
	 * @param array
	 *            arrVerificar - Matriz que passa quais campos serão
	 *            verificados.
	 * @param function
	 *            fn - Função que será chamada logo depois da validação.
	 */
	,
	testarValidacao : function(arrVerificar, fn) {

		arrVerificar = arrVerificar || '*.obrigatorio, *.errada';
		fn = fn || false;


		if (typeof(arrVerificar) == "object") {

			for (i in arrVerificar) {

				arrVerificar[i] = "#" + arrVerificar[i];

			}

		}

		var ids = new Array();
		$(arrVerificar.toString()).each(function(i) {

			ids[i] = "#" + this.id;

		})

		if (!ids.length) {

			if (fn) {

				fn();

			}

		} else {

			Validacao.funcao = fn;
			Validacao.proximo = ids;
			$(Validacao.proximo.shift()).focus().blur();

		}

	}

	/**
	 * Reseta a validação para um determinado tipo de campo ou - caso o
	 * inverterSelecao esteja false - para os campos que não forem ele.
	 *
	 * @param array
	 *            arrCampos - Matriz com os campos que serão passados.
	 * @param boolean
	 *            inverterSelecao - Lógico que quando setado 'TRUE' reseta a
	 *            validação dos campos que estiverem em arrIgnorar caso
	 *            contrário faz o inverso.
	 */
	,
	resetarValidacao : function(arrCampos, inverterSelecao) {

		inverterSelecao = inverterSelecao || false;
		arrCampos = arrCampos || "";

		if (arrCampos != "") {

			if (inverterSelecao) {

				for (i in arrCampos) {

					arrCampos[i] = "#" + arrCampos[i];

				}

				$(arrCampos.toString()).each(function() {

					Validacao.removerHint($(this)).addClass("obrigatorio");

				})

			} else {

				$('*.obrigatorio, *.correta').each(function() {

					if (((arrCampos.toString().search($(this).attr("id")) == -1)
							? true
							: false)) {

						Validacao.removerHint($(this)).addClass("obrigatorio");

					}

				})

			}

		} else {

			$('*.obrigatorio, *.correta').each(function() {

				Validacao.removerHint($(this)).addClass("obrigatorio");

			})

		}

		Validacao.testarValidacao(arrCampos);

	}

	/**
	 * Remove a validação definitivamente dos campos passados.
	 *
	 * @param array
	 *            arrCampos - Matriz que determina os campos que a validação
	 *            será removida.
	 */
	,
	removerValidacao : function(arrCampos) {

		arrCampos = arrCampos
				|| alert("Programador é necessário passar os campos onde a formatação será removida!");

		for (i in arrCampos) {

			Validacao.removerHint($("#" + arrCampos[i]))
					.removeClass("obrigatorio").removeAttr("onblur");

		}

	}

	/**
	 * Verifica um determinado número de campos que estão como obrigatórios ou
	 * todos os obrigatórios.
	 *
	 * @param array
	 *            arrIgnorar - Matriz com os campos que serão verificados.
	 * @param boolean
	 *            inverterSelecao - Lógico que verifica os campos passados no
	 *            arrIgnorar como obrigatórios se 'TRUE', caso contrário faz o
	 *            inverso.
	 */
	,
	verificarObrigatorio : function(arrCampos, inverterSelecao) {

		inverterSelecao = inverterSelecao || false;
		arrCampos = arrCampos || "";
		validarGeral = true;

		if (arrCampos != "") {

			if (inverterSelecao) {

				for (i in arrCampos) {

					arrCampos[i] = "#" + arrCampos[i] + ".obrigatorio, #"
							+ arrCampos[i] + ".errada";

				}

				$(arrCampos.toString()).each(function() {

					if ($(this).hasClass("errada")) {

						validarGeral = "Atenção existem campos com erros de preenchimento.";
						return false;

					}

					validarGeral = "Atenção existem campos não preenchidos.";
					return false;

				})

			} else {

				$('*.obrigatorio, *.errada').each(function() {

					if (((arrCampos.toString().search($(this).attr("id")) == -1)
							? true
							: false)) {

						if ($(this).hasClass("errada")) {

							validarGeral = "Atenção existem campos com erros de preenchimento.";
							return false;

						}

						validarGeral = "Atenção existem campos não preenchidos.";
						return false;

					}

				})

			}

			return validarGeral;

		} else {

			$('*.obrigatorio, *.errada').each(function() {

				if ($(this).hasClass("errada")) {

					validarGeral = "Atenção existem campos com erros de preenchimento.";
					return false;

				}

				validarGeral = "Atenção existem campos não preenchidos.";
				return false;

			})

			return validarGeral;

		}

	}

}