// Objeto AJAX para comunicação Assincrona com um servidor de aplicações WEB
function AJAX(url,metodoEnvio,params,processa,modo) {
//INICIALIZA AS VARIAVEIS PARA CONTROLE DA FILA
//fila[X][0] - Div onde sera carregada a pagina
//fila[X][1] - Pagina que sera chamada
//fila[X][2] - Metodo de envio
//fila[X][3] - Campos do form concatenados no padrao para serem enviados. Null caso seja um link

  this.ifila = 0
  this.fila = new Array();
  this.DivId = '';
  this.url = url;
  this.metodoEnvio = (metodoEnvio) ? metodoEnvio : 'GET';
  this.params  = (metodoEnvio='GET') ? null : params;
	this.processaresultado = processa;
	this.Header = new Array();
	this.modo = (modo) ? modo : 'T';
	if(this.modo!='T'&&this.modo!='X') {
		this.modo = 'T';
	}                    
	this.conectar();
}
AJAX.prototype = {
//GUARDA NA FILA O ID DO OBJETO E A URL QUE SERAO CARREGADOS PELO LINK CLICADO
  ajaxLink:  function(id_target,url){
          //Exibe mensagem de que esta carregando a pagina no objeto de ID informado
           this.MensagemCarregando('carregar');  

          //Adiciona a solicitacao na fila
          this.fila[this.fila.length]=[id_target,url,"GET",null];
          
          //Se nao tem conexoes na fila, inicia a execucao
          if(this.fila.length==1){
              this.ajaxRun();
          }
    //return;
          },

  //GUARDA NA FILA O ID DO OBJETO E O FORM QUE SERAO CARREGADOS PELO LINK CLICADO
  ajaxForm: function(id_target,id_form){
				 //Exibe mensagem de que esta carregando a pagina no objeto de ID informado
          this.MensagemCarregando('carregar'); 
          //Pega a pagina que sera chamada pelo form
           var url = document.getElementById(id_form).action;
          //Busca metodo de envio definido no form
          var metodoEnvio = document.getElementById(id_form).method.toUpperCase();
          //Busca os elementos do form que serao enviados para a pagina solicitada
          var elementos_form = this.BuscaElementosForm(id_form);

          //Adiciona a solicitacao na fila
          this.fila[this.fila.length]=[id_target,url,metodoEnvio,elementos_form];

          //Se nao tem conexoes na fila, inicia a execucao
          if(this.fila.length==1){
              this.ajaxRun();
          }
          return;
        },
  
//EXECUTA A PROXIMA SOLICITACAO DA FILA
 ajaxRun: function(){
        var url = this.fila[this.ifila][1];
        this.DivId = this.fila[this.ifila][0];
        //Define o metodo de envio (GET ou POST)
        var metodoEnvio;
        if (this.fila[this.ifila][3]==null){
            //Se for Link, utiliza GET
            metodoEnvio = "GET";
        }else{
            //Se for Form, define o metodo de envio e prepara a url
            metodoEnvio = this.fila[this.ifila][2];
            if (metodoEnvio=="" || metodoEnvio==null){
                //Se nao tiver definido nada, usa POST
                metodoEnvio = "POST";
                
            }
            if (metodoEnvio=="GET"){
                //Metodo GET passa as informacoes na linha da url
                url = url + "?" + this.fila[this.ifila][3];
            }else {
               this.params =  this.fila[this.ifila][3];
            }
            
        }   
        this.metodoEnvio = metodoEnvio;
        this.url = url;
        this.conectar();
    
        },

//FUNCAO PARA PEGAR OS CODIGOS SCRIPT
 ExtraiScript: function(texto){
        var ini, pos_src, fim, codigo, texto_pesquisa;
        var objScript = null;
        //Joga na variavel de pesquisa o texto todo em minusculo para na hora da pesquisa nao ter problema com case-sensitive
        texto_pesquisa = texto.toLowerCase()
        // Busca a primeira tag <script
        ini = texto_pesquisa.indexOf('<script', 0)
        // Executa o loop enquanto achar um <script
        while (ini!=-1){
              //Inicia o objeto script
              var objScript = document.createElement("script");
              //Busca se tem algum src a partir do inicio do script
              pos_src = texto_pesquisa.indexOf(' src', ini)
              // Define o inicio para depois do fechamento dessa tag
              ini = texto_pesquisa.indexOf('>', ini) + 1;

              //Verifica se este e um bloco de script ou include para um arquivo de scripts
              if (pos_src < ini && pos_src >=0){//Se encontrou um "src" dentro da tag script, esta e um include de um arquivo script
                  //Marca como sendo o inicio do nome do arquivo para depois do src
                  ini = pos_src + 4;
                  //Procura pelo ponto do nome da extencao do arquivo e marca para depois dele
                  fim = texto_pesquisa.indexOf('.', ini)+4;
                  //Pega o nome do arquivo
                  codigo = texto.substring(ini,fim);
                  //Elimina do nome do arquivo os caracteres que possam ter sido pegos por engano
                  codigo = codigo.replace("=","").replace(" ","").replace("\"","").replace("\"","").replace("\'","").replace("\'","").replace(">","");
                  // Adiciona o arquivo de script ao objeto que sera adicionado ao documento
                  objScript.src = codigo;
              }else{//Se nao encontrou um "src" dentro da tag script, esta e um bloco de codigo script
                  // Procura o final do script
                  fim = texto_pesquisa.indexOf('</script>', ini);
                  // Extrai apenas o script
                  codigo = texto.substring(ini,fim);
                  // Adiciona o bloco de script ao objeto que sera adicionado ao documento
                  objScript.text = codigo;
              }

              //Adiciona o script ao documento
              document.body.appendChild(objScript);
              // Procura a proxima tag de <script
              ini = texto.indexOf('<script', fim);

              //Limpa o objeto de script
              objScript = null;
          }
        },

//FUNCAO PARA PEGAR OS ELEMENTOS DO FORM
  BuscaElementosForm: function(idForm) {
        var elementosFormulario = document.getElementById(idForm).elements;
        var qtdElementos = elementosFormulario.length;
        var queryString = "";
        var elemento;

        //Cria uma funcao interna para concatenar os elementos do form
        ConcatenaElemento = function(nome,valor) {
                                    if (queryString.length>0) {
                                        queryString += "&";
                                    }
                                    queryString += encodeURIComponent(nome) + "=" + encodeURIComponent(valor);
                                 };

        //Loop para percorrer todos os elementos
        for (var i=0; i<qtdElementos; i++) {
          //Pega o elemento
          elemento = elementosFormulario[i];
          if (!elemento.disabled) {
            //Trabalha com o elemento caso ele nao esteja desabilitado
            switch(elemento.type) {
            //Realiza a acao dependendo do tipo de elemento
                case 'text': case 'password': case 'hidden': case 'textarea':
                    ConcatenaElemento(elemento.name,elemento.value);
                    break;
                case 'select-one':
                    if (elemento.selectedIndex>=0) {
                        ConcatenaElemento(elemento.name,elemento.options[elemento.selectedIndex].value);
                    }
                    break;
                case 'select-multiple':
                    for (var j=0; j<elemento.options.length; j++) {
                        if (elemento.options[j].selected) {
                            ConcatenaElemento(elemento.name,elemento.options[j].value);
                        }
                    }
                    break;
                case 'checkbox': case 'radio':
                    if (elemento.checked) {
                        ConcatenaElemento(elemento.name,elemento.value);
                    }
                    break;
                }
              }
            }
          return queryString;
        },

// ATIVAR O CARREGA E DESATIVAR QUANDO TERMINAR
  MensagemCarregando: function(id){
        var e = document.getElementById(id);
          if (e.className=="escondido") {
            e.className="mostra";
          } else {
            e.className="escondido";
          }  
        },

  addHeader:	function(h,v) {
					this.Header[h] = v;
				},
	delHeader:	function(h) {
					delete(this.Header[h]);
				},
	setHeader:	function() {
					if(this.httprequest==null) { return;} 
					for(h in this.Header) {
						this.httprequest.setRequestHeader(h,this.Header[h]);
					}
				},
	conectar:		function() {
					 if(this.url==undefined||this.url=='') {
								return; 
					 }
							this.httprequest = null;
              try{
                this.httprequest = new XMLHttpRequest();// Mozilla, Safari, Firefox, etc...
                  try {
                    if (this.httprequest.overrideMimeType) {
                    //Se possível, ignora cabecalho usado pelo servidor e forca o padrao "text/xml". Alguns navegadores exigem esse padrao e pode dar erro se o servidor nao utilizar ele
                      this.httprequest.overrideMimeType('text/xml');
                    }
                  } catch (e1) { }
              }catch(e2){
                  try{
                    this.httprequest = new ActiveXObject("Msxml2.XMLHTTP");// Internet Explorer
                  }catch(e3){
                      try{
                        this.httprequest = new ActiveXObject("Microsoft.XMLHTTP");// Internet Explorer
                      }catch(e4){
                      //tratamento para alguma outra forma de implementar XMLHTTP
                      this.httprequest = false;
                      }
                  }
              }
              if (!this.httprequest){
                  //Nao conseguiu instanciar o objeto xmlhttp para fazer as solicitacoes
                  alert("Erro de AJAX. Seu browser deve suportar o objeto de XMLHttpRequest ou permitir o uso de scripting.");
              }
              if(this.httprequest!=null&&this.httprequest!=undefined) {
						      var obj = this;
							    this.httprequest.onreadystatechange = 	function() {
                                          obj.processaretorno.call(obj);
																		    }
              
                //Executa a solicitacao
                if(this.metodoEnvio==undefined||this.metodoEnvio=='') { 
                  this.metodoEnvio = 'GET';
                } 
         
                this.httprequest.open(this.metodoEnvio,this.url, true);
							  
                //Metodo POST precisa definir este RequestHeader 
                if (this.metodoEnvio=='POST') {
                   this.addHeader('Content-Type','text/xml'); 
                   this.addHeader('encoding','ISO-8859-1');
                   this.addHeader('Content-Type', 'application/x-www-form-urlencoded'); 
                   this.addHeader('Content-length', this.params.length ); 
                }  
                this.setHeader();
						    this.httprequest.send(this.params);
                
					    }
						},
	processaretorno:	function() {
            var retorno;
            if(this.httprequest.readyState==4) {
                  if(this.httprequest.status==200) {
                      if (this.modo=='T') {
                         retorno = unescape(this.httprequest.responseText.replace(/\+/g," "));
                      } else {
                         retorno = this.httprequest.responseXML;
                      }
                      //var retorno = (this.modo=='T') ? this.httprequest.responseText : this.httprequest.responseXML;
									    
                      if(this.processaresultado!=null) {
										    this.processaresultado(retorno);
									    } else {
  											 var Div =  document.getElementById(this.DivId);
												 if (this.modo=='T') {
                           //Exibe o valor retornado no objeto de ID informado
														Div.innerHTML=retorno;
                         } else {
                            document.write(retorno);
                         }
									    }
                      this.MensagemCarregando('carregar');     
								  } else { 
  			              //Caso o status ainda nao foi tratado, chama a funcao de tratamento de pagina de erro
                      this.ajaxPaginaErro(this.httprequest);
                      this.MensagemCarregando('carregar'); 
								  }
					  }

                //Exibe o valor retornado no objeto de ID informado
               // this.ExtraiScript(retorno);

                //passa para a proxima posicao da fila
                this.ifila++;
                if(this.ifila<this.fila.length){
                    //Caso tenha mais solicitacoes na fila, executa a proxima
                    setTimeout("this.ajaxRun()",20);
                }else{
                    //Caso nao tenha mais solicitacoes na fila, reinicia a fila
                    this.fila = null;
                    this.fila = new Array();
                    this.ifila = 0;
                }
              //return;
              


						},
//FUNCAO PARA RETORNAR A MENSAGEM DE ERRO QUANDO O SERVIDOR RETORNAR UMA PAGINA DE ERRO
 ajaxPaginaErro: function(httprequest){
        var retorno;
        switch (httprequest.status) {
              case 404:
                  return "Página não encontrada!!!";
                  break;
              case 500:
                  return "Erro interno do servidor!!!";
                  break;
              default:
                  return "Erro desconhecido!!!<br>" + httprequest.status + " - " + httprequest.statusText.replace(/\+/g," ");
          }
        }

} //fim