/*
* Ajax
* @Author: Alexander Gavazov
* @Date: 2007-11-22
*/

/*
* OPTIONS
* parameters - String
* encoding - String
* asynchronous - Bool
* jsonVar - String
* onInit - Function (state 0)
* onOpen - Function (state 1)
* onSent - Function (state 2)
* onReceiving - Function (state 3)
* onComplete - Function (state 4)
* onFailure - Function XXX
*
*
* STATES
* 0 - Uninitialized -  The initial value
* 1 - Open - The open() method has been successfully called
* 2 - Sent - The UA successfully completed the request, but no data has yet been received
* 3 - Receiving - Immediately before receiving the message body (if any). All HTTP headers have been received
* 4 - Loaded - The data transfer has been completed
*/

Ajax = function(url, method, options)
{
	if(!url || !method || !options)
	{
		return false;
	}

	if(!this.createHttp())
	{
		return false;
	}

	if(typeof(options) != 'object')
	{
		return false;
	}

	// Set vars
	this.url = url;
	this.method = method.toUpperCase();
	this.options = options;

	// Set options
	this.setOptions();

	// Set parameters
	this.setParameters();

	// Request
	this.request();

	// Get data
	this.getData();
}

Ajax.prototype.createHttp = function()
{
	if(window.XMLHttpRequest)
	{
		this.xmlHttp = new XMLHttpRequest();
		if(this.xmlHttp.overrideMimeType)
		{
			this.xmlHttp.overrideMimeType('text/xml');
		}
	}
	else
	{
		try
		{
			this.xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e)
		{
			try
			{
				this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e)
			{
				this.xmlHttp = false;
			}
		}
	}

	return (this.xmlHttp) ? true : false;
}

Ajax.prototype.setOptions = function()
{
	if(!this.options.encoding)
	{
		this.options.encoding = 'UTF-8';
	}

	if(!this.options.asynchronous)
	{
		this.options.asynchronous = true;
	}

	if(!this.options.parameters)
	{
		this.options.parameters = null;
	}
}

Ajax.prototype.setParameters = function()
{
	if(this.method == 'GET' && this.options.parameters)
	{
		if(this.url.search('\\?') != -1 && this.url.substr(-1) == '?')
		{
			this.url += this.options.parameters;
		}
		else if(this.url.search('\\?') != -1)
		{
			this.url += '&' + this.options.parameters;
		}
		else
		{
			this.url += '?' + this.options.parameters;
		}
	}
}

Ajax.prototype.request = function()
{
	// Callback: onInit()
	if(this.xmlHttp.readyState == 0)
	{
		if(this.options.onInit)
		{
			this.options.onInit(this.xmlHttp.responseText, this);
		}
	}

	this.xmlHttp.open(this.method, this.url, this.options.asynchronous);

	this.xmlHttp.setRequestHeader('Accept-Charset', this.options.encoding);

	// Callback: onOpen()
	if(this.xmlHttp.readyState == 1)
	{
		if(this.options.onOpen)
		{
			this.options.onOpen(_transfer.xmlHttp.responseText, _transfer);
		}
	}

	if(this.method == 'POST')
	{
		this.xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		this.xmlHttp.setRequestHeader('Content-length', this.options.parameters);
		this.xmlHttp.setRequestHeader('Connection', 'close');
		this.xmlHttp.send(this.options.parameters);
	}
	else
	{
		this.xmlHttp.send(null);
	}
}

Ajax.prototype.getData = function()
{
	// If is finish now (cache) - Callback: onComplete()
	if(this.xmlHttp.readyState == 4)
	{
		if(this.options.jsonVar)
		{
			eval(this.options.jsonVar + '=' + this.xmlHttp.responseText);
		}
		if(this.options.onComplete)
		{
			this.options.onComplete(this.xmlHttp.responseText, this);
		}
	}

	var _transfer = this;

	this.xmlHttp.onreadystatechange = function()
	{
		// Callback: onSent()
		if(_transfer.xmlHttp.readyState == 2)
		{
			if(_transfer.options.onSent)
			{
				_transfer.options.onSent(_transfer.xmlHttp.responseText, _transfer);
			}
		}
		// Callback: onReceiving()
		else if(_transfer.xmlHttp.readyState == 3)
		{
			if(_transfer.options.onReceiving)
			{
				_transfer.options.onReceiving(_transfer.xmlHttp.responseText, _transfer);
			}
		}
		// Callback: onComplete()
		else if(_transfer.xmlHttp.readyState == 4)
		{
			if(_transfer.options.jsonVar)
			{
				eval(_transfer.options.jsonVar + '=' + _transfer.xmlHttp.responseText);
			}
			if(_transfer.options.onComplete)
			{
				_transfer.options.onComplete(_transfer.xmlHttp.responseText, _transfer);
			}
		}
	}
}
