// Ajax constructor
function ajax (url, options)
{
	this.initialize(url, options);
}

// Ajax prototype
ajax.prototype =
{
	initialize: function( url , options )
	{
		this.transport = this.getTransport();
		this.responseType = options.responseType || 'text';
		this.updateEl = options.updateEl || null;
		this.postBody = options.postBody || '';
		this.method = options.method || 'post';
		this.onLoading = options.onLoading || null;
		this.onLoaded = options.onLoaded || null;
		this.onInteractive = options.onInteractive || null;
		this.onComplete = options.onComplete || null;
		this.onError = options.onError || null;
		this.request( url );
		this.error = 0;
	},

	// Bind local method
	bind: function( methodName, params)
	{
		var obj = this;
		return function() { obj[methodName](params) }
	},

	// Request processing
	request: function( url )
	{
		this.transport.open( this.method , url , true );
		this.transport.onreadystatechange = this.bind( 'onStateChange' );
		if( this.method == 'post' )
		{
			this.transport.setRequestHeader( 'Content-type' , 'application/x-www-form-urlencoded' );
			if( this.transport.overrideMimeType) this.transport.setRequestHeader( 'Connection' , 'close' );
		}
		this.transport.send(this.postBody);
	},

	// Wrapper for proccessing of request
	onStateChange: function()
	{
		switch( this.transport.readyState )
		{
			// Unitialized: open not called yet
			case 0:
				if( this.onUnitialized )
					this.onUnitialized();
				break;
			// On loading: send not called yet
			case 1:
				if( this.onLoading )
					this.onLoading();
				break;
			// On loaded: request sent, headers and status available
			case 2:
				if( this.onLoaded )
					this.onLoaded();
				break;
			// On Interactive: response is comming
			case 3:
				if( this.onInteractive )
					this.onInteractive();
				break;
			// Request Completed
			case 4:
				// Just 200 is ok
				if( this.transport.status == 200 )
				{
					// Return Text
					if(this.responseType == 'text')
					{
						if( this.updateEl )
						{
							el = document.getElementById( this.updateEl );
							el.innerHTML = this.transport.responseText;
						}
						else if ( this.onComplete )
						{
							this.onComplete( this.transport.responseText );
						}
					}
					// Return XML
					else
					{
						if ( this.onComplete )
							this.onComplete( this.transport.responseXML );
					}
				}
				else
				{
					if (this.onError )
						this.onError( this.transport.status );
				}
		}
	},

	// Choose XHR by client
	getTransport: function()
	{
		if (window.ActiveXObject)
			return new ActiveXObject('Microsoft.XMLHTTP');
		else if (window.XMLHttpRequest)
			return new XMLHttpRequest();
		else
			return false;
	}
};