{

/** 
* Duas formas de chamar as rotinas AJAX:
*
*  #### FUNÇÃO: enviaElementos
*       Parâmetros:
*            documento -> deve ser sempre o documento ou objeto onde estão definidos os campos de formulário que serão validados
*            pagina -> nome da página que será chamada para fazer a validação dos campos
*            metodo -> TRUE para uma chamada SINCRONA (chama a página de validação, e não aguarda o retorno. Deixa o retorno para ser tratada pela função definda no parâmetro FUNCAO)
                       FALSE para uma chamada ASSINCRONA ( chama a página de validação, e espera o retorno). Devolvendo para a página CHAMADORA um array com os dados da página chamada.
*            funcao (opcional)-> nome da função que será chamada para tratar o retorno da página chamada
*                   Não é utilizada quando o parâmetro SINCRONO é igual a false
*  **** Envia todos os campos começados com "txt" (tem que ser minúsculo) 
*       para uma página, onde serão validados. Essa página devolverá os seguintes elementos XML:
*       erros -> haverá uma lista dos campos que possuem problemas
*       erroGlobal -> erros genéricos, onde é apresentado um alert com a mensagem de erro
*       Sucesso -> toda a validação ocorreu com sucesso 
*
*  ???? Pré-requisito: 
*       1. Deve existir pelo um campo dentro do formulário, começando com o prefixo "txt".
*       2. A página a ser chamada pelo AJAX, tem que devolver um dos elementos XML mencionados a cima. 
*
*  #### FUNÇÃO: conversaComAcao
*       Parâmetros:
*            documento -> deve ser sempre o documento ou objeto onde estão definidos os campos de formulário que serão utilizados pela ação
*            pagina -> nome da página que será chamada para fazer a execução da ação
*            metodo -> TRUE para uma chamada SINCRONA (chama a página de validação, e não aguarda o retorno. Deixa o retorno para ser tratada pela função definda no parâmetro FUNCAO)
                       FALSE para uma chamada ASSINCRONA ( chama a página de validação, e espera o retorno). Devolvendo para a página CHAMADORA um array com os dados da página chamada.
*            funcao (opcional)-> nome da função que será chamada para tratar o retorno da página chamada
*                   Não é utilizada quando o parâmetro SINCRONO é igual a false
*  **** Envia todos os campos começados com "txt" (tem que ser minúsculo) 
*       para uma página, que realizará alguma ação e devolverá um retorno. Essa página devolverá os seguintes elementos XML:
*       erros -> haverá uma lista dos campos que possuem problemas
*       erroGlobal -> erros genéricos, onde é apresentado um alert com a mensagem de erro
*       Sucesso -> toda a validação ocorreu com sucesso 
*
*/
	var divAjaxCarregando = null;
	var terminouAjax = false;
	var retornoDoAjax = null;
	var ajaxDebug = false;
	var disabledProcessando = true;


 	
    function xmlhttp() {

 			var A;

 			var msxmlhttp = new Array(
				'Msxml2.XMLHTTP.5.0',
				'Msxml2.XMLHTTP.4.0',
				'Msxml2.XMLHTTP.3.0',
				'Msxml2.XMLHTTP',
				'Microsoft.XMLHTTP');
			for (var i = 0; i < msxmlhttp.length; i++) {
				try {
					A = new ActiveXObject(msxmlhttp[i]);
				} catch (e) {
					A = null;
				}
			}

			if(!A && typeof XMLHttpRequest != "undefined")
				A = new XMLHttpRequest();

			return A;

    }

    function xmldoc(XML) {

		var xmlDoc2 = null;

		//code for Internet Explorer
		if (window.ActiveXObject)
		{
			//System.useCodepage = true;
			xmlDoc2 = new ActiveXObject("Microsoft.XMLDOM");
			xmlDoc2.async=false;
			xmlDoc2.loadXML(XML);
			
		}
		// code for Mozilla, Firefox, etc.
		else if (document.implementation && document.implementation.createDocument)
		{
			//xmlDoc= document.implementation.createDocument("","",null);
			//xmlDoc.load(XML);
			var oParser = null;
			oParser = new DOMParser();
			xmlDoc2 = oParser.parseFromString(XML, "text/xml");
			
		}

		return xmlDoc2;
    }


    function preparaDadosEnvio()
    //Essa função deve ser construida de acordo com o número de elementos que se deseja enviar para o servidor
    //Ex.: Se a pagina tiver um combo e um text e os dois são parametros de entrada, definir o array de dados
    //com tamanho de 2
    {
        arrValorObjetos = new Array(1);

        if(frmPrincipal.combo1.value !='')
        {
            //arrValorObjetos[0] = frmPrincipal.combo1.options[frmPrincipal.combo1.selectedIndex].text;
            arrValorObjetos[0] = frmPrincipal.combo1.value;

            montaXMLEnvio (arrValorObjetos);
        }
    }


    function montaXMLEnvio(arrDados)
    //Essa função não necessita ser editada (a não ser para implementação de melhorias) e ela deverá realizar
    //a formatação da string XML que será enviada ao servidor(Recebendo um array de dados e convertendo em string)
    {
        var strXMLEnvio;

        strXMLEnvio = "<?xml version='1.0' encoding='UTF-8'?>";
        strXMLEnvio = strXMLEnvio + "<root>";
        strXMLEnvio = strXMLEnvio + "<dados>";

        for (i = 0; i < arrDados.length; i++)
        {
            strXMLEnvio = strXMLEnvio + arrDados[i] ;
        }

        strXMLEnvio = strXMLEnvio + "</dados></root>";

		return strXMLEnvio;

    }

    function enviaDadosAJAX(documento, dadosXML, pagina, sincrono, funcao)
    //Essa função deve ser alterada a página ASP a ser acessada
    {

        var xmlHTTP = xmlhttp();
        
        
        terminouAjax = false;
		retornoDoAjax = "";
		
		if (ajaxDebug) { 

					
			alert("Página chamada: " +  pagina + "\n Enviado = \n" + dadosXML );
			
		}

		
        xmlHTTP.open("POST",pagina ,sincrono);
		xmlHTTP.setRequestHeader("charset", "UTF-8");

		//xmlHTTP.setRequestHeader("Method", "POST " + pagina + " HTTP/1.1");
		//xmlHTTP.setRequestHeader("Content-Type", "application/xml");

		xmlHTTP.setRequestHeader("Content-type", "application/xml");


		//xmlHTTP.setRequestHeader("Content-length", dadosXML.length);
		//xmlHTTP.setRequestHeader("Connection", "close");

		
		xmlHTTP.onreadystatechange = function() {

					if (xmlHTTP.readyState == 1 /* loading */ ) {
		               if (typeof(showdivAjaxCarregandoForAjax)=="function" && sincrono) {
		                  showdivAjaxCarregandoForAjax(true);
		               }
		            } else if (xmlHTTP.readyState == 2 /* loaded */ ) {
		            	 
		               if (typeof(showdivAjaxCarregandoForAjax)=="function"  && sincrono) {
		                  showdivAjaxCarregandoForAjax(false);
		               }
		            }

					if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
						terminouAjax = true;

						var responseText;
						responseText = xmlHTTP.responseText.replace(/^\s*|\s*$/g,"");

						retornoDoAjax = responseText;
						
						var txt = xmlHTTP.responseText.replace(/^\s*|\s*$/g,"");
						status = txt.charAt(0);
						
						if ( funcao != "" && sincrono ) {
						
							eval( funcao + '("' + obterRetornoXML(true) + '")');
						}
					}

					if (xmlHTTP.readyState != 4)
						return;
		}

        xmlHTTP.send(dadosXML);


//	    if (typeof(this.Request.responseText)=="unknown") {
	//		return("");
		//}

		if ( ! sincrono ) {

			retornoDoAjax = xmlHTTP.responseText.replace(/^\s*|\s*$/g,"");
			delete xmlHTTP;
			return retornoDoAjax;
					
		} else {

			delete xmlHTTP;
			return null;
		
		}

    }



    function desmontaXMLRetorno(dadosXMLRetorno, sincrono)
    
    //Essa função não necessita ser editada (a não ser para implementação de melhorias) e ela deverá realizar
    //a formatação da string XML que retorna do servidor (Recebendo uma string e convertendo em um array de dados)
    {

		if ( ajaxDebug ) {
			
			alert(dadosXMLRetorno);
		} 

  		if ( dadosXMLRetorno.indexOf("<menu>") > -1 ) {

			return dadosXMLRetorno;

		}

  		if ( dadosXMLRetorno.indexOf("RETORNODADOSASSINCRONO") > -1 ) {

			return dadosXMLRetorno;

		}		
        //Verifica se tivemos sucesso
  		if (  ( dadosXMLRetorno.indexOf("<rows>") > -1 )  ||  ( dadosXMLRetorno.indexOf("<complete>") > -1   )  )   {

			return dadosXMLRetorno;
		} else { 
		
	    	var arrValorObjetos = null;
	    	
	    	try {
	       		 var xmlDOM = xmldoc(dadosXMLRetorno.replace(/^\s+|\s+$/g,""));
			} catch (e) {
				alert("errr");
			}
	
	        //Verifica se temos Erro
	        var xmlEmlemts = xmlDOM.getElementsByTagName("erros");
	
			if ( xmlEmlemts.length > 0 ) {
	
				var arrValorObjetos = new Array(xmlEmlemts.length + 1);
		
				arrValorObjetos[0] = "ERRO";
				
				for(i = 0; i < xmlEmlemts.length; i++)
				{
				    arrValorObjetos[i+1] = unescape(xmlEmlemts[i].firstChild.nodeValue);
		
				}
		
			} 
	
	        //Verifica se temos Erro Globais
	        var xmlEmlemts = xmlDOM.getElementsByTagName("erroGlobal");
	
			if ( xmlEmlemts.length > 0 ) {
	
				var arrValorObjetos = new Array(xmlEmlemts.length + 1);
		
				arrValorObjetos[0] = "ERROGLOBAL";
				
				for(i = 0; i < xmlEmlemts.length; i++)
				{
				    arrValorObjetos[i+1] = unescape(xmlEmlemts[i].firstChild.nodeValue);
		
				}
			
			} 
	
	        //Verifica se tivemos sucesso
	        var xmlEmlemts = xmlDOM.getElementsByTagName("Sucesso");
	
			if ( xmlEmlemts.length > 0 ) {
		
				var arrValorObjetos = new Array(xmlEmlemts.length + 1);
		
				arrValorObjetos[0] = "SUCESSO";
				
				for(i = 0; i < xmlEmlemts.length; i++)
				{

					if ( xmlEmlemts[i].firstChild ) {
					
				    	arrValorObjetos[i+1] = unescape(xmlEmlemts[i].firstChild.nodeValue);
	
					} else {
					 
				    	arrValorObjetos[i+1] = "";
					}									    	
		
				}
			
			} 
			
			if ( dadosXMLRetorno.indexOf("Falha na conex") >= 0 ) {
			
				alert(dadosXMLRetorno);
				return false;
			}
			
			// Verifica se eh sincrono ou nao
			if (sincrono) {
	
				var retornoAux = "";
				
				if ( arrValorObjetos ) { 		
					for(i = 0; i < arrValorObjetos.length; i++) {
					
						retornoAux += unescape(arrValorObjetos[i]) + "$$$$$";
					
					}

					return retornoAux;

				} else {

									
					alert(dadosXMLRetorno);
					return false;

				} 					
				
			
			} else {
			
				return arrValorObjetos;
				
			}
	
		} 
		

    }

	
    function validacaoAjax(documento, arrDados, pagina, funcao, sincrono)
    //Essa função chama todo o procedimento AJAX
    {

    	// monta o XML
    	var strXMLEnvio = montaXMLEnvio(arrDados);

    	// envia os dados para o AJAX
    	var retornoXML = enviaDadosAJAX(documento, strXMLEnvio, pagina, sincrono, funcao);
    	
    	if ( !sincrono ) {
    	
    		return retornoXML;

    	} else {
    	
    		return false;
    	}
    	

	}
	
	function obterRetornoXML ( sincrono ) {

		var responseText = retornoDoAjax;

    	// obtem os dados de retorno
    	var arrValorObjetos = null;
    	arrValorObjetos = desmontaXMLRetorno(responseText, sincrono);

		if (arrValorObjetos == null) {
			return "Problemas no processamento";
		}
		else if (arrValorObjetos.length<1) {
			return "Problemas no processamento";
		}
		else if (arrValorObjetos.length == 1 ) 
		{
			return arrValorObjetos[0];
		}
		else 
		{
			return arrValorObjetos;
		}

    }

	//
	// Envia elementos para Forms de Validação
	//
    function enviaElementos(documento, pagina, funcao, sincrono) {

		var listaDeElementos = documento.getElementsByTagName("input");
		var arrDados = new Array();
		var arrRetorno;

		var j = 0;
		for(i=0;i<listaDeElementos.length;i++){
			if(listaDeElementos[i].name.substring(0,3) == 'txt'){
				var campo = listaDeElementos[i].name.replace("txt","");
				arrDados[j] = "<" + campo + ">" + escape(listaDeElementos[i].value) + "</" + campo + ">";
				j++;
			}
		}

		var listaDeElementos = documento.getElementsByTagName("textarea");
		for(i=0;i<listaDeElementos.length;i++){
			if(listaDeElementos[i].name.substring(0,3) == 'txt'){
				var campo = listaDeElementos[i].name.replace("txt","");
				arrDados[j] = "<" + campo + ">" + escape(listaDeElementos[i].value) + "</" + campo + ">";
				j++;
			}
		}


		// Chama a função de envio para o AJAX
		if ( j > 0 ) {


			// Volta os labels para normais
			var arrayLabels = documento.getElementsByTagName("LABEL");
			
			for ( j=0;j<arrayLabels.length;j++) {

				if ( arrayLabels[j].id.substr(0, 5) == "label" ) {
				
					if (arrayLabels[j].className == "") {
					
						arrayLabels[j].className = "labelOK";
					}
				}
									
			
			}

			var retornoXML = validacaoAjax(documento, arrDados, pagina, funcao, sincrono);
		
			if ( ! sincrono ) {

				arrRetorno = desmontaXMLRetorno(retornoXML, sincrono);

			} else {
			
				return true;
			}


			// Verifica se aconteceu algum erro
			if (arrRetorno[0] == "ERRO") {
			
				for(i=1;i<arrRetorno.length;i++){
				
					var conteudo = arrRetorno[i].split("||");
	
					var mensagemErro = "";
					
					for(j=0;j<conteudo.length;j++){
					
						if ( conteudo[j].length > 0 ) {
						
						
							var campos = conteudo[j].split("===");
							var labelField = "label" + campos[0];
							
							var labelElement = documento.getElementById(labelField);
							
							if ( labelElement != null ) {
							
								labelElement.className = "labelNOTOK";
							
							}
							
							mensagemErro += campos[1] + "\n";
							
						}
					}

					alert(mensagemErro);
				
				}
			
			}
			
			// Verifica se aconteceu algum erro
			if (arrRetorno[0] == "ERROGLOBAL") {
	
				var mensagemErro = "";
	
				for(i=1;i<arrRetorno.length;i++){
	
					mensagemErro += arrRetorno[i];
				}
				
				alert(mensagemErro);
			}		
	
	
			// Verifica se aconteceu SUCESSO
			if (arrRetorno[0] == "SUCESSO") {

				if ( arrRetorno[1] == "action=bemvindo.php"  || arrRetorno[1] == "OKSALVA" || arrRetorno[1] == "RETORNARDADOS" ) { 

					if ( arrRetorno[1] == "RETORNARDADOS" ) {
					
						return arrRetorno;
						
					} 

					return true;

				} else {
				
					return false;
				}
				
			}		
		
			
			if ( ( arrRetorno.indexOf("<rows>") > -1 ) || ( arrRetorno.indexOf("<complete>") > -1  )   ) {
				return arrRetorno;
				
			} 	
		}
		
		
		return false;
    }

	//
	// Realiza chamada de Ação que devolve valores a serem apresentados
	//
    function conversaComAcao(documento, pagina, funcao, sincrono) {

		//
		// Verifica se já existe o layer de carregando
		//
		var bodyElement = documento.getElementsByTagName("body");

		var listaDeElementos = documento.getElementsByTagName("input");
		var arrDados = new Array();
	
		var j = 0;

		for(i=0;i<listaDeElementos.length;i++){
		
			if(listaDeElementos[i].id.substring(0,3) == 'txt'){
				var campo = listaDeElementos[i].id.replace("txt","");
				
				arrDados[j] = "<" + campo + ">" + escape(listaDeElementos[i].value) + "</" + campo + ">";
				j++;
			}
		}
	
		if ( j == 0 ) {
		
			arrDados[j] = "<NADA>nada</NADA>";
			j++;
			
		}
		
	
		// Chama a função de envio para o AJAX
		if ( j > 0 ) {
		
			var retornoXML = validacaoAjax(documento, arrDados,  pagina, funcao, sincrono);
			
			if ( ! sincrono ) {
			
				var arrRetornoConversa = desmontaXMLRetorno(retornoXML, sincrono);

				return arrRetornoConversa;
				
			} else {
			
				return true;
			}
			
		}
		
				
		return false;
    }
 
  	//
	// Realiza chamada de Ação que devolve valores a serem apresentados
	//
    function conversaComAcaoMultiplasLinhas(documento, conteudoXML, pagina, funcao, sincrono) {

		//
		// Verifica se já existe o layer de carregando
		//
		var bodyElement = documento.getElementsByTagName("body");

		var listaDeElementos = documento.getElementsByTagName("input");
		var arrDados = new Array();
	
		var j = 0;

		for(i=0;i<listaDeElementos.length;i++){
		
			if(listaDeElementos[i].id.substring(0,3) == 'txt'){
				var campo = listaDeElementos[i].id.replace("txt","");
				
				arrDados[j] = "<" + campo + ">" + escape(listaDeElementos[i].value) + "</" + campo + ">";
				j++;
			}
		}
	
		if ( j == 0 ) {
		
			arrDados[j] = "<NADA>nada</NADA>";
			j++;
			
		} 
		
	
		// Chama a função de envio para o AJAX
		if ( j > 0 ) {
		
			arrDados[j] = conteudoXML;
			
			var retornoXML = validacaoAjax(documento, arrDados,  pagina, funcao, sincrono);
			
			if ( ! sincrono ) {
			
				var arrRetornoConversa = desmontaXMLRetorno(retornoXML, sincrono);

				return arrRetornoConversa;
				
			} else {
			
				return true;
			}
			
		}
		
				
		return false;
    }
   
    function validaConteudoRetornoAjax(documento, arrRetorno) {

		// Verifica se aconteceu algum erro
		if (arrRetorno[0] == "ERRO") {
		
			for(i=1;i<arrRetorno.length;i++){
			
				var conteudo = arrRetorno[i].split("||");

				var mensagemErro = "";
				
				for(j=0;j<conteudo.length;j++){
				
					if ( conteudo[j].length > 0 ) {
					
					
						var campos = conteudo[j].split("===");
						var labelField = "label" + campos[0];
						
						var labelElement = documento.getElementById(labelField);
						
						if ( labelElement != null ) {
						
							labelElement.className = "labelNOTOK";
						
						}
						
						mensagemErro += unescape(campos[1]) + "\n";
						
					}
				}
				
				if (mensagemErro.length > 5) { 
					alert(mensagemErro);
					return false;
				}
					
			
			}
		
		}
		
		// Verifica se aconteceu algum erro
		if (arrRetorno[0] == "ERROGLOBAL") {

			var mensagemErro = "";

			for(i=1;i<arrRetorno.length;i++){

				mensagemErro += arrRetorno[i];
			}
			
			alert(mensagemErro);
			return false;
		}		

		// Verifica se aconteceu SUCESSO
		if (arrRetorno[0] == "SUCESSO") {
				if (arrRetorno[1] == "OKSALVA") {
					arrRetorno.splice(1,1);
					arrRetorno.splice(0,1);
					return arrRetorno;
					
				} else { 
					alert(arrRetorno[1]);
					return true;
				}
				
			
		}		
    
    }
    
}
