/**
 * A function to easily allow the addition of function calls after a page 
 * has loaded.
 * Usage: addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
 * Usage: addLoadEvent(function() { [Some code] });
 */
function addLoadEvent(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function')
	{
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) { oldonload(); }
			func();
		}
	}
}


/**
 * The AJAXHandler class definition.
 *
 * Interface:
 *
 * ^ new AJAXHandler(divTarget, showThrobber)
 *   - Creates a new AJAXHandler object. This object can be used to handle a 
 *     single AJAX interaction. divTarget should be a DIV element on the page 
 *     and showThrobber should be true or false.
 *
 * ^ getNewXMLHTTPObject()
 *   - Creates a new AJAX connection object, and returns it, or returns null 
 *     if an object cannot be created.
 *
 * ^ ajaxResponseReceived()
 *   - Called when the AJAX response is received from the server. In this 
 *     base class, the response text is simply written to the target DIV. 
 *     This method should be overwritten by subclasses.
 *
 * ^ sendRequest(resourceName)
 *   - Send an AJAX request. resourceName should be the page name to request, 
 *     for example 'somePage.php'.
 *
 * ^ displayThrobber()
 *   - Display the throbber if the handler is configured to do so.
 *
 * ' ajaxConn
 *   - The AJAX connection object for this handler. This will be null if AJAX 
 *     is not available on the current system.
 *
 * ' divTarget
 *   - The DIV target for this handler.
 *
 * ' showThrobber
 *   - Whether or not a throbber should be shown by this handler.
 *
 */
function AJAXHandler(divTarget, showThrobber)
{
	// Store the DIV target for this handler
    this.divTarget = divTarget;
    // Store whether or not a throbber should be shown by this handler
    this.showThrobber = showThrobber;
	
	// Define the getNewXMLHTTPObject() method
	this.getNewXMLHTTPObject = function()
	{
		var xmlHttp = null;
		try
		{
			// Firefox, Opera 8.0+, Safari
			xmlHttp = new XMLHttpRequest();
		} catch (e) {
			// Internet Explorer
			try
			{
				xmlHttp = new ActiveXObject('Msxml2.XMLHTTP');
			} catch (e2) {
				try
				{
					xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
				} catch (e3) {
					xmlHttp = null;
				}
			}
		}
		return xmlHttp;
	};
	// Define the internal AJAX connection state handler function
	this.ajaxConnStateChanged = function()
	{
		if (this.ajaxConn.readyState == 4 || this.ajaxConn.readyState == 'complete')
		{
			this.extractScripts();
			this.ajaxResponseReceived();
		}
	};
	// Define an internal function to evaluate any JavaScript in the AJAX response
	this.extractScripts = function()
	{
		var search = this.ajaxConn.responseText;
		var script;
		while (script = search.match(/(<script[^>]+javascript[^>]+>\s*(<!--)?)/i))
		{
			search = search.substr(search.indexOf(RegExp.$1) + RegExp.$1.length);
			if (!(endscript = search.match(/((-->)?\s*<\/script>)/))) break;
			
			block = search.substr(0, search.indexOf(RegExp.$1));
			search = search.substring(block.length + RegExp.$1.length);
			
			var newScript = document.createElement('script');
			newScript.text = block;
			document.getElementsByTagName("head").item(0).appendChild(newScript);
		}
	};
	// Define the ajaxResponseReceived() method
	this.ajaxResponseReceived = function()
	{
		// Unlock the div height
		this.divTarget.style.height = '';
		// Update the page with the response text
		this.divTarget.innerHTML = this.ajaxConn.responseText;
	};
	// Define the sendRequest(resourceName) method
	this.sendRequest = function(resourceName)
	{
/* // LOOKING FOR RACE CONDITION CODE - START
		if (this.ajaxConn.ajaxHandler === null || this.ajaxConn.ajaxHandler === undefined)
		{
			var reason1 = ' (';
			if (this.ajaxConn.ajaxHandler === null) { reason1 += 'null'; }
			if (this.ajaxConn.ajaxHandler === undefined) { reason1 += 'undefined'; }
			reason1 += ')';
			alert('SEND REQUEST - Failed to assign AJAX Handler' + reason1);
		}
// LOOKING FOR RACE CONDITION CODE - END */		
		this.displayThrobber();
		var url = resourceName + '?sid=' + Math.random();
		this.ajaxConn.open('GET', url, true);
		this.ajaxConn.send(null);
	};
	// Define the displayThrobber() method
	this.displayThrobber = function()
	{
		if (this.showThrobber)
		{
			this.divTarget.style.height = this.divTarget.offsetHeight;
			this.divTarget.innerHTML = '<img src="images/ajax-loading.gif" width="32" height="32" />';
		}
	};
    
	// Define the AJAX connection object for this handler
	this.ajaxConn = this.getNewXMLHTTPObject();
	// If the AJAX connection object was successfully created
	if (this.ajaxConn !== null)
	{
		// Assign the AJAX connection object this handler, and ensure it calls 
		// the handler when a response is received
		this.ajaxConn.ajaxHandler = this;
/* // LOOKING FOR RACE CONDITION CODE - START
		if (this.ajaxConn.ajaxHandler === null || this.ajaxConn.ajaxHandler === undefined)
		{
			var reason1 = ' (';
			if (this.ajaxConn.ajaxHandler === null) { reason1 += 'null'; }
			if (this.ajaxConn.ajaxHandler === undefined) { reason1 += 'undefined'; }
			reason1 += ')';
			alert('Failed to assign AJAX Handler' + reason1);
		}
// LOOKING FOR RACE CONDITION CODE - END */
		this.ajaxConn.onreadystatechange = function()
		{
			if (this.ajaxHandler !== null && this.ajaxHandler !== undefined)
			{
				this.ajaxHandler.ajaxConnStateChanged();
			} else {
/* // LOOKING FOR RACE CONDITION CODE - START
				var reason2 = ' (';
				if (this.ajaxHandler === null) { reason2 += 'null'; }
				if (this.ajaxHandler === undefined) { reason2 += 'undefined'; }
				reason2 += ')';
				alert('No AJAX Handler assigned' + reason2);
// LOOKING FOR RACE CONDITION CODE - END */
			}
		};
	} else {
/* // LOOKING FOR RACE CONDITION CODE - START
		var reason3 = ' (';
		if (this.ajaxConn === null) { reason3 += 'null'; }
		if (this.ajaxConn === undefined) { reason3 += 'undefined'; }
		reason3 += ')';
		alert('Failed to assign AJAX Connection' + reason3);
// LOOKING FOR RACE CONDITION CODE - END */
	}
}


