/**
* Global instance of request object
*/
var http_request = null;

var ajax_request_queue = new Array();

/** 
* ajax_init()
* Initialise AJAX to be called inside <body onload=""> 
*/
function ajax_init()
{	create_http_request_object();
}

/** 
* create_http_request_object()
* Create a new instance of the HTTP request object with 
* cross-browser support
*/
function create_http_request_object()
{
	var ro = null;
	if(window.ActiveXObject)
	{	ro = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else
	{	ro = new XMLHttpRequest();
	}
	if(ro==null)
	{	alert("Error: Your browser does not support the necessary functionality. (Create HRO)");
	}
	http_request = ro;
	return ro;
}

/** 
* http_request_exists()
* Returns true if http_request global instance exists 
* and is set
*/
function http_request_exists()
{
	if(http_request==null)
	{	
		http_request = create_http_request_object();
		if(http_request==null)
		{
			alert("Error: Your browser does not support the necessary functionality. (Use HRO)");
			return false;			
		}
	}
	return true;
}

/** 
* get_http_response_text()
* Returns the response as plain text/plain
*/
function get_http_response_string()
{	return http_request.responseText;
}

/** 
* get_http_response_text()
* Returns the response as text/xml
*/
function get_http_response_xml()
{	return http_request.responseXML;
}

/** 
* response_exists()
* Returns true if the server response is waiting and 
* there is no error in the response
*/
function http_response_exists()
{
	if(http_request_exists() && (http_request.readyState==4) && (http_request.status==200))
	{
		handle_response_error();
		return true;
	}
	return false;
}

/** 
* push_request(url, callback_function)
* Push a new request into the HTTP request queue. Note that
* all requests are send via HTTP GET
*/
function push_request(url, callback_function)
{
	if(document.getElementById("waiting"))
	{
		document.getElementById("waiting").style.display = 'block';
		if(document.getElementById("portfolio_image"))	
			document.getElementById("portfolio_image").innerHTML = '';
	}
	var new_request = new Array();
	new_request[0] = url;
	new_request[1] = callback_function;
	ajax_request_queue.push(new_request);
	setTimeout("shift_request();", 100);
}

/** 
* shift_request()
* Shift a request from the queue when the request object is
* ready
*/
function shift_request()
{
	if((http_request.readyState==4 || http_request.readyState==0) && ajax_request_queue.length > 0)
	{
		var request = ajax_request_queue.shift();
		http_request.open('GET', request[0], true);
		http_request.onreadystatechange = request[1];
		http_request.send(null);
	}
	return true;
}

/** 
* handle_response_error()
* Support function for response_exists() - will alert server 
* response error
*/
function handle_response_error()
{
	var response = http_request.responseText;
	if((response.indexOf('AJAX_ERROR')>=0) || (response.length==0))
	{	alert("Error: Server response produced an exception or does not exist:\n\n"+response);
	}
}

/** 
* load_xslt(xslt_path)
* Load XSLT document synchronously from server 
* given the .xsl path. Returns XSLT doc object
*/
function load_xslt(xslt_path)
{
 	var xslt_doc_tmp = null;
	if(http_request_exists())
	{
		http_request.open("GET", xslt_path, false);        
		http_request.send(null);    
		if(this.DOMParser)
		{
			var dp = new DOMParser();
			xslt_doc_tmp = dp.parseFromString(http_request.responseText, "text/xml");
		} 
		else if(window.ActiveXObject)
		{
			xslt_doc_tmp = create_msxml_to_document_object();         
			xslt_doc_tmp.async = false;         
			xslt_doc_tmp.load(http_request.responseXML);
		}
		if(xslt_doc_tmp==null)
		{	alert("Error: Failed to load synchronous XSLT via HRO\n(Your browser does not support the necessary functionality)");
		}
		xslt_doc = xslt_doc_tmp;
		return xslt_doc_tmp;
	}
	return false;
}

/** 
* create_msxml_to_document_object()
* Create a Microsoft XML to DOM document object which allows
* the processing of XSTL

*/
function create_msxml_to_document_object()
{
	var msxml_2_dom;
	var msxml_2_dom_document_versions = new Array("Msxml2.DOMDocument.6.0",
											      "Msxml2.DOMDocument.5.0",
											      "Msxml2.DOMDocument.4.0",
												  "Msxml2.DOMDocument.3.0");
	for(var i=0; i<msxml_2_dom_document_versions.length && !msxml_2_dom; i++) 
	{
		try 
		{	msxml_2_dom = new ActiveXObject(msxml_2_dom_document_versions[i]);
		} 
		catch(e) {}
	}
	if (!msxml_2_dom)
	{
		alert("Please upgrade your MSXML version from \n" + 
		  	  "http://msdn.microsoft.com/XML/XMLDownloads/default.aspx");
		return false;
	}
	else 
	{	return msxml_2_dom;
	}
}

/** 
* create_xhtml_fragment(response_xml)
* Create a XHTML fragment from response XML parsed via
* XSLT file, passing the response XML data and the XSLT
* as a docuemnt object Returning the XHTML frgament
*/
function create_xhtml_fragment(response_xml, xslt_doc)
{
	if(xslt_doc==null)
	{
		alert("Error: XSLT document object does not exist\n(Your browser does not support the necessary functionality)");
		return false;
	}
	if(window.XMLHttpRequest && window.XSLTProcessor && window.DOMParser)
	{
		var xslt_processor = new XSLTProcessor();
		xslt_processor.importStylesheet(xslt_doc);
		return xslt_processor.transformToFragment(response_xml, document);
	}
	else if(window.ActiveXObject)
	{
		var xslt_processor = create_msxml_to_document_object();
		xslt_processor.async = false;
		xslt_processor.load(response_xml);
		return xslt_processor.transformNode(xslt_doc);
	}
	alert("Error: Failed to create XHTML fragment\n(Your browser does not support the necessary functionality)");
	return false;
}

/** 
* get_element(element_id)
* Returns a DOM element object, passing it's ID
*/
function get_element(element_id)
{
	var element = document.getElementById(element_id);
	if(!element)
	{
		alert("Error: Failed to find DOM element\n(Your browser does not support the necessary functionality)");
		return false;
	}
	return element;
}

/** 
* insert_xhtml_into_dom_element(element_id, fragment)
* Inserts an XHTML fragment into a selected page element using
* methods depending on browser type. Returns XHTML fragment as
* a string
*/
function insert_xhtml_into_dom_element(element_id, fragment)
{
	var element = get_element(element_id);
	if(window.ActiveXObject)
	{	
		element.innerHTML = fragment;
		return element.innerHTML;
	}
	else
	{	
		element.innerHTML = "";
		element.appendChild(fragment);
		return element.innerHTML;
	}
	return false;
}
