/**
 * @author Thiago Victorino
 */
function ajax() {
	/**
	 * Modo de como a requisição será enviada GET/POST
	 * Por default ela vem como GET
	 */
	this.modo = "GET";
	
	
	this.recursivo = false;
	/**
	 * A URL em que será disparada a requisição
	 */
	this.url = null ;
	
	
	
	/**
	 * O modo como irá retornar a resposta
	 * do servidor XML/TEXT
	 * por default ela vem XML
	 * (Por enquanto não está em uso!!!)
	 */
	this.modoRetorno = "xml";
	
	
	
	/**
	 * É, na realidade a variavel send que eu envio
	 * caso eu uso o metodo POST, como o atributo modo está por default
	 * GET ela será definida como default 'null'
	 */
	this.sendi = null;
	
	
	
	/**
	 * É o estado em que se encontra a requisição (readdyState)
	 * Ela pode ser usada para funções em qnto se usa
	 * o metodo onCarregando
	 */
	this.estado = null;
	
	
	
	/**
	 * É o objeto XMLResquest criado para as requisições
	 */
	this.httpRequest = null;
	
	
	
	/**
	 * Atributo que será preenchida via função onSucesso
	 */
	this.respostaXML = null;
	
	
	
	/**
	 * Atributo que será preenchida via função onSucesso
	 */
	this.respostaText = null;
	
	
	
	/**
	 * Atributo que formará a fila das requisições
	 */
	this.fila=[];
	
	
	
	/**
	 * Array que conterá as informações do erro CASO ELE OCORRA
	 * poderá ser usada com a função onErro
	 */
	this.displayErrors = [];
	
	
	
	/**
	 * @method setVarPost
	 * Seta o valor das variaveis caso eu queira enviar via POST
	 * @param {String} nome Nome da variavel
	 * @param {String} valor Valor da variavel
	 */
	this.setVarPost = function (nome,valor){
		if(this.sendi == null){
			this.sendi = nome+"="+valor;
		}
		else{
			this.sendi += "&"+nome+"="+valor;
		}
	}
	/**
	 * @method getErrors
	 * Retorna o erro dependendo da opção que eu escolher
	 * As opções são:
	 *     * - ESTATUS : Retorna o código do erro
	 *     * - ESTATUSTEXT: Retorna o erro escrito
	 *     * - URL: Retorna a URL utilizada que causou o erro
	 * @return {String} erro em formato string
	 * @param  {String} op
	 */
	this.getErrors = function (op){
		op = op.toUpperCase();
		if(op == "ESTATUS")
		 {
		 	return this.displayErrors[0];
		 }
		else if(op == "ESTATUSTEXT")
		 {
		 	return this.displayErrors[1];
		 }
		else if(op == "URL")
		 {
		 	return this.displayErrors[2];
		 }
	};
	/**
	 * @method getEstatus
	 * Função para pegar o estatus atual
	 * Util para usar no metodo onCarregando
	 * @return {Integer} retorna o estatus
	 */
	this.getEstado = function(){
		return this.estado;
	};
	/**
	 * Cria a fila das requisições
	 */
	this.filaDeRaquisicao = function()
	{
	  this.fila[this.fila.length] = new Array(this.url,this.modo,this.modoRetorno,this.sendi,this.onSucesso,this.onCarregando,this.onErro); 
	  // this.fila[0] = new Array(this.url,this.modo,this.modoRetorno,this.sendi,this.onSucesso,this.onCarregando,this.onErro); 
	};
	/**
	 * @method enviar
	 * Adiciona primariamente na fila 
	 * Caso ele seja um único na fila ele logo após faz a requisição
	 * @param {String} url
	 */
	this.enviar = function (url)
	 {
		 this.url = url;
		 var _this = this;
		_this.filaDeRaquisicao.call(_this);	  
	    if(_this.fila.length == 1){//verifica se ele é o primeiro da fila, se for começa a requisição
		_this.requisitar.call(_this,_this.fila[0][0]);
	   }
	 };
	/**
	 * @method setModo
	 * Configura o modo de envio GET/POST
	 * @param {String} modo Modo como ele será enviado GET ou POST
	 */
	this.setModo = function(modo){
		this.modo = modo;
	};
	
	/**
	 * @method requisitar
	 * Faz a requisição AJAX
	 * É um método PRIVADO
	 * @param {String} url URL que será enviada
	 */
	this.requisitar = function(){
		
		var  _this = this;
		if (window.XMLHttpRequest) { // Mozilla, Safari,...
		  this.httpRequest = new XMLHttpRequest();
		} 
		else if (window.ActiveXObject) { // IE
		 try {
		     this.httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
		 } 
		 catch (e){
		  try {
		       	 this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
		  } 
		  catch (e) {}
		 }
	    }
		this.httpRequest.onreadystatechange = function(){_this.processaRetorno.call(_this);};
		if(this.fila[0][0].indexOf('?')==-1)
		  {
	  		random_ = '?'+Math.ceil(Math.random()*100000);
		  }
		else
		  {
	  		random_ = '&'+Math.ceil(Math.random()*100000);
		  }
		try{
			this.httpRequest.open(this.fila[0][1],this.fila[0][0]+random_, true);
			//Adiciona alguns cabeçalhos caso queira usar post
			if(this.fila[0][1].toUpperCase() == "POST" )
			 {
				this.httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
				//Esta próxima chamada, se descomentada, faz nada mais funcionar nos módulos.
				//this.httpRequest.setRequestHeader("Content-length", this.sendi.length);
				//Fechava a conexão no IE antes de processar o resto.
			    //this.httpRequest.setRequestHeader("Connection", "close");
		 	
			 }
			this.httpRequest.setRequestHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
			/**
			 * Verifica se deu um erro de conexao
			 */
				//Quando o conteúdo é nulo não pode-se enviar via post,
				// por isso define-se como 1 caso seja nulo e seja do tipo Post,
				// caso contrário, apenas envia a requisição.
				//fonte:http://www.zapatec.com/website/forums/viewtopic.php?p=3128&sid=523e1069b1b1c7623e14107ac369a965
				if(this.fila[0][3]===null && this.fila[0][1].toUpperCase() == "POST")
					this.fila[0][3]="a="+ 1;
				
				this.httpRequest.send(this.fila[0][3]);	
		}
		catch(e){
			try{var mensagemErr = "ERRO "+e.description+"\n\n";
			mensagemErr += "\tFoi perdida a sua conexão com a internet\n";
			mensagemErr += "\tEsse aplicativo pode não funcionar corretamente\n";
			mensagemErr += "\tVerifique sua conexão e atualize a página.";
			alert(mensagemErr);}catch(e){}
		}
	    if(!this.recursivo){
			this.fila[0][3]= null;
			this.sendi = null;	
		}
		
	};

	/**
	 * Defeini se as requisições serão recursivas ou não
	 * Na verdade ele por enquanto somente está sendo utilizada na classe
	 * pingRequest
	 * @param {Boolean} bool Verdadeira caso seja resursivo e false para o inverso
	 */
	this.setRecursivo = function(bool){
		this.recursivo = bool;
	};
	/**
	 * @method processaRetorno
	 * É um método PRIVADO
	 * ELe é exucutado no evento onreadystatechange do httpXMLRequest
	 * Procesa o retorno de acordo como foi configurada
	 * E caso tenha alguém na fila, executa o próximo
	 */
	this.processaRetorno =  function(){
		var  _this = this;
		this.estado = this.httpRequest.readyState;
		if(this.estado!=4)
		  {
			this.onCarregando = this.fila[0][5];
			this.onCarregando();
		  }
		if(this.estado==4)
		  {
		    
			/**
			 * Essa verificação é feita para ver se da um erro
			 * quando tenta verifivar o status
			 */
			try{
				this.httpRequest.status;
				var estatus = true;
			}
			catch(e){
				var estatus = false;
			
			}
			if(estatus){
				if(this.httpRequest.status==200)
				 {
					//alert("Esse vem da classe\n\n"+this.httpRequest.responseText)
					this.respostaText = this.httpRequest.responseText;//coloco elas aqui para funcionar a função getRespostaText
				    this.respostaXML = this.httpRequest.responseXML; //coloco elas aqui para funcionar a função getRespostaXML
		     		this.onSucesso = this.fila[0][4];
					this.onSucesso();
				 }
				 else{
					if(this.httpRequest.status == 12029){
						var mensagemErr = "ERRO: Conexão Indisponível\nCódigo: "+this.httpRequest.status+"\n";
						mensagemErr += "\nFoi perdida a sua conexão com a internet e";
						mensagemErr += "\nesse aplicativo pode não funcionar corretamente."; 
						mensagemErr += "\nVocê terá que recarregar o sistema após a correção do problema com sua conexão";
						mensagemErr += "\n\n Deseja recarregar o sistema agora?";
						var res = confirm(mensagemErr);
						if(res){
							parent.window.location.reload();
							return this.httpRequest.status;
						}else{
							
						}
						
	
					}else{
						//alert("Erro\nCódigo: "+this.httpRequest.status);
					}
					try{
						this.displayErrors[0] = this.httpRequest.status;
					    this.displayErrors[1] = this.httpRequest.statusText;	
					}catch(e){
						this.displayErrors[0] = undefined;
					    this.displayErrors[1] = undefined;
					}
					this.onErro = this.fila[0][6];
					
					this.displayErrors[2] = this.fila[0][0];
					this.onErro();
			 }	
			}
			
		 this.fila.shift();//deleta o primeiro
		 if(this.fila.length>0){
		   _this.requisitar.call(_this);//executa o proximo, caso haja
		 }
	  }
	};
	/**
	 * @method getRespostaXML
	 * @return {Object} this.respostaXML 
	 * Retorna o valor XML da requisição
	 */
	this.getRespostaXML = function(){
		
		if(this.verificarSessao()){
			
			if(navigator.appName == "Microsoft Internet Explorer"){
									
				//Eu fiz isso pq o IE não estava entendendo o XML
				//Ae eu fiz um parser da string e transformei em um objeto XML
				var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
			    xmlDoc.async="false";
				
			    try {
					xmlDoc.loadXML(this.getRespostaText());
				}catch(e){
					//alert("try 1: "+e.description);
					this.respostaXML = null;
				}
				
				try {
					this.respostaXML = xmlDoc.documentElement;
				}catch(e){
					//alert("try 2: "+e.description);
					this.respostaXML = null;
				}
				
				return this.respostaXML; 
			
			}
			else{
			  	
				try{
					xml = this.respostaXML.documentElement;
				}
				catch(e){
					//alert(e+"\n\nConteudo: "+this.getRespostaText())
					xml = null;
				}
	  			
				return xml;	
			
			}
			
		}
		
	};
	
	
	/**
	 * @method getRespostaJson
	 * @return {Object} this.respostaText com eval 
	 * Retorna o valor em objeto da requisição
	 */
	this.getRespostaJson= function(){
		if(this.verificarSessao()){
			return eval(this.respostaText);	
		}
		
	};

	/**
	 * @method getRespostaText
	 * @return {String} this.respostaText 
	 * Retorna o valor texto da requisição
	 */
	this.getRespostaText= function(){
		if(this.verificarSessao()){
			return this.respostaText;	
		}
		
	};
	/**
	 * Faz a verificação se a sessão PHP foi
	 * encerrada ou não
	 */
	this.verificarSessao = function(){
		if(this.respostaText == "sessao = false"){
			alert('Sua sessão expirou (JS) .\nVocê estará sendo redirecionado a tela de login \npara que seja feito a entrada no sistema novamente');
			parent.parent.parent.parent.location.reload();
			return false;
		}else{
			return true;
		}
	};
	/**
	 * funções de implementação 
	 *
	 * @method onCaregando
	 */
	this.onCarregando = function(){};
	/**
	 * @method onSucesso
	 */
	this.onSucesso = function(){};
	/**
	 * @method onError
	 */
	this.onErro = function(){};
}

