//
// Class Proxy
//

function Proxy()
{
}

// Signature:
// public void laod(String url, Function callback);
Proxy.prototype.load = 0;

Proxy.create = function()
{
	return new XmlHttpProxy();
};

//
// Class XmlHttpProxy
//

function XmlHttpProxy()
{
	Proxy.apply(this, []);
	
	this.queue = [];
}

XmlHttpProxy.prototype = new Proxy();

// Signature:
// public void query(String url, Table parameters, Function callback);
//
// Example:
// public void query("/users", {username = "Foo"}, function() {});
XmlHttpProxy.prototype.query = function(_url, _params, _callback)
{
}

XmlHttpProxy.prototype.load = function(_url, _callback)
{
	this._post({url:_url, callback:_callback, method:"GET"});
}

XmlHttpProxy.prototype._post = function(request)
{
	var xmlHttpRequest = this._createXmlHttpRequest();
	var thisRef = this;
		
	xmlHttpRequest.onreadystatechange = function()
	{
		thisRef._processStateChanged(this);
	};
	
	request.xmlHttpRequest = xmlHttpRequest;
	this.queue.push(request);
	
	if(this.queue.length == 1)
	{
		this._openAndSend(request);
	}
}

XmlHttpProxy.prototype._processStateChanged = function()
{
	var request = this.queue[0];
	var xmlHttpRequest = request.xmlHttpRequest;
	
	switch(xmlHttpRequest.readyState)
	{
		case 4:
		{
			
			this.queue.splice(0, 1);
			if(request.status = 200)
			{
				request.callback(true, xmlHttpRequest.responseText); 
			} else
			{
				request.callback(false);
			}
			
			try
			{
				xmlHttpRequest.onreadystatechanged = null;
			} catch (e) {}
			
			try
			{
				xmlHttpRequest.abort();
			} catch (e) {}

			if(this.queue.length > 0)
			{
				var thisRef = this;
				request = this.queue[0];	
				window.setTimeout(function() {
					thisRef._openAndSend(request);
				}, 0);
			}
			
			break;
		}
	}
}

XmlHttpProxy.prototype._openAndSend = function(request)
{
	if(!request)
	{
		throw new Error("Request cannot be null");
	} else if(!request.xmlHttpRequest)
	{
		throw new Error("No XMLHTTP request provided");
	} else
	{
		window.setTimeout(function() {
			with(request.xmlHttpRequest)
			{
				open(request.method, request.url, true);
				send("");
			}
		}, 100);
	}
}

XmlHttpProxy.prototype._createXmlHttpRequest = function()
{
	if(window.XMLHttpRequest && !(window.ActiveXObject))
	{
		return new XMLHttpRequest();
	} else
	{
		try
		{
			return new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e)
		{
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
}

XmlHttpProxy.prototype.toString = function()
{
	return "XmlHttpProxy";
}
