/** Net - XMLHTTP Interface - bfults@gmail.com - 2006-02-05                 **
 ** Code licensed under Creative Commons Attribution-ShareAlike License     **
 ** http://creativecommons.org/licenses/by-sa/2.5/                          **/

Net = function()
{
	this.Request = Net._createRequestObject();
}

/** Net.post(sURL, sVars, fnCallback[, fnError]) -- make an HTTP POST request
 ** Returns true on successful request dispatch, false on error.
 ** fnCallback will be called with a single argument (the XMLHTTP object)
 ** Optional fnError: call upon erroneous HTTP status code or timeout.
 **/ 
Net.post = function(sURL, sVars, fnCallback, fnError,par,constructor)
{
	var tArg = typeof sVars;
	switch (tArg)
	{
		case "string":
		break;

		case "object":
		sVars = Net._serializeObject(sVars);
		break;

		default:
		sVars = '';
	}
	fnError = fnError || Net._fnErrorDefault;
	try {
		var N = new Net();
		N.Request.open("POST", sURL, true);
		N._setCallback(fnCallback, fnError, par,constructor);
		N.Request.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
		N.Request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		//N.Request.setRequestHeader("Content-Type", "text/plain; charset=iso-8859-1");
		//N.Request.setRequestHeader("Content-Type", "text/plain; charset=UTF-8");		N.Request.send(sVars);
	}
	catch (e) { fnError("initialization"); }
	return true;
}

// a default error function showing the structure (does nothing)
Net._fnErrorDefault = function(sType, Request)
{
	switch (sType)
	{
		case "timeout":
		// it was a timeout (Request undefined)
		break;

		case "initialization":
		// initialization error (Request undefined)
		break;

		default:
		// other error (HTTP status, etc.)
	}
}

// a helper function to serialize an object
Net._serializeObject = function(oFrom)
{
	var aTemp = [];
	for (var i in oFrom)
	{
		aTemp.push(encodeURIComponent(i) +"="+ encodeURIComponent(oFrom[i]));
	}
	return aTemp.join('&');
}

/** Net._setCallback(fnCallback, fnError,par,constructor)
 ** Attaches (and wraps) a request object with a user-defined callback.
 ** Optional fnError: call upon erroneous HTTP status code or timeout.
 **/
Net.prototype._setCallback = function(fnCallback, fnError,par,constructor)
{
	this.Request.onreadystatechange = (function (oNet)
	{
		return function()
		{
			if (oNet.Request.readyState == 4)
			{
				window.clearTimeout(oNet.timeout);

				if (oNet.Request.status === undefined
					|| oNet.Request.status === 0
					|| (oNet.Request.status >= 200 && oNet.Request.status < 300)
					|| oNet.Request.status == 304)
				{
					if(constructor)					{
						fnCallback.call(constructor,oNet.Request.responseText,par);
					}else{
						fnCallback(oNet.Request.responseText,par);					}
				}
				else
				{
					fnCallback(oNet.Request.responseText,par);					//fnError("other", oNet.Request);
				}
			}
		}
	})(this);

	this.timeout = window.setTimeout((function(oNet) {
		return function() {
			oNet.Request.onreadystatechange = function() {};
			oNet.Request = null;
			fnError("timeout"); }})(this), 10000);
}

/** Net._createRequestObject()
 ** Creates and returns an XMLHTTP element or null on failure.
 **/
Net._createRequestObject = function()
{
	var xmlhttp;
	if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); }
	else if (window.ActiveXObject) {
		try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
		catch (e) { xmlhttp = null; }}
	}
	return xmlhttp;
}
/** End Net asynchronous request library */
function xmlhttp(url,param,fnDone,par,constructor)
{	Net.post(url, param, fnDone,'',par,constructor);}
