/**
 * @author Henrique
 */
function Ajax(){
	//Variaveis globais (privadas)
	var self = this;
	var vez = null;
	var fila = new Array();
	var method = "POST";
	var lastTime = 0;
	var assincrono = true;
	var xmlhttp;
	
	novoObjeto();
	setInterval(function(){
		rotina()
	},4000);
	
	//cria objeto ajax
	function novoObjeto(){
		try{
			xmlhttp = new XMLHttpRequest();
		}
		catch(ee){
			try{
				xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(e){
				try{
					xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch(E){
					xmlhttp = false;
				}
			}
		}
	}
	
	//objeto de requisição
	function objRequest(pag,param,val,tipo) {
		this.pag = pag;
		this.param = param;
		this.val = val;
		this.tipo = tipo;
	}
	
	//calcula tempo atual
	function UTCTime() {
		var atual = new Date();
		return Date.UTC(atual.getFullYear(), atual.getMonth(), atual.getDate(), atual.getHours(), atual.getMinutes(), atual.getSeconds(), atual.getMilliseconds());
	}
	
	//funcao que realiza requisição
	function ajaxRequest() {
		inicialTime = UTCTime();
		
		if(method == "POST")
			xmlhttp.open(method, vez.pag+"?rand="+UTCTime() , assincrono);
		else
		 	xmlhttp.open(method, vez.pag+"?rand="+UTCTime()+"&"+vez.param , assincrono);
			
		//bug firefox
		try {
			xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		}
		catch(e) {
			
		}
		
		xmlhttp.onreadystatechange = function(){
			if (xmlhttp.readyState == 4){
				var status = 0;
				try{
					status = xmlhttp.status;
				}catch(e){
					novoObjeto();
					return;
				}
				//caso seja uma pagina valida
				if(status == 200){
					var texto = xmlhttp.responseText;
					if (vez.tipo == 2){
						if(vez.val != null)
							eval(vez.val + "(texto)");
					}else if (vez.tipo == 1){
						document.getElementById(vez.val).innerHTML = texto;
						interpretador(texto);
					}else if (vez.tipo == 3){
						eval(texto);
					}
					lastTime = UTCTime();
					if(fila.length > 0){
						vez = fila.shift();
						delay();
					}else
						vez = null;
				}
				// caso ocora algum erro...
				else if(status != 0){
					inicialTime = UTCTime();
					setTimeout(function() { ajaxRequest() },12000);
				}
			}
		};
		//bug firefox
		try{
			if(method == "POST")
				xmlhttp.send(vez.param);
			else
				xmlhttp.send();
		}catch(e) {}
	}
	
	
	function delay(){
		var diferenca = UTCTime() - lastTime;
		if(diferenca > 700)
			ajaxRequest();
		else{
			diferenca = 700 - diferenca;
			setTimeout(function() {
				ajaxRequest()
			}, diferenca);
		}
	}
	
	//rotina para verificar se a chamada ajax está demorando para ser respondida
	//caso sim, aborta e inicia novamente
	function rotina(){
		if(vez != null){
			var diferenca = UTCTime() - inicialTime;
			if (diferenca > 14000) 
				self.abortar();
		}
	}
	
	this.chamadaJSON = function (pag,param){
		if(vez == null){
			//adiciona para a chamada atual
			vez = new objRequest(pag,param,null,3);
			//delay, if need
			delay();
		}else{
			//adiciona chamada na fila
			fila.push(new objRequest(pag,param,null,3));
		}
	}
	
	this.chamadaFunc = function (pag,param,val){
		if(vez == null){
			//adiciona para a chamada atual
			vez = new objRequest(pag,param,val,2);
			//delay, if need
			delay();
		}else{
			//adiciona chamada na fila
			fila.push(new objRequest(pag,param,val,2));
		}
	}
	
	//
	this.chamadaDiv = function (pag,param,val){
		if(vez == null){
			//adiciona para a chamada atual
			vez = new objRequest(pag,param,val,1);
			//delay, if need
			delay();
		}else{
			//adiciona chamada na fila
			fila.push(new objRequest(pag,param,val,1));
		}
	}
	
	//altera metodo
	this.setMethod = function(metodo){
		method = metodo;
	}
	
	//obtem metodo
	this.getMethod = function(){
		return method;
	}
	
	//aborta chamada ajax
	this.abortar = function(){
		xmlhttp.abort();
		ajaxRequest();
	}
	
	//altera tipo do ajax
	this.setAssicrono = function(val){
		assicrono = val;
	}
	
	//obtem tipo do ajax
	this.getAssicrono = function(){
		return assincrono;
	}
	
	function interpretador(html){
		var inicio = html.search(/<script>/);
		if(inicio != -1) {
			inicio += 8;
			var fim = html.search(/<\/script>/);
			var script = html.substr(inicio,fim - inicio);
			eval(script);
		}
	}
}
//var ajax = new Ajax();