
var lBlnExecutouFoco = false;

function clsValidadorFormulario(pObjForm)
{
	var _Form = pObjForm; // Formulário, usado somente para submeter.
	var _arrFormItens = new Array(); // Array de itens de formulário
	
	/*
		Adiciona as classes de itens de formulário a um array local
	*/
/*	this.addItemForm = function (pNovoItemForm)
	{
		_arrFormItens.push(pNovoItemForm);
	}*/
	this.addItemForm = function (pNovoItemForm)
	{
		_arrFormItens.push(pNovoItemForm);
	}
	
	this.Validar = function ()
	{
		/*
		Arrays para armazenar todos os arrays retornados pelas validações dos campos. Os arrays possuem a seguinte estrutura:
		lArrErros[x].objeto -> Objeto (não somente nome) do formulário
		lArrErros[x].descricao -> Texto descrevendo o erro relacionado ao objeto
		*/
		var lArrErros = new Array();
		var lArrRetorno = new Array();
		
		for (var iFormItens = 0 ; iFormItens < _arrFormItens.length ; iFormItens++) // varre todos os itens de formulário
		{
			lArrRetorno = _arrFormItens[iFormItens].Validar();
			
			// Concatena todos os arrays de erros, vindo da validação dos itens de formulário
			if (lArrRetorno.length > 0)
				lArrErros = lArrErros.concat(lArrRetorno);
		}
		
		/*
		var lStrTmpErros = "";
		for (var ierr = 0 ; ierr < lArrErros.length ; ierr++)
			lStrTmpErros += "\n[" + (ierr+1) + "] objeto: " + lArrErros[ierr].objeto.name + ", erro " + lArrErros[ierr].descricao;
		alert("Foram retonadas " + lArrErros.length + " mensagens de erro\n\n" + lStrTmpErros);
		*/
		return lArrErros;
	}
}

function clsItemForm(pStrLabelItemForm)
{
	// Variáveis públicas
	
	// Variáveis locais
	var _ObjItemForm; // Objeto do formulário
//	var _TipoItemForm; // Tipo do objeto do formulário
	var _NomeExibicao = pStrLabelItemForm; // nome que deve ser exibido nas mensagens de erro
	var _arrClsValidacaoItem = new Array(); // Array de validações de itens de formulário


	/*
	Configura a instância da classe com o objeto do formulário
	*/
	this.setItemForm = function (pObjItemForm, pObjForm) // passar p/ o construtor
	{	
		var obj = RetornaObjeto(pObjItemForm, pObjForm);
		
//		if (pObjItemForm == "radOptRadio" || pObjItemForm == "chkOpcao")
//			alert(obj.length);
			
		//alert(obj);
		_ObjItemForm = obj; //pObjItemForm
		
		//alert(_ObjItemForm);
//		_TipoItemForm = typeof pObjItemForm; // Pegar todos os tipos de objetos do formulário
//		alert(pObjItemForm.type);
	}

	/*
	Adiciona as validações que um item de formulário deve possuir
	*/
	this.addClasseValidacao = function (pObjValida)
	{
		_arrClsValidacaoItem.push(pObjValida);
	}
	
	/*
		Executa a validação do item do formulário, fazendo um loop em todas as validações do formulário. Essas validações
	retornam um texto, caso o campo não passe na validação. Esse texto é adicionado a um Array de mensagens de erro.
	*/
	this.Validar = function ()
	{
		var lArrErros = new Array();
		var lRetorno;
		
		// Executa as validações que foram adicionadas a esse item de formulário
		for (var iValidacao = 0 ; iValidacao < _arrClsValidacaoItem.length ; iValidacao++)
		{
			lRetorno = _arrClsValidacaoItem[iValidacao](_ObjItemForm, _NomeExibicao);
			
			if (lRetorno != "") // Se a classe de validação retornar mensagem de erro
			{
				lArrErros.push({descricao:lRetorno,objeto:_ObjItemForm});
//				if (!lBlnExecutouFoco)
//					Foco();
			}
		}

		return lArrErros;
	}
	
	/*
	Coloca o foco no item de formulário. Deve ser usado somente para o primeiro item de formulário encontrado com erro de validação.
	*/
	this.Foco = function ()
	{
		_ObjItemForm.focus();
	}
}

/*
==============================================================================
					Validações pré-definidas
==============================================================================
*/

/*
function clsValida_text_Data(pObjItemForm)
{
}
*/

