/**
 * @author Henrique
 */



function Ajax(last)
{
	//Variaveis globais (privadas)
	var self = this;
	var vez = null;
	var fila = new Array();
	var method = "POST";
	var lastTime = 0;
	var lastId = last;
	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,func) {
		this.pag = pag;
		this.param = param;
		this.func = func;
	}
	
	//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)
				{
					if(vez.func != null)
					{
						var texto = xmlhttp.responseText;
						eval(vez.func+"(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.chamada = function (pag,param,func){
		if(vez == null)
		{
			//adiciona para a chamada atual
			vez = new objRequest(pag,param,func);
			//delay, if need
			delay();
		}
		else
		{
			//adiciona chamada na fila
			fila.push(new objRequest(pag,param,func));
		}
	}
	
	//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;
	}
}