/*
 * Utilities for AJAX functionality.
 * When changes are made to this libary, make sure that you re-test all
 * dependent pages.
 *
 * ************* NOTE *********************
 * All pages which use this library must
 * implement their own versions of:
 *    method extractData()
 *    method handleStateChange()
 *    var xmlHttp
 * ****************************************
 */

/**
 * Instanciate the XML retriever, based on browser type.
 * This returns an object. It should be stored in a global page variable
 * There may be several XML retrievers for any given page.
 */
function createXMLHttpRequest() {
	var xmlHttpOut;
	if (window.ActiveXObject) {
		xmlHttpOut = new ActiveXObject("Microsoft.XMLHTTP");
	} else if (window.XMLHttpRequest) {
		xmlHttpOut = new XMLHttpRequest();
	}
	return xmlHttpOut;
}

/**
 * Begin the call process to retrive XML.
 * This includes setting up for when the XML is returned.
 * @param xmlHttpTemp XML Loading object, different in IE and FireFox etc.
 * @param sXmlUrl URL of the XML object.
 * @param functionToHandleStateChange Name of the method to call when the state changes.
 */
function startRequest(xmlHttpTemp, sXmlUrl, functionToHandleStateChange) {
	xmlHttpTemp.onreadystatechange = functionToHandleStateChange;
	xmlHttpTemp.open("GET", sXmlUrl, true);
	xmlHttpTemp.send(null);
}

/**
 * Begin the call process to post data and return results XML.
 * @param xmlHttpTemp XML Loading object, different in IE and FireFox etc.
 * @param sXmlUrl URL of the XML object.
 * @param functionToHandleStateChange Name of the method to call when the state changes.
 * @param sParams URI format String, eg "username=Joe%20Bloggs&age=20".
 */
function startRequestPost(xmlHttpTemp, sXmlUrl, functionToHandleStateChange, sParams) {
	xmlHttpTemp.onreadystatechange = functionToHandleStateChange;
	xmlHttpTemp.open("POST", sXmlUrl, true);
	xmlHttpTemp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlHttpTemp.setRequestHeader("Content-length", sParams.length);
	xmlHttpTemp.setRequestHeader("Connection", "close");
	xmlHttpTemp.send(sParams);
}

