/******************************************************
Arquivo para funções javascript que tenham como objetivo a navegação
e postagem de dados para o servidor.

Lista de funções:
  - addScript: Utilizado para fazer o ajax interpretar códigos HTML e Javascript.
  - deleteNode: Utilizado para remover elementos filhos de um pai.
  - postar: Posta os dados do formulário especificado.
  - postarAjax: Posta os dados do formulário especificado, através de AJAX. 

TODO:
  - Implementar fila na utilização do ajax  
******************************************************/


/******************************************************
Variável global para acesso XML
******************************************************/
var kXML = null;
if (kXML==null) {
  try {
    kXML = new ActiveXObject("Msxml2.XMLHTTP")}
  catch(e) {
    try { kXML = new ActiveXObject("Microsoft.XMLHTTP"); } 
    catch(sc) { kXML = null; }
  }
  if (!kXML && typeof XMLHttpRequest != "undefined") kXML = new XMLHttpRequest();
}
if (kXML==null)  alert(msg.errNaoSuportaXML);

if(typeof(filaAJAX)=='undefined'){
	// cria a fila
	var filaAJAX = new Array();
	var ifila = 0;
}
/******************************************************
addScript(script: String): void 
Para utilização deste, é necessário que o elemento BODY tenha
o id "body1".
Utilizado para fazer o ajax interpretar códigos HTML e Javascript.
Sempre utilizado pela função postarAjax.
  - script: Código javascript
******************************************************/
function addScript(script){    
  deleteNode('body1');
  var codigo = ""+script.match(/([a-zA-Z0-9./_-]*.js)/g); 
  var arquivos = codigo.split(",");
  for(i=0;i<arquivos.length;i++) {
    elemento = document.createElement("script");
    elemento.setAttribute('type','text/javascript');
    elemento.setAttribute('src',arquivos[i]);
    document.body.appendChild(elemento);
  }
  extraiScript(script);
}

/******************************************************
extraiScript(texto: String): void 
Utilizado para fazer o ajax interpretar códigos Javascript
dentro de templates HTML.
Sempre utilizado pela função postarAjax.
  - texto: Texto retornado do ajax
******************************************************/
function extraiScript(texto){
  var ini = 0;
  while (ini!=-1){
    ini = texto.indexOf('<script>', ini);
    if (ini >=0){
      ini = texto.indexOf('>', ini) + 1;
      var fim = texto.indexOf('</script>', ini);
      codigo = texto.substring(ini,fim);
      novo = document.createElement("script")
      novo.text = codigo;
      document.body.appendChild(novo);
    }
  }
}

/******************************************************
deleteNode(element: String): void 
Utilizado para remover todos os elementos do tipo scritp abaixo da tag
especificada.
Sempre utilizado pela função postarAjax.
  - element: Elemento pai
******************************************************/
function deleteNode(element){
  var label=document.getElementById(element); 
  for(i=0;i<label.childNodes.length;i++) {
    if(label.childNodes.item(i).nodeName=='SCRIPT') label.removeChild(label.childNodes.item(i));
  }
}