/**
 *
 * Created on 20/09/2007
 * @author Thiago Victorino
 * @version 1.0
 * @copyright Copyright &copy; 2007 
 * @classDescription Essa classe irá simular o "Ajax Reverso"
 */
function PingRequest(){
	
	var destino;
	var intervalo = 5000;//valor padrão de 5 segundos
	var timer;
	var _this = this;
	
	/**
	 * Definie o destino de para onde vai as requisições
	 * @param {String} url Uma strign de URL
	 */
	this.setDestino = function(url){
			destino = url;
	};
	/**
	 * Define o intervalo em SEGUNDOS para cada requisição
	 * @param {int} intervalo Numero inteiro de quantos segundo deve-se 
	 * fazer a requisição
	 */
	this.setIntervalo = function(intervalo){
		intervalo = (intervalo * 1000); 
	};
	
	/**
	 * Desliga as requisições
	 */
	this.desligar =function(){
		clearInterval(timer);
	};
	
	/**
	 * Faz a requisição Ajax
	 */
	this.pingar = function(){
		this.setRecursivo(true);
		this.enviar(destino);
	};
	/**
	 * Liga as requisições
	 */
	this.ligar = function(){
		timer = setInterval(function(){_this.pingar();},intervalo);
		
	};
	this.onRetorno = function(){};
	this.onSucesso = function(){
		this.onRetorno();
	};
}
PingRequest.prototype = new ajax();

