/*
----------------------------------------------------------
Version:		0.1
Author:			RHH
Creation Date:	22/06/2005
----------------------------------------------------------
Description:
Functions to implement Asynchronous communication in JavaScript and XML.
*/

var iAJAX_GENERIC_TEST = -999;
var iSERVER_TIMEOUT = 5000;					// Wait 5 seconds
var iAJAX_COUNT = 0;
var iAJAX_PROCESS_ID = null;

 
function Ajax(_fnCallback)
{
	this.xmlhttp=null;

	this.submitAJAX = AJAX_submitAJAX;
	this.submitAdhocSQL = AJAX_submitAdhocSQL;
	this.getResponseText = AJAX_getResponseText;
	this.submitURL = AJAX_submitURL;
	this.submitSynchronousURL = AJAX_submitSynchronousURL;
	this.setCallBack = AJAX_setCallBack;
	this.setCannotConnectCallback = does_nothing;
	this.setTimedOutCallback = does_nothing;
	this.abort = AJAX_abort;
	
	this.fnCallback = _fnCallback;
}

function does_nothing()
{
		return;
}


function AJAX_setCallBack(_fnCallback)
{
	this.fnCallback = _fnCallback;
}


function AJAX_abort()
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RHH
	Creation Date:		15/06/2006
	----------------------------------------------------------
	Description:
	Cancels the current ajax request
	----------------------------------------------------------
*/
	// Cancel the current operation
	if(this.xmlhttp != null)
		this.xmlhttp.abort();
}




function AJAX_submitSynchronousURL(myUrl,aFields, bArrayCanContainArrays) 
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RMA
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	The submitSynchronousURL function sends an array to a page URL.
	The server processes the page and returns the content of that page SYNCHRONOUSLY.
	----------------------------------------------------------
	-- baFieldsContainsArrays - If the array of data contains arrays, then set this to true to cause recursive serialization of those arrays.
*/
	var bAsynchronous = false;

	if (bArrayCanContainArrays == undefined)
		bArrayCanContainArrays = false;


	var myText = "aFields="+encodeURIComponent(AJAX_js_array_to_php_array(aFields, bArrayCanContainArrays));
		
	// Check for an instances of the xmlhttpRequest object
	if(window.XMLHttpRequest) 
	{
		// Create a new xmlhttpRequest
		this.xmlhttp = new XMLHttpRequest();
	}
	else if(window.ActiveXObject)
	{
		// Create a Microsoft.XMLHTTP
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else 
	{
		// AJAX not supported!!
		return false;
	}
	//this.xmlhttp.fnCallback = this.fnCallback;
	//this.xmlhttp.fn12029Callback = this.fn12029Callback;
	//this.xmlhttp.fn12002Callback = this.fn12002Callback;
	
	// Assigns destination URL, method to POST
	this.xmlhttp.open("POST", myUrl, bAsynchronous);
		
	// Sending it as encoded formdata
	this.xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
	
	// We need to specify the length of the contents
	this.xmlhttp.setRequestHeader("Content-length",myText.length); 
		
	// Connection is to be closed after transfer
	this.xmlhttp.setRequestHeader("Connection","close"); 
	
	// Transmits the request, with the postable string
	this.xmlhttp.send(myText); 
	
	return true;
}

function AJAX_submitURL(myUrl,aFields, bArrayCanContainArrays, bAsynchronous) 
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RHH
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	The submitURL function sends an array to a page URL.
	The server then processes the page and returns the content of that page.
	The page should be designed to return a well-formed XML packet.
	----------------------------------------------------------
	-- baFieldsContainsArrays - If the array of data contains arrays, then set this to true
								to cause recursive serialization of those arrays.
*/

	if (bArrayCanContainArrays == undefined)
		bArrayCanContainArrays = false;
	
	if (bAsynchronous == undefined)
		bAsynchronous = true;
	
	var myText = "aFields="+encodeURIComponent(AJAX_js_array_to_php_array(aFields, bArrayCanContainArrays));
	
	// Check for an instances of the xmlhttpRequest object
	if(window.ActiveXObject)
	{
		// Create a Microsoft.XMLHTTP
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else if(window.XMLHttpRequest) 
	{
		// Create a new XMLHttpRequest
		this.xmlhttp = new XMLHttpRequest();
	}
	else 
	{
		// AJAX not supported!!
		//alert('AJAX not supported!!');
		return false;
	}
	//this.xmlhttp.fnCallback = this.fnCallback;
	//this.xmlhttp.fn12029Callback = this.fn12029Callback;
	//this.xmlhttp.fn12002Callback = this.fn12002Callback;
	
	// Assigns destination URL, method to POST
	this.xmlhttp.open("POST", myUrl, bAsynchronous);
		
	// Sending it as encoded formdata
	this.xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
	
	// We need to specify the length of the contents
	this.xmlhttp.setRequestHeader("Content-length",myText.length); 
		
	// Connection is to be closed after transfer
	this.xmlhttp.setRequestHeader("Connection","close");
	
	// Set the event handler for an event that fires at every state change
	if (this.fnCallback==null)
		this.xmlhttp.onreadystatechange=onReady;
	else
		this.xmlhttp.onreadystatechange=this.fnCallback;		
	
	// Transmits the request, with the postable string
	this.xmlhttp.send(myText); 
	
	return true;
}