/*
Valida se somente foi digitado números
*/
function clsValida_text_SomenteNumeros(pObjItemForm, pStrNomeCampo)
{
	if (pObjItemForm.value == "") return ""; // só valida o campo se estiver preenchido

	var er = /\D+/;
	var lStrMsgRetorno = "";

	if (er.exec(pObjItemForm.value) != null)
		lStrMsgRetorno = "O campo \"" + pStrNomeCampo + "\" somente deve possuir números.";
		
	return lStrMsgRetorno;
}

/*
Valida se o campo é do tipo moéda
*/

function clsValida_text_Moeda(pObjItemForm, pStrNomeCampo)
{
	if (pObjItemForm.value == "") return ""; // só valida o campo se estiver preenchido

	//var er = /^\d{1,3}(\.\d{3})*\,\d{2}$/;
	var er = /\,\d{2}$/;
	var lStrMsgRetorno = "";
	
	if (er.exec(pObjItemForm.value) == null)
		lStrMsgRetorno = "O valor digitado no campo \"" + pStrNomeCampo + "\" não é válido.";
		
	return lStrMsgRetorno;
}


function clsValida_text_Email(pObjItemForm, pStrNomeCampo)
{
	if (pObjItemForm.value == "") return ""; // só valida o campo se estiver preenchido

	var er = /\w{1,}[@]\w{1,}([.](\w{1,})){1,2}$/;
	var lStrMsgRetorno = "";

	if (er.exec(pObjItemForm.value) == null)
		lStrMsgRetorno = "O e-mail digitado no campo \"" + pStrNomeCampo + "\" não é um e-mail válido.";
		
	return lStrMsgRetorno;
}

function clsValida_text_Data(pObjItemForm, pStrNomeCampo)
{
	if (pObjItemForm.value == "") return ""; // só valida o campo se estiver preenchido

	var er = /^((0[1-9]|[12]\d)\/(0[1-9]|1[0-2])|30\/(0[13-9]|1[0-2])|31\/(0[13578]|1[02]))\/\d{4}$/;
	var lStrMsgRetorno = "";

	if (er.exec(pObjItemForm.value) == null)
		lStrMsgRetorno = "A data digitada no campo \"" + pStrNomeCampo + "\" não é uma data válida.";
		
	return lStrMsgRetorno;
}

/*
Valida se o input foi preenchido ou selecionado

obs: Somente a validação para os tipos "checkbox" e "radio" suportam mais de um objeto no formulário com o mesmo nome
*/
function clsValida_Obrigatorio(pObjItemForm, pStrNomeCampo)
{
	var lStrTipoCampo = RetornaTipoInput(pObjItemForm);
	var lStrMsgRetorno = "";
	
	if (lStrTipoCampo == "text" || lStrTipoCampo == "password" || lStrTipoCampo == "hidden" /*|| lStrTipoCampo == "textarea"*/)
	{
		if (pObjItemForm.value.length == 0)
			lStrMsgRetorno = "O preenchimento do campo \""+ pStrNomeCampo + "\" é obrigatório."
	}
	else if (lStrTipoCampo == "select-one") // select (combo) de seleção simples
	{
		if (!pObjItemForm.selectedIndex || pObjItemForm.options[pObjItemForm.selectedIndex].value == "-1")
		//if (pObjItemForm.options[pObjItemForm.selectedIndex].value == "")
			lStrMsgRetorno = "O campo \""+ pStrNomeCampo + "\" é obrigatório, escolha uma opção."
	}
	else if (lStrTipoCampo == "select-multiple") // select (combo) de seleção múltipla
	{
		var iSel = 0;
		
		// Varre os options do select-multiple procurando algum selecionado, ao achar o loop para de executar
		// verifica: enquanto não chegou no final das opções && se o item esta selecionado && se o item selecionado tem a propriedade 'value' diferente de vazio
		for ( ; iSel < pObjItemForm.options.length && !pObjItemForm.options[iSel].selected && pObjItemForm.options[iSel].value != "-1" ; iSel++);
		
		if (iSel == pObjItemForm.options.length)
			lStrMsgRetorno = "O campo \""+ pStrNomeCampo + "\" é obrigatório, escolha uma ou mais opções."
	}
	else if (lStrTipoCampo == "checkbox" || lStrTipoCampo == "radio")
	{
		var lBlnAchouUm = false;
		
		//alert(lStrTipoCampo + ": " + pObjItemForm.length);
		
		if (pObjItemForm.length) // Possui mais de um checkbox
		{
			for (iChk = 0 ; iChk < pObjItemForm.length ; iChk++)
				if (pObjItemForm[iChk].checked)
				{
					lBlnAchouUm = true;
					break;
				}
		}
		else //Possui somente um checkbox
			if (pObjItemForm.checked)
				lBlnAchouUm = true;
		
		if (!lBlnAchouUm)
			lStrMsgRetorno = "O campo \""+ pStrNomeCampo + "\" é obrigatório, escolha uma opção."
			
	}
	else
		alert("Um campo do formulário não pode ser validado"); // rever essa msg p/ uma msg padrão.

	return lStrMsgRetorno;
}

