var _ajax = false;

var pajax_baseurl = '';
function pajax_call() // pajax_call(funcname, arg0, arg1...
{
	if (!_ajax)
		_ajax = new Ajax();
		
	args = pajax_call.arguments;
	_ajax.clearParams();
	
	for (i=1; i<args.length; i++)
		_ajax.setParam('args'+(i-1)+'', args[i]);
	
	_ajax.setParam('func', args[0]);
	
	rnd = (new Date()).getTime()+'';
	_ajax.setParam('rnd', rnd);
	_ajax.doRequest(pajax_baseurl+'pajaxhandle.php', pajax_callback, 'post');
} // pajax_call

function pajax_fetch() // pajax_fetch(url, arg0, arg1...
{
	if (!_ajax)
		_ajax = new Ajax();
		
	args = pajax_fetch.arguments;
	_ajax.clearParams();
	
	for (i=1; i<args.length; i++)
		_ajax.setParam('args'+(i-1)+'', args[i]);
	
	
	rnd = (new Date()).getTime()+'';
	_ajax.setParam('rnd', rnd);
	_ajax.doRequest(pajax_baseurl+args[0], pajax_callback, 'post');

} // pajax_fetch

function pajax_callback(responseText)
{
	
	if (responseText.length < 2 || responseText.indexOf('{"') != 0)
	{
		alert('pajax :: js : trashed response received \n\n' + responseText);
		return;
	}
	eval('var result = ' + responseText);
	
	if (!result.callback)
		alert(responseText);
	
	callback = result.callback + '(';
	
	for (i=0; i<result.args.length; i++)
	{
		if (i > 0)
			callback += ', ';
		callback += 'result.args[' + i + ']';
	}
	callback += ');';
	eval(callback);
} // pajax_callback


function Ajax()
{
	// initialize the member function references 
  // for the class prototype
  if (typeof(_ajax_prototype_called) == 'undefined')
  {
     _ajax_prototype_called = true;
     Ajax.prototype.setParam = setParam;
     Ajax.prototype.clearParams = clearParams;
     Ajax.prototype.doRequest = doRequest;
     Ajax.prototype._getHttpRequest = _getHttpRequest;
     Ajax.prototype._getParams = _getParams;
     Ajax.prototype._getParamsArray = _getParamsArray;
     Ajax.prototype._urlEncode = _urlEncode;
  }

	function setParam(param, val)
	{
		paramCount = this.parameters.length;
		this.parameters[paramCount] = param;
		this.values[paramCount] = val;
	} // setParam
	
	function clearParams()
	{
		this.parameters = new Array();
		this.values = new Array();
	} // clearParams

	function doRequest(url, callback, method)
	{ 
		if (!this.httpRequest)
		{
			alert('Could not perform action: No httpRequest object.');
		}
		else
		{
			httpRequest = this.httpRequest;
			httpRequest.abort();
			httpRequest.onreadystatechange = function ()
			{
				if (httpRequest.readyState == 4)
				{
					if (httpRequest.status == 200)
					{
						//alert(httpRequest.responseText);
						callback(httpRequest.responseText);
					}
					else
					{
						alert('Could not perform action: ' + httpRequest.status);
					}
				}
			} // function

			if (method.toLowerCase() == 'get')
			{
				
				if (this.parameters.length > 0)
					url += '?' + this._getParams();
				
				httpRequest.open('GET', url, true); 
				httpRequest.send(null);
			}
			else if (method.toLowerCase() == 'post')
			{
				httpRequest.open('POST', url, true); 
				httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); 
				params = this._getParams();
				httpRequest.setRequestHeader("Content-Length", params.length);
				httpRequest.send(params);
			}
			else
			{
				alert("Unknown method: " + method);
			}
		}
	} // doRequest

	function _getHttpRequest()
	{
		var httpRequest = false;
		if (window.XMLHttpRequest)
		{ // Mozilla, Safari,... 
			httpRequest = new XMLHttpRequest(); 
		}
		else if (window.ActiveXObject)
		{ // IE 
			try
			{ 
				httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); 
	   	} 
	   	catch (e)
	   	{ 
	   		try
	   		{ 
	   			httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
	   		} 
	   		catch (e) {} 
	   	} 
		}

		return httpRequest;
	} // _getHttpRequest
	
	function _getParams()
	{
		var params = '';
		for (i=0; i<this.values.length; i++)
		{
			if (i > 0)
				params += '&';
			
			if (typeof(this.values[i]) === 'object')
			{
				// array
				params += this._getParamsArray(this.parameters[i], this.values[i], 0);
			}
			else
			{
				// string
				params += this._urlEncode(this.parameters[i]);
				params += '=';
				params += this._urlEncode(this.values[i]);
			}
		}
		//alert(params);
		return params;
	} // _getParams
	
	function _getParamsArray(parameter, values, depth)
	{
		/*
			Below is needed for recursiveness to work. Without this
			each (nested) call of this function will overwrite the variables.
			For some reason each variable declared in this function is declared
			with some behaviour of a global variable.
		*/
		if (aparams == null)
		{
			var aparams = new Array();
			var indexes = new Array();
		}
		
		aparams[depth] = '';
		indexes[depth] = 0;
		for (key in values)
		//for (indexes[depth]=0; indexes[depth]<values.length; indexes[depth]++)
		{
			if (indexes[depth] > 0)
				aparams[depth] += '&';
				
			if (typeof(values[indexes[depth]]) === 'object')
			{
				aparams[depth] += this._getParamsArray(parameter+'['+key+']', values[key], depth+1);
			}
			else
			{
				aparams[depth] += parameter+'['+key+']';
				aparams[depth] += '=';
				aparams[depth] += this._urlEncode(values[key]);
			}
			
			indexes[depth]++;
		}
		
		return aparams[depth];
	} // _getParamsArray
	
	
	function _urlEncode(str)
	{
		encodedStr = escape(str);
 		encodedStr = encodedStr.replace("+", "%2B");
  	encodedStr = encodedStr.replace("/", "%2F"); 
  	return encodedStr;
	} // _urlEncode

	this.httpRequest = _getHttpRequest();
	this.parameters = new Array();
	this.values = new Array();
	
} // class Ajax