/******************************************************
postar(frm: String, action: String, target: String, mod: String, smod: String, acao: String, cpo: String, vlr: String, popup: Boolean, width: Integer, height: Integer): void 
Posta os dados do formulário especificado. Dentro do formulário é necessário 
que se tenha 3 campos hiddens (modulo, submodulo, acao). 
  - frm: Formulário (Caso não exista, ele cria o elemento form especificado
  - action: Arquivo de destino do post
  - target: Janela de destino (padrão deve ser "_self")
  - mod: Módulo do sistema
  - smod: Submódulo do sistema
  - acao: Ação que deverá ser executada
  - cpo: Campo do formuláro
  - vlr: Valor do campo especificado no parâmetro "cpo"
  - popup: <true|false> Se o alvo da ação deve ser um Pop-Up
  - width: largura do Pop-Up
  - height: altura do Pop-Up
  - ret: <true|false> Se true, ajax não sera contado na sessão de retorno  
******************************************************/
function postar(frm,action,target,mod,smod,acao,cpo,vlr,popup,width,height,ret){
	try{
	  if(popup) {
	    var WindowObjectReference = null;
	    if(WindowObjectReference == null || WindowObjectReference.closed) {
	      WindowObjectReference = window.open('',target,'resizable=yes,width='+width+',height='+height+',status=no,scrollbars=no');
	      if (WindowObjectReference.window.screen) WindowObjectReference.window.moveTo(0,0);
	    } else {
	      WindowObjectReference.focus();
	    }    
	  }   

		// Caso não exista o form especificado 
	  if(!document.forms[frm]) {
			o = {act:action,modulo:mod,submodulo:smod,ac:acao};
			f = createFormNav(frm,o);		  
	  }else{ 
	  	f = document.forms[frm];	  
		  f.modulo.value = mod;
		  f.submodulo.value = smod;
		  f.acao.value = acao;
  	}
	  
	  try{
		  // Quando retorno for especificado e igual a 1 ele não adiciona o post na sessão de historico de navegacao  	
		  if(ret==true){ 
			  incluirCampoForm(f,'hidden','retorno','retorno',1);
		 	}	
	
			if(cpo) {
			  incluirCampoForm(f,'hidden',cpo,cpo,vlr);
			} 
		}catch(e) {
			alert('Erro ao tentar criar campo hidden cpo ou retorno dinamicamente no form');
	  	alert('Erro: '+e.message);
		}  
	 	
	  f.method = 'POST';
	  f.action = action;
	  f.target = target;
	  f.submit();
	}catch(e) {
	  alert('Erro: '+e.message);
	}  
}

/******************************************************
postarAjax(frm: String, action: String, local: String, mod: String, smod: String, acao: String, , cpo: String, vlr: String): void 
Posta os dados do formulário especificado, através de AJAX. 
  - frm: Formulário
  - action: Arquivo de destino do post
  - local: Local (elemento) aonde será colocado retorno. Se valor for
            vazio, significa que retorno é código js.
  - mod: Módulo do sistema
  - smod: Submódulo do sistema
  - acao: Ação que deverá ser executada
  - cpo: Campo do formuláro
  - vlr: Valor do campo especificado no parâmetro "cpo"
  - ret: <true|false> Se true, ajax não sera contado na sessão de retorno
******************************************************/
function postarAjax(frm,action,local,mod,smod,acao,cpo,vlr,ret){  
  document.getElementById('loading').innerHTML = '<img src="./imagens/loading.gif" border="0" align="absmiddle" width="15" height="15"> &nbsp; &nbsp; Carregando';
  document.body.style.cursor = 'wait';
  var kDados = 'modulo='+mod+'&submodulo='+smod+'&acao='+acao+'&local='+local+'&ajax=1';
  if(ret) kDados+= '&retorno=1'; // Quando retorno for especificado e igual a 1 ele não adiciona o post na sessão de historico de navegacao
  if(cpo) kDados+= '&'+cpo+'='+vlr; 
	//alert(kDados);
  try {
    if (frm) {
    
    
    /*
			// Caso não exista o form especificado 
		  if(!document.forms[frm]) {
				o = {act:action,modulo:mod,submodulo:smod,ac:acao};
				frm = createFormNav(frm,o);		  
		  }else{ 
		  	frm = document.forms[frm];	  
	  	}
	  	*/
	  	frm = document.forms[frm];	


			try{		
	      // Para cada um dos elementos do formulário
	      for (var i=0;i<frm.elements.length;i++) {
	
	        if (((frm.elements[i].type=="radio") || (frm.elements[i].type=="checkbox")) && (frm.elements[i].checked)) {
	          kDados += "&"+frm.elements[i].name+"="+escape(frm.elements[i].value);
	
	        } else if ((frm.elements[i].type!="radio") && (frm.elements[i].type!="checkbox") && (frm.elements[i].type!="button") && (frm.elements[i].type!="undefined")) {
	          // Se for múltipla seleção
	          if (frm.elements[i].type=="select-multiple") {
	            for (var z=0;z<frm.elements[i].options.length;z++){
	              if ((frm.elements[i].options[z].selected) && (frm.elements[i].options[z].value.trim()!="Null")) kDados += "&"+frm.elements[i].name+"="+frm.elements[i].options[z].value;
	            }
	          } else {
	            if (frm.elements[i].name!='modulo' && frm.elements[i].name!='submodulo' && frm.elements[i].name!='acao' && frm.elements[i].name!=cpo){ 
	            	kDados += "&"+frm.elements[i].name+"="+escape(frm.elements[i].value);
	            }
	          }
	        }
	      }
      }catch(e){  
      	//alert('Erro: \n'+e.message);    
      }    
      
    }     
    
    try{
    	enfileiraAJAX(action,kDados,local);
    	
   	
	  }catch(e){
	 		alert('Erro ao criar fila ajax: \n'+e.message);
	 	}     	
  }catch(e){
 		alert('Erro: \n'+e.message);
 	}   
}