function AJAX_submitAJAX(myUrl,aFields, lStatementID) 
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RHH
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	The submitAJAX function sends an array and a statement ID to a Url.
	The server then processes this request (runs the statement) and returns an
	XML packet containing the result.
*/

	var myText = "aFields="+encodeURIComponent(AJAX_js_array_to_php_array(aFields)) + "&lStatementID=" + encodeURIComponent(lStatementID);
				
	// Check for an instances of the XMLHttpRequest object
	if(window.XMLHttpRequest) 
	{
		// Create a new XMLHttpRequest
		this.xmlhttp = new XMLHttpRequest();
	}
	else if(window.ActiveXObject)
	{
		// Create a Microsoft.XMLHTTP
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else 
	{
		// AJAX not supported!!
		return false;
	}
	//this.xmlhttp.fnCallback = this.fnCallback;
	//this.xmlhttp.fn12029Callback = this.fn12029Callback;
	//this.xmlhttp.fn12002Callback = this.fn12002Callback;
	
	// Assigns destination URL, method to POST
	this.xmlhttp.open("POST", myUrl, true);
		
	// Sending it as encoded formdata
	this.xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
	
	// We need to specify the length of the contents
	this.xmlhttp.setRequestHeader("Content-length",myText.length); 
		
	// Connection is to be closed after transfer
	this.xmlhttp.setRequestHeader("Connection","close"); 
	
	// Set the event handler for an event that fires at every state change
	if (this.fnCallback==null)
		this.xmlhttp.onreadystatechange=onReady;
	else
		this.xmlhttp.onreadystatechange=this.fnCallback;
		
	// Transmits the request, with the postable string
	this.xmlhttp.send(myText); 
	
	return true;
}

function AJAX_submitAdhocSQL(myUrl,aFields, sSQLStatement) 
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RHH
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	The submitAJAX function sends an array and a statement ID to a Url.
	The server then processes this request (runs the statement) and returns an
	XML packet containing the result.
*/

	var myText = "aFields="+encodeURIComponent(AJAX_js_array_to_php_array(aFields)) + "&lStatementID=-1&sSQLStatement=" + encodeURIComponent(sSQLStatement);
		
	// Check for an instances of the XMLHttpRequest object
	if(window.XMLHttpRequest) 
	{
		// Create a new XMLHttpRequest
		this.xmlhttp = new XMLHttpRequest();
	}
	else if(window.ActiveXObject)
	{
		// Create a Microsoft.XMLHTTP
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else 
	{
		// AJAX not supported!!
		return false;
	}
	//this.xmlhttp.fnCallback = this.fnCallback;
	//this.xmlhttp.fn12029Callback = this.fn12029Callback;
	//this.xmlhttp.fn12002Callback = this.fn12002Callback;
	
	// Assigns destination URL, method to POST
	this.xmlhttp.open("POST", myUrl, true);
		
	// Sending it as encoded formdata
	this.xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
	
	// We need to specify the length of the contents
	this.xmlhttp.setRequestHeader("Content-length",myText.length); 
		
	// Connection is to be closed after transfer
	this.xmlhttp.setRequestHeader("Connection","close"); 
	
	// Set the event handler for an event that fires at every state change
	if (this.fnCallback==null)
		this.xmlhttp.onreadystatechange=onReady;
	else
		this.xmlhttp.onreadystatechange=this.fnCallback;
	
	// Transmits the request, with the postable string
	this.xmlhttp.send(myText); 
	
	return true;
}

function AJAX_getResponseText()
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RHH
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	Captures the responseText from the asyncronous AJAX connection.
	This is returned to the calling interface
*/

	if (this.xmlhttp.readyState!=4)
	{
		//this shouldn't have been called at any state other than 4. Something wen't wrong.
		return;
	}
	
	return (this.xmlhttp.responseText);
}


	
function AJAX_js_array_to_php_array (a, bArrayCanContainArrays)
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RHH (Internet Trawl)
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	This converts a javascript array to a string in PHP serialized format.
	This is useful for passing arrays to PHP. On the PHP side you can 
	unserialize this string from a cookie or request variable. For example,
	assuming you used javascript to set a cookie called "php_array"
	to the value of a javascript array then you can restore the cookie 
	from PHP like this:
		<?php
			session_start();
			$my_array = unserialize(urldecode(stripslashes($_COOKIE['php_array'])));
			print_r ($my_array);
		?>
	This automatically converts both keys and values to strings.
	The return string is not URL encodeURIComponentd, so you must call the
	Javascript "encodeURIComponent()" function before you pass this string to PHP.	