/*
* Gets contents of specified .xml file using AJAX and if successful calls the createTable function.
* @dependant on: jquery-1.2.1.js
* @param sFile: the XML file to get data from
* @param sRowTag: Row XML tag
* @param sColumnTag: Column XML tag
* @param sTarget: element of calling page to insert the data into
* @param sTabID : id of new table to be dynamically created
*/
function getXML(sFile, sRowTag, sColumnTag, sTarget, sTabID, sOptionList, isSorted, arrayAlign, isPaged) {
	var sURL = sFile;
	var iRowCount = 0;
	var isCached = false;
	var iArrayCountNum = parseInt($("#" + sTabID +  "_xmlArrayNum").val());

	// test to see if we already have data loaded from the DB
	try {
		// if g_xmlData is NOT undefined - we have data - build table
		//if (g_xmlData !== undefined)
		if(g_arrayXML[iArrayCountNum] !== undefined){
			isCached = true;

			if (haveOption(sOptionList, "#FILTER")){
				var sFilterAttr = getOption( sOptionList, "#FILTER_ATTRIBUTE", "|");
				var sFilterAttrValue = getOption( sOptionList, "#FILTER", "|");

				var sXML = g_arrayXML[iArrayCountNum].cloneNode(true); // clone xmlDocument object so that that "g_xmlData" remains untouched
				var xmlRows = sXML.documentElement.childNodes;

				for (var i = 0; i < xmlRows.length;i++){
					if (xmlRows.item(i).nodeType == 1){
						if(xmlRows.item(i).getAttribute(sFilterAttr) != null){
							if(xmlRows.item(i).getAttribute(sFilterAttr) !== sFilterAttrValue){
								var xmlRootParent = xmlRows.item(i).parentNode;
								xmlRootParent.removeChild(xmlRootParent.childNodes[i]); // remove rows that do not match attribute value
							}
						}
					}
				}

				var sPrevFilterValue = $("#" + sTabID +  "_prevFilterValue").val();
				if (sPrevFilterValue !== sFilterAttrValue){ // if previous attribute value does not match current attribute value, reset global variables
					try {
						//remove previous hidden input fields
						$("#" + sTabID + "_firstDisplayed").remove();
						$("#" + sTabID + "_lastDisplayed").remove();
						$("#" + sTabID + "_buttonClicked").remove();
						$("#" + sTabID + "_isFirstTime").remove();
						$("#" + sTabID + "_prevFilterValue").remove();

						//add new hidden input fields
						$("<input type=\"hidden\" id=\"" + sTabID +  "_firstDisplayed\" style=\"display:none;\" value=\"1\" />").appendTo("#content");
						$("<input type=\"hidden\" id=\"" + sTabID +  "_lastDisplayed\" style=\"display:none;\" value=\"201\" />").appendTo("#content");
						$("<input type=\"hidden\" id=\"" + sTabID +  "_buttonClicked\" style=\"display:none;\" value=\"\" />").appendTo("#content");
						$("<input type=\"hidden\" id=\"" + sTabID +  "_isFirstTime\" style=\"display:none;\" value=\"true\" />").appendTo("#content");
						$("<input type=\"hidden\" id=\"" + sTabID +  "_prevFilterValue\" style=\"display:none;\" value=\"" + sFilterAttrValue + "\" />").appendTo("#content");
					}
					catch(err){}
					sPrevFilterValue = sFilterAttrValue;
				}
				iRowCount = createTable(sXML, sRowTag, sColumnTag, sTarget, sTabID, sOptionList, isSorted, arrayAlign, isPaged); // createTable with cloned xmlObject
			} else {
				iRowCount = createTable(g_arrayXML[iArrayCountNum], sRowTag, sColumnTag, sTarget, sTabID, sOptionList, isSorted, arrayAlign, isPaged); // createTable with original xmlDocument object
			}

			if(iRowCount > 0 && isSorted){ // only sort if have rows
				sortTable(sTabID); // sortTable must be defined in the page's own script.
			}
		}
	}
	catch(err){ // if g_xmlData is not declared, we catch the error and do a non-cached version.
		isCached = false;
	}

	if (!isCached) { // no cache found, or no g_xmlData found
		$.ajax(
		{
			url: sURL,
			type: "GET",
			dataType: "xml",
			timeout: 40000,
			error: function()
			{
				$("#" + sTarget).html("An error has occurred. Please try again shortly.");
			},
			success: function(xml)
			{
				try
				{
					g_arrayXML[g_iXMLArrayCounter] = xml;
				}
				catch(err){}

				//add new hidden input fields
				$("<input type=\"hidden\" id=\"" + sTabID +  "_firstDisplayed\" style=\"display:none;\" value=\"1\" />").appendTo("#content");
				$("<input type=\"hidden\" id=\"" + sTabID +  "_lastDisplayed\" style=\"display:none;\" value=\"201\" />").appendTo("#content");
				$("<input type=\"hidden\" id=\"" + sTabID +  "_buttonClicked\" style=\"display:none;\" value=\"\" />").appendTo("#content");
				$("<input type=\"hidden\" id=\"" + sTabID +  "_isFirstTime\" style=\"display:none;\" value=\"true\" />").appendTo("#content");
				$("<input type=\"hidden\" id=\"" + sTabID +  "_xmlArrayNum\" style=\"display:none;\" value=\"" + g_iXMLArrayCounter + "\" />").appendTo("#content");
				$("<input type=\"hidden\" id=\"" + sTabID +  "_prevFilterValue\" style=\"display:none;\" value=\"\" />").appendTo("#content");

				iRowCount = createTable(xml, sRowTag, sColumnTag, sTarget, sTabID, sOptionList, isSorted, arrayAlign, isPaged);
				g_iXMLArrayCounter++;

				if(iRowCount > 0 && isSorted) // only sort if have rows
				{
					sortTable(sTabID); // sortTable must be defined in the page's own script.
				}
			}
		});
	}
}
