/**
*	Ajaxer is an easy-to-use AJAX implementation class (function).
*	Ajaxer allows you to quickly develop cross-platform applications.
*
*	@author					Luis Guillermo Salazar Baez <luis@freaky-media.com>
*	@copyright				DPT Sports Group 2006
*	@category				JavaScript
*	@version				1.1
*/
function Ajaxer()
{

	/**
	*	The function object to be called when Loading state
	*
	*	@var					function objFunctionLoading
	*	@access					public
	*/
	var objFunctionLoading = null;

	/**
	*	The funtion object to be called when loaded state
	*
	*	@var					function objFunctionLoaded
	*	@access					public
	*/
	var objFunctionLoaded = null;

	/**
	*	The function object to be called when interactive state
	*
	*	@var					function objFunctionInteractive
	*	@access					public
	*/
	var objFunctionInteractive = null;

	/**
	*	The function object to be called when complete state
	*
	*	@var					function objFunctionComplete
	*	@access					public
	*/
	var objFunctionComplete = null;

	/**
	*	The XMLHTTPRequest object to be used as Transport.
	*
	*	@var					XMLHTTP this.objTransport
	*	@access					public
	*/
	var objTransport = null;

	/**
	*	The list of this.parameters to be send on the request.
	*
	*	@var					Array this.parameters
	*	@access					public
	*/
	var parameters = new Array();

	/**
	*	The URL for the request.
	*
	*	@var					String this.requestURL
	*	@access					public
	*/
	var requestURL = "";

	/**
	*	The HTTP Method to be used for sending the data.
	*
	*	@var					String this.requestMethod
	*	@access					public
	*/
	var requestMethod = "GET";

	/**
	*	A flag indicating if the browser has to wait or not
	*	for the request to end.
	*
	*	@var					boolean this.asynchronous
	*	@access					public
	*/
	var asynchronous = true;




	/**
	*	Sets the function to be used when loading state
	*
	*	@access					public
	*/
	this.setLoading = function( objFunction )
	{
		if ( objFunction!=null && ( typeof objFunction == "function" ) )
			objFunctionLoading = objFunction;
	} // setLoading




	/**
	*	Sets the function to be used when loaded state
	*
	*	@access					public
	*/
	this.setLoaded = function( objFunction )
	{
		if ( objFunction!=null && ( typeof objFunction == "function" ) )
			objFunctionLoaded = objFunction;
	} // setLoaded




	/**
	*	Sets the function to be used when interactive state
	*
	*	@access					public
	*/
	this.setInteractive = function( objFunction )
	{
		if ( objFunction!=null && ( typeof objFunction == "function" ) )
			objFunctionInteractive = objFunction;
	} // setInteractive




	/**
	*	Sets the function to be used when complete state
	*
	*	@access					public
	*/
	this.setComplete = function( objFunction )
	{
		if ( objFunction!=null && ( typeof objFunction == "function" ) )
			objFunctionComplete = objFunction;
	} // setComplete




	/**
	*	Sets a parameter to be send on the next request.
	*
	*	@param					String paramName The parameter name
	*	@param					String paramValue The parameter value
	*	@access					public
	*/
	this.setParameter = function(paramName, paramValue)
	{
		if ( parameters==null )
			parameters = new Array();
		parameters.push( paramName + "=" + escape(paramValue) );
	} // setParameter




  	/**
	*	Sets the request application URL.
	*
	*	@param					String urlStr
	*	@access					public
	*/
	this.setURL = function(urlStr)
	{
		if ( urlStr!=null && urlStr.length>0 )
			requestURL = urlStr;
	} // setURL




  	/**
	*	Sets the HTTP method ( POST/GET)
	*
	*	@param					String methodName
	*	@access					public
	*/
	this.setMethod = function(methodName)
	{
		methodName = methodName.toUpperCase();

		if ( methodName=="POST" )
			requestMethod = "POST";
		else
			requestMethod = "GET";
	} // setMethod




  	/**
	*	Sets if the Ajaxer has to wait for a call back function.
	*
	*	@param					boolean sync
	*	@access					public
	*/
	this.setAsynchronous = function(sync)
	{
		asynchronous = sync;
	} // setAsynchronous




  	/**
	*	Returns the response text for the last execution.
	*
	*	@return					String
	*	@access					public
	*/
	this.getResponseText = function()
	{
		if ( objTransport!=null )
		{
			if ( objTransport.readyState==4 || objTransport.readyState=="complete" )
				return objTransport.responseText;
			else
				return '';
		}
		else
		{
			return '';
		}
	} // getResponseText




  	/**
	*	Returns the response XML for the last execution.
	*
	*	@return					XMLDocument
	*	@access					public
	*/
	this.getResponseXML = function()
	{
		if ( objTransport!=null )
		{
			if ( objTransport.readyState==4 || objTransport.readyState=="complete" )
				return objTransport.responseXML;
			else
				return null;
		}
		else
		{
			return null;
		}
	} // getResponseXML




	/**
	*	Sets the function to be used when complete state
	*
	*	@access					public
	*/
	this.getHeader = function( headerName )
	{
		if ( headerName!=null && headerName.length>0 && objTransport!=null )
			return objTransport.getResponseHeader( headerName );
		else
			return '';
	} // getHeader




	/**
	*	Sets the function to be used when complete state
	*
	*	@access					public
	*/
	this.evalReponseText = function()
	{
		var responseText = this.getResponseText();

		if ( responseText!=null && responseText.length>0 )
		{
			try
			{
				return eval(responseText);
			}
			catch(e){}
		} // if

	} // evalReponseText




	/**
	*	Handles the states for the last request
	*
	*	@access					public
	*/
	this.handleCallBack = function()
	{

		if ( objTransport!=null )
		{

			switch( objTransport.readyState )
			{

				// loading
				case 1:
					if ( objFunctionLoading!=null )
						objFunctionLoading.call();
				break;

				// loaded
				case 2:
					if ( objFunctionLoaded!=null )
						objFunctionLoaded.call();
				break;

				// interactive
				case 3:
					if ( objFunctionInteractive!=null )
						objFunctionInteractive.call();
				break;

				// complete
				case 4:

					var contentType = objTransport.getResponseHeader('Content-type').toLowerCase();
					var isJavaScript = ( contentType.indexOf("javascript")>0 );

					if ( isJavaScript==true )
					{
						try
						{
							eval( objTransport.responseText );
						}
						catch(e)
						{
							alert("Ajaxer: There was an error while evaluating JavaScript remote response.\n[ " + e.toString() + " ]");
						}
					}
					else
					{
						objFunctionComplete.call();
					}

				break;

			} // switch

		} // if
	} // handleCallBack




  	/**
	*	Prepares the transport object.
	*	Prepares the PROPER transport depending on user's browser.
	*
	*	@access					public
	*/
	this.prepareTransport = function()
	{
		var objRequest = null;

		// if the object has not been initialized before...
		if ( objRequest==null )
		{
			// First, lets see think user uses IE.
			if ( window.ActiveXObject )
			{

				var MSTransportVersions = new Array(
												'Msxml2.XMLHTTP.5.0',
												'Msxml2.XMLHTTP.4.0',
												'Msxml2.XMLHTTP.3.0',
												'Msxml2.XMLHTTP',
												'Microsoft.XMLHTTP'
											);
				for ( var i=0; i<MSTransportVersions.length && objRequest==null; i++ )
				{
					try
					{
						objRequest = new ActiveXObject( MSTransportVersions[i] );
						break;
					}
					catch(e){}
				} // for

			} // if

			// If not IE, then lets think it may be Firefox.
			//	Actually, this is the standard one.
			if ( objRequest==null && (window.XMLHttpRequest) )
			{
				objRequest = new XMLHttpRequest();
			}
		}

		if ( objRequest==null )
			throw new Error("Ajaxer: XMLHttpRequest Object could not be instantiated.");
		else
			objTransport = objRequest;
	} // prepareTransport




  	/**
	*	Prepare the XMLHTTPRequest headers.
	*
	*	@access					private
	*/
	this.prepareHeaders = function()
	{
		if ( objTransport!=null )
		{
			objTransport.setRequestHeader("X-Requested-With","XMLHttpRequest");
			objTransport.setRequestHeader("If-Modified-Since","Sat, 1 Jan 2000 00:00:00 GMT");

			if ( requestMethod=="POST" )
				objTransport.setRequestHeader("Content-type","application/x-www-form-urlencoded");

			if ( objTransport.overrideMimeType )
				objTransport.setRequestHeader("Connection","close");
		} // if
	} // prepareHeaders




  	/**
	*	Executes the request.
	*
	*	@access					public
	*/
	this.execute = function()
	{
		try
		{
			this.prepareTransport();

			this.setParameter("A_RId",Math.random());

			if ( requestMethod=="GET" )
				requestURL = requestURL + "?" + parameters.join("&");

			objTransport.open( requestMethod, requestURL, asynchronous );

			objTransport.onreadystatechange = this.handleCallBack;

			this.prepareHeaders();

			objTransport.send(
									( requestMethod=="POST" ? parameters.join("&") : null )
								);
			parameters = new Array();
		}
		catch(e)
		{
			alert("Ajaxer: Exception while executing request.\n[ " + e.toString() + " ]");
		}
	} // execute




} // Ajaxer