*/

	if (bArrayCanContainArrays == null)
		bArrayCanContainArrays = false; // default to false since RHH keeps 
										//  using arrays where he doesn't intend to.
										
	if (bArrayCanContainArrays)
		//Use new recursive form
		return AJAX_js_array_to_php_array_recursive(a);

	var a_php = "";
    var total = 0;
		
    for (var key in a)
    {
        ++ total;
        a_php = a_php + "s:" +
                String(key).length + ":\"" + String(key) + "\";s:" +
                String(a[key]).length + ":\"" + String(a[key]) + "\";";
    }
    a_php = "a:" + total + ":{" + a_php + "}";
	//alert(a_php);
    return a_php;
}
	
function AJAX_js_array_to_php_array_recursive(a)
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RMA + above
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Added serialization for arrays within arrays
		-- This can serialize arrays declared as "var myvariable = Array();"
		-- This can serialize arrays declared as "var myvariable = ['value1',value2,...];"
		-- This CANNOT serialize arrays declared as "var myvariable = {};" 
			(except for the outer array)
	----------------------------------------------------------
	Description:
	This converts a javascript array to a string in PHP serialized format.
	This is useful for passing arrays to PHP. On the PHP side you can 
	unserialize this string from a cookie or request variable. For example,
	assuming you used javascript to set a cookie called "php_array"
	to the value of a javascript array then you can restore the cookie 
	from PHP like this:
		<?php
			session_start();
			$my_array = unserialize(urldecode(stripslashes($_COOKIE['php_array'])));
			print_r ($my_array);
		?>
	This automatically converts both keys and values to strings.
	The return string is not URL encodeURIComponentd, so you must call the
	Javascript "encodeURIComponent()" function before you pass this string to PHP.	
*/
	var a_php = "";
    var total = 0;
		
    for (var key in a)
    {
        ++ total;
		/*???RMA???
		if (String(a[key])=='[object Object]')
			alert(AJAX_isArray(a[key]));
		*/
		if (AJAX_isArray(a[key]))
		{ 
			//a serialized array:
			a_php = a_php 
				+ "s:" +String(key).length + ":\"" + String(key) + "\";"
				+ AJAX_js_array_to_php_array_recursive(a[key]);
		}
		else
		{
			//assume everything else is string
			a_php = a_php 
				+ "s:" +String(key).length + ":\"" + String(key) + "\";"
				+ "s:" +String(a[key]).length +":\""+String(a[key])+ "\";" ;
		}
       
    }
    a_php = "a:" + total + ":{" + a_php + "}";
    return a_php;
}


/*
	----------------------------------------------------------
	Version:		0.1
	Author:			RMA (Internet Trawl)
	Creation Date:	22/06/2005
	----------------------------------------------------------
	Description:
	Return a boolean value telling whether the first argument is an Array object. 
	----------------------------------------------------------
		-- This can detect arrays declared as "var myvariable = Array();"
		-- This can detect arrays declared as "var myvariable = ['value1',value2,...];"
		-- This CANNOT detect arrays declared as "var myvariable = {};"
*/
function AJAX_isArray() 
{
	if (typeof arguments[0] == 'object') 
	{  
		var criterion = arguments[0].constructor.toString().match(/array/i); 
 		return (criterion != null);  
	}
	
	return false;
}


function phpSerialize(array)
{
/*
	----------------------------------------------------------
	Version:		0.1
	Author:			AJM (Internet Trawl)
	Creation Date:	06/01/2009
	----------------------------------------------------------
	Description:
	Internet Explorer is garbage, so in order to pass an array through ajax it must be serialized.
	----------------------------------------------------------
		-- Takes an object and returns a string of it's data serialized to work with PHP's json_decode()
*/
	var $ = ""; // serialized string
	
	var serializeString = function( str )
	{
		return ( str.constructor == String ) 
			? "\"" + str.replace( /"/ , "\\\"" ) + "\"" 
			: str;
	}
	
	var serializeArray = function( arr )
	{
		var strs = "";
					
		for( var i = 0; i < arr.length; i++ )
		{
			strs += serializeString( arr[ i ] ) + ",";
		}
				
		return "[" + rtrimComma( strs ) + "]";
	}
	
	var rtrimComma = function( str )
	{
		return str.substr( 0, str.length - 1 );
	}
	
	// iterate object
	for( var key in array )
	{    
		if (array[ key ].constructor != null && array[ key ].constructor == Function ) 
			continue; // we can't serialize functions
		
		$ += "\"" + key + "\":";
		
		switch( array[ key ].constructor )
		{
			case String:
			case Number:
				$ += serializeString( array[ key ] );
			break;
			case Array:
				$ += serializeArray( array[ key ] );
			break;
			case Object:
				$ += phpSerialize(array[ key ]); // recursion
			break;
		}
		
		$ += ",";
	}
		
	return "{" + rtrimComma( $ ) + "}";
}
