/*
 * liteAJaX
 * version 0.1.1
 * 
 * by Davide 'Folletto Malefico' Casali
 * - www.digitalhymn.com
 * thanks to Bru
 * - www.codewitch.org
 *
 * Copyright (C) 2005
 * Feel free to distribute under GPL.
 *
 */

/*
 * Should work on: IE5.5+, Firefox, Opera 7.6+
 *
 * Usage Example:
 *  var la = new liteAJaX("ajax.php"); *  la.fxWork = function (oXML) { alert(oXML.responseText); }; *  la.call("fxWork", "var1=some&var2=thing");
 *
 * The server will receive on "ajax.php", in the same URL path position, with a POST request
 * with the following string: fx=fxWork&var1=some&var2=thing
 *
 * Additional parameters:
 *  - liteAJaX.method = [GET|POST]
 *    sets the open method for the XMLHTTPRequest.
 *
 */

/****************************************************************************************************
 * Constructor for the class.
 * The optional parameter URI can be passed (it's the file where this class will call eventually).
 * In no URI is passed, than the same file of the page will be assumed.
 * 
 * @param	URI location
 */
function liteAJaX(uri)
{
	// *** Self
	// Since I've been using prototypal declaration to optimize memory consumption this
	// declaration isn't needed but I place this here in order to remember two important
	// facts: (1) javascript supports closures && (2) 'this' is bugged in the closures process.
	//  (1) This means that every function declared inside another function can use
	//      all the variables of the function that includes it.
	//  (2) 'this' isn't correctly exported in this process, so if needed we must declare 'self'
	//      for the same purpose.
	var self = this;
	
	// *** XMLHTTP
	// Multiple declarations to be widely accessible on various browsers.
	try { this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
	catch (e) { try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
	catch (e) { try { this.xmlhttp = new XMLHttpRequest(); }
	catch (e) { this.xmlhttp = false; }}}
	
	// *** Callback
	this.callback = uri;
	if (!this.callback) this.callback = ".";
	
	// *** Request Method
	this.method = "POST";
	
	// *** Response text
	// Watch out: the request is ASYNK, this means that this var will be set a while after.
	this.responseText = false;
}

/****************************************************************************************************
 * Simple function to make a direct call to a specific page using XMLHTTPRequest and to take 
 * back a single value (the plain page output). So, no 'real' XML involved.
 * 
 * @param	function name (will be a fx=name parameter)
 * @param	parameters to be passed (urlencoded)
 */
liteAJaX.prototype.call = function(sFunction, sVars)
{
	out = false;
	
	// *** Define default helper function
	if (!sFunction) sFunction = "callhelper";
	if (!this[sFunction]) this[sFunction] = this.callhelper;
	
	// *** Make Call
	try
	{
		out = this.rawCall(this.callback, "fx=" + sFunction + "&" + sVars, this.method, this[sFunction]);
	}
	catch (e) { out = false; }
	
	return out;
}

/****************************************************************************************************
 * This is the default helper function for the call() function. If no helper function matching
 * the first parameter of the call() is found within this class, then this function will be used.
 * 
 * @param	XML response object
 */
liteAJaX.prototype.callhelper = function(oXML)
{
	alert("Default Callhelper:\n" + oXML.responseText);
}

/****************************************************************************************************
 * Calls a specific URI using the XMLHTTPRequest object with the specified paramteres.
 *
 * Based upon XHConn (http://xkr.us/code/javascript/XHConn/) - brad@xkr.us - 2005-01-24
 * Licenced under CC-ShareAlike license (http://creativecommons.org/licenses/by-sa/2.0/).
 * 
 * @param	URI file locator to call
 * @param	parameters to be passed
 * @param	connection method [GET|POST]
 * @param	ready state helper function callback
 */
liteAJaX.prototype.rawCall = function(sURI, sVars, sMethod, fxReady)
{
	var out = false;
	
	if (this.xmlhttp)
	{
		var self = this; // js closure fix for 'this' misbehave
		sMethod = sMethod.toUpperCase();
		
		try
		{
			// ****** Method switch [GET|POST]
			if (sMethod == "GET")
			{
				this.xmlhttp.open(sMethod, sURI + "?" + sVars, true);
				sVars = "";
			}
			else
			{
				this.xmlhttp.open(sMethod, sURI, true);
				this.xmlhttp.setRequestHeader("Method", "POST " + sURI + " HTTP/1.1");
				this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			}
			
			// ****** Defines the onreadystatechange function
			this.xmlhttp.onreadystatechange = function()
			{
				switch (self.xmlhttp.readyState)
				{
					case 1: // *** Loading...
						break;					case 2: // *** Parsing...
						break;					case 3: // *** Available...
						break;					case 4: // *** Ready
						self.responseText = self.xmlhttp.responseText;
						fxReady(self.xmlhttp);
						break;
				}
			};
			
			// ****** Send Request
			this.xmlhttp.send(sVars);
			
			out = true;
		}
		catch(z) { out = false; }
	}
	
	return out;
}