// funcao que enfileira as chamadas AJAX
function enfileiraAJAX(action,kDados,local) {
	if(typeof(action)=='undefined' || typeof(kDados)=='undefined' || typeof(local)=='undefined' ){
		// parametros incompletos
		return;
	}
	  // adiciona o item na fila
	  filaAJAX[filaAJAX.length] = new Array(action,kDados,local);
	  // se a fila estiver vazia, inicia a execução
	  if((ifila+1) >= filaAJAX.length){ 
		execFilaAJAX();
	}else{
		return;
	}	
}

//Executa a próxima conexão da fila
function execFilaAJAX() {
  document.getElementById('loading').innerHTML = '<img src="imagens/loading.gif" border="0" align="absmiddle" width="15" height="15"> &nbsp; &nbsp; Carregando';
  document.body.style.cursor = 'wait';
  // carrega os dados da pagina da fila
  var kDados = filaAJAX[ifila][1];
  var lc = filaAJAX[ifila][2];

  kXML.open("POST",filaAJAX[ifila][0],true);

  kXML.onreadystatechange = function() {
    if (kXML.readyState == 4) {
			// requisição terminada
      var xHTML = kXML.responseText;
      if(lc==''){ 
      	try{
      		eval(xHTML);
      	}catch(e){
      		alert('Erro tentar executar eval('+xHTML+')!');
      	}        
      }
      else {
      	try{
        	var html = xHTML;
        	document.getElementById(lc).innerHTML = html.replace("'","\'");
        	addScript(xHTML);
        }catch(e){
        	alert('Erro ao incluir html!');
        }
      }
      
      try{
      	document.getElementById('loading').innerHTML = '';
      	document.body.style.cursor = 'default';
     	}catch(e){
     		alert('Erro ao tentar remover conteúdo da div loading!');
     	}
     	      	
      // remove o primeiro da fila
      filaAJAX.shift();
      if ((ifila+1) <= filaAJAX.length) setTimeout("execFilaAJAX()",2000);
      return;
    }
  }
  kXML.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  kXML.setRequestHeader("Cache-Control", "no-store, no-cache, must-revalidate");
  kXML.setRequestHeader("Cache-Control", "post-check=0, pre-check=0");
  kXML.setRequestHeader("Pragma", "no-cache");  
	kXML.send(kDados);
}

function alerta(str){
	alert(str);
}

///////////////////ajax ext 2.0.1 /////// funções abaixo não foram testadas por completo nem finalizadas. Após verificar códigos que utilizam ou não remover ou finalizar.
var evalResponse= function(r,o){
	xHTML =r.responseText;
	eval(xHTML);
};

//id do elemento html que receber na propriedade innerHTML o valor de retorno do ajax
var elInner = 'template'

var innerResponse= function(r,o){
	xHTML =r.responseText;
	var html = xHTML;
 	document.getElementById(elInner).innerHTML = html.replace("'","\'");
 	addScript(xHTML);
};

var erroAjax= function(r,o){
	alert('Erro ao executar ajax!');
};