/**
 * The NumberListBoxAJAXHandler class definition.
 *
 * Interface:
 *
 * ^ new NumberListBoxAJAXHandler(divTarget, showThrobber, search, pageSize, pageNumber)
 *   - Creates a new NumberListBoxAJAXHandler object. This object can be used 
 *     to handle a single AJAX interaction, requesting a number list box. 
 *     divTarget should be a DIV element on the page that will contain the 
 *     number list box, and showThrobber should be true or false. search 
 *     should be the number search term. pageSize and pageNumber are 
 *     pagination parameters.
 *
 * ^ sendRequest()
 *   - Send an AJAX request for a view forum box.
 *
 * ' search
 *   - The search term.
 *
 * ' pageSize
 *   - The number of results to show per page.
 *
 * ' pageNumber
 *   - The page number of the result set to show.
 *
 */
function NumberListBoxAJAXHandler(divTarget, showThrobber, search, pageSize, pageNumber)
{
	// Call the constructor for the AJAXHandler class
	AJAXHandler.call(this, divTarget, showThrobber);
	// Store the search term and pagination parameters
	this.search = search;
	this.pageSize = pageSize;
	this.pageNumber = pageNumber;
	
	// Define the sendRequest() method
	this.sendRequest = function()
	{
		this.displayThrobber();
		var url = 'number-list-box.php?search=' + this.search + '&sid=' + 
			Math.random();
		if (this.pageSize != null)
		{
			url += ('&pagesize=' + this.pageSize);
		}
		if (this.pageNumber != null)
		{
			url += ('&pagenumber=' + this.pageNumber);
		}
		this.ajaxConn.open('GET', url, true);
		this.ajaxConn.send(null);
	}
}
// Make AJAXHandler the superclass of NumberListBoxAJAXHandler
NumberListBoxAJAXHandler.prototype = new AJAXHandler();


