/*
 *	AJAX Module v2
 *	Copyright 2007 - 2008 Petro Salema
 *	www.petrosalema.com
 *
 * --------------------------------------------- */


var Ajax = {


	RETRY_DELAY: 1000, // Interval between retry a busy request


	getTransport: function()
	{
		if(window.XMLHttpRequest)
		{
			return new XMLHttpRequest();
		}
		else if(window.ActiveXObject)
		{
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
		else
		{
			return false;
		}
	},


	dispatch: function(request_id, request_type, postfields)
	{/* We pass a reference to the ajax request object rather than the object itself to spare memory */

		var r = Ajax.connections[Ajax.indexOf(request_id)].request;

		if(r.busy)
		{/* If we are busy try again in 1 second */

			setTimeout(Ajax.dispatch.bindTo({}, r), Ajax.RETRY_DELAY);
			return;
		}

		var call = r.url;
		if(r.fresh) { call += ((r.url.indexOf('?') > -1) ? '&' : '?') + 'rand=' + Math.random(); }

		var t = r.transport;

		try
		{

			t.open(request_type, call, true);

			if(request_type == 'POST') t.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

			t.send(encodeURI(postfields));
			t.onreadystatechange = r.callback.bindTo(r);
		}
		catch(e)
		{
			r.failed("Could not send request");
			return;
		}

		r.busy = true;
	},


	remove: function(request_id)
	{/* Removes the Ajax request from the lists of connections */

		var c = Ajax.connections;
		var i = Ajax.indexOf(request_id);
		var r = c[i];

		/*	FOR DEBUGGING

			var trace = "";

			for(var j=0; j<c.length; j++)
			{
				trace += c[j].request.url + "\n";
			}

			alert(trace);
		*/

		if(r.timer)
		{
			clearTimeout(r.timer);
			r.timer = null;
		}

		r.transport = null;
		r.request = null;

		c.splice(i, 1);
	},


	indexOf: function(request_id)
	{
		var c = Ajax.connections;

		for(var i in c)
		{
			if(c[i].id == request_id)
			{
				return i;
			}
		}
	},


	connections: []


};


Ajax.RequestPOST = function(url, oncomplete, fresh, interval, postfields)
{
	return new Ajax.Request(url, oncomplete, fresh, interval, "POST", postfields);
}


Ajax.Request = Class({


	transporter: null,
	busy: false,
	url: null,
	oncomplete: null,
	canvas: null,
	fresh: false,
	interval: false,
	timer: null,


	init: function(url, oncomplete, fresh, interval, request_type, postfields)
	{
		this.id = (new Date).getTime();
		this.url = url;
		this.oncomplete = oncomplete;
		this.fresh = fresh || false;
		this.interval = interval || false;
		this.transport = Ajax.getTransport();

		var type = request_type || "GET";

		if(this.transport)
		{
			Ajax.connections.push({id:this.id, request:this});
			Ajax.dispatch(this.id, type, postfields);
		}
		else
		{
			this.failed("Could not create HTTPRequest object");
		}
	},


	callback: function()
	{
		var t = this.transport;

		if(t.readyState == 4)
		{
			try
			{
				if(t.status == 200)
				{
					this.succeeded();
				}
				else
				{
					this.failed(t.status + " error!");
				}
			}
			catch(e)
			{
				this.failed("Firefox error: " + e);
			}
		}
	},


	failed: function(msg)
	{
		this.transport.abort();
		Ajax.remove(this.id);
	},


	succeeded: function()
	{
		if(this.oncomplete)
		{
			this.oncomplete(this.transport.responseText);
		}

		if(this.interval)
		{/* If its a periodical request repeat it after interval milliseconds */

			this.busy = false;
			this.timer = setTimeout(Ajax.dispatch.bindTo({}, this.id), this.interval);
		}
		else
		{
			Ajax.remove(this.id);
		}
	}


});
