function Ajax() {
}

Ajax.IE = (window.ActiveXObject !== undefined);

Ajax.prototype.superClass = EventDispatcher;
Ajax.prototype.request;
Ajax.prototype.requests = [];
Ajax.prototype.state = 4;

Ajax.prototype.create = function() {
	try {
		this.request = new XMLHttpRequest();
	}
	catch (excGeneral) {
		try {
			this.request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch (excMicrosoft) {
			try {
				this.request = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch (excMicrosoft2) {
				this.request = null;

				alert("Não foi possível criar o objeto \"XMLHttpRequest\"!\nAtualize seu navegador:\n\n" + excMicrosoft2 + "\n" + excMicrosoft + "\n" + excGeneral);
			}
		}
	}
};

/*
* Converte uma String para XML
*/
Ajax.prototype.toXml = function(str) {
	var xmlObject, xml;

	xml = null;
	//str = str.split("\n").join(""); // remove as quebras de linha
	
	if (str.match(/^<\?\s*xml/) !== null) {
		if (LZ.IE) {
			xml = new ActiveXObject("Microsoft.XMLDOM");
			xml.async = "false";
			xml.loadXML(str);
			
			if (xml.parseError.errorCode === 0) {
				xml.removeChild(xml.firstChild); // para igualar ao Firefox (sem o 1º nó)
			}
			else xml = xml.parseError.reason;
		}
		else {
			xmlObject = new DOMParser();
			xml = xmlObject.parseFromString(str, "text/xml"); // executa incondicionalmente
		}
	}

	return xml;
};

Ajax.prototype.process = function(url, params) {
	if (params == null) params = {};
	
	var ref = this;
	var url = url;
	var postData = (params.postData !== undefined) ? params.postData : "";
	var method = (postData !== "") ? "post" : ((params.method !== undefined) ? params.method.toLowerCase() : "get");
	var async = (params.async !== undefined) ? params.async : true;
	var onComplete = (params.onComplete !== undefined) ? params.onComplete : function(){};
	var onProcess = (params.onProcess !== undefined) ? params.onProcess : function(){};

	this.create();
	
	this.request.onreadystatechange = function() {
		ref.state = ref.request.readyState;
		onProcess({state: ref.state});

		if (ref.state === 4) {
			var text = ref.request.responseText;
			
			onComplete({text: text, xml: ref.toXml(text)});

			if (ref.requests.length > 0) {
				var obj = ref.requests.shift(); // remove o 1º elemento da fila
				
				ref.process(obj.url, obj.params); // executa o elemento removido
			}
		}
	};

	try {
		this.request.open(method, url, async);

		if (postData !== "") this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

		this.request.send(postData);
	}
	catch (exception) {
		var o = "";

		if (LZ.IE) for (var i in exception) o += i + ": " + exception[i] + "\n";
		else o = exception;
		
		alert("ERRO:\n" + o);
	}
};

Ajax.prototype.execute = function(url, params) {
	if (this.state < 4) this.requests.push({url: url, params: params});
	else this.process(url, params);
};