/*
==============================================================================
					Funções auxiliares
==============================================================================
*/

function RetornaTipoInput(pObjInput) // pesquisar cross browser
{
	var lTipo = "";
//	var tmp_tamanho = pObjInput.length;
//	var lObjeto = (pObjInput.length)?pObjInput.item(0):pObjInput;
	
	
	

/*	if (pObjInput.length && !pObjInput.hasChildNodes //!pObjInput.options)
		pObjInput = pObjInput.item(0);*/
	if (pObjInput.options) // O SELECT nunca pode ser um array
		if (pObjInput.multiple)
			lTipo = "select-multiple";
		else
			lTipo = "select-one";
	else 
		if (pObjInput.length)
			lTipo = pObjInput[0].type;
		else
			lTipo = pObjInput.type;
	
//	alert(lTipo);
/*
	if (pObjInput.tagName == "INPUT")
		//lTipo = pObjInput.attributes.getNamedItem("type").nodeValue;
		lTipo = pObjInput.attributes.getNamedItem("type").nodeValue;
	else
		lTipo = pObjInput.tagName.toLowerCase();
	if (lTipo == "select")
		if (pObjInput.attributes.getNamedItem("multiple"))
			lTipo = "select-multiple";
		else 
			lTipo = "select-one";
*/

	return lTipo;
}

function RetornaObjeto(pStrNomeObjeto, pStrNomeForm)
{
	var objeto = null;
//	if (document.all)
	objeto = eval("document." + pStrNomeForm + "." + pStrNomeObjeto);
	//objeto = document.getElementById("//@id='" + pStrNomeObjeto + "'");
	
//	alert(objeto);
//	alert("document." + pStrNomeForm + "." + pStrNomeObjeto);
//	objeto = document.getElementById(pStrNomeObjeto);
//	var objeto = eval("document.form1." + pStrNomeObjeto);
//	if (objeto.item(0))
//		alert(objeto.item(0));
/*	if (!objeto)
	{
		alert("vai procurar pela tagname");
		var objeto = ProcuraObjetoByTagName(pStrNomeObjeto);
	}
	else alert("Não fez procura por tagname");
	*/
	return objeto;
}

/*
Retorna um array com os objetos do form. Teoricamente, por possuirem métodos em comum, 
*/
function ProcuraObjetoByTagName(pStrNomeObjeto)
{
	var lArrItemForm = new Array();


	// verifica se é um array de INPUT (text, password, checkbox, radio)
	var nodeList = document.getElementsByTagName("INPUT");
	var lObjItemForm = null;
	
	for (var iNode = 0 ; iNode < nodeList.length ; iNode++)
	{
		lObjItemForm = nodeList.item(iNode);

		if (!lObjItemForm.attributes.getNamedItem("id"))
			alert("Atenção: Existem elementos INPUT sem a tag ID");
			
		alert ("Comparando INPUT: " + lObjItemForm.attributes.getNamedItem("id").nodeValue + " com " + pStrNomeObjeto);
		
		if (lObjItemForm.attributes.getNamedItem("id").nodeValue == pStrNomeObjeto)
		{
			lArrItemForm.push(lObjItemForm);
			alert("adicionou um INPUT");
		}
	}
	
//	alert ("Total de INPUTs pesquisados
	
	if (!lArrItemForm.length)
	{
		// verifica se é um array de SELECT
		nodeList = document.getElementsByTagName("SELECT");
		lObjItemForm = null;
	
		for (var iNode = 0 ; iNode < nodeList.length ; iNode++)
		{
			lObjItemForm = nodeList.item(iNode);
	
			if (!lObjItemForm.attributes.getNamedItem("id"))
				alert("Atenção: Existem elementos SELECT sem a tag ID");
			
			alert ("Comparando SELECT: " + lObjItemForm.attributes.getNamedItem("id").nodeValue + " com " + pStrNomeObjeto);
			
			if (lObjItemForm.attributes.getNamedItem("id").nodeValue == pStrNomeObjeto)
				lArrItemForm.push(lObjItemForm);
				alert("adicionou um SELECT");
		}
	}

	alert("Tamanho do array de itens gerado: " + lArrItemForm.length);
	return lArrItemForm;
}

/*
- Testar função de Foco do item do formulário
- Vazer verificações p/ o textarea
*/