/////////////////////////////////////////////////////
//	Method used to retrieve an xhtml formated block
//	from the provided href and insert it into the
//	document.
//
//	href - Target url to request the data from, i.e. /Somewhere/GetData.aspx?id=545
//	target - The text id of the html element that will have the xhtml inserted into (InnerHTML)
//	funcToCall - JavaScript function to call when the data has been loaded.
//	data - Data to push back in the body of the request, i.e. form data.
//	isFormData - boolean indicating that the data is infact form data.

function loadXHTMLFragment(href, target, data, isFormData, ignoreChangebar)
{
	return _loadXHTMLFragment(retrieveXMLDoc(href, data, isFormData), target, ignoreChangebar);
}
function _loadXHTMLFragment(response, target, ignoreChangebar)
{
	var status = -1;
	
	if (response != null) {
		replaceTag(target, response.responseText);

		if (!ignoreChangebar)
		{
			//	Ensure that the change bar is updated

			var script = retrieveXMLDoc("/PMM/Common/UpdateChangeBar.jsp", null, false);
		
			if (script != null)
				replaceTag(null, script.responseText);
		}
			
		status = response.status;
	}

	response = null;
	
	return status;
}

function requestAjaxNoChangeBar(href, target, data, isFormData)
{
	var response = retrieveXMLDoc(href, data, isFormData);

	if (response != null)
		replaceTag(target, response.responseText);
		
	response = null;
}

function loadXHTMLFragmentStopScroll() { document.body.scrollTop = 0; }

/////////////////////////////////////////////////////
//	Method used to retrieve a response from the server
//	but not inject that response into the page. Used
//	for validation etc.

function retrieveServerResponse(href, data) {
	var response = retrieveXMLDoc(href, data, (data != null));
	
	return (response != null ? response.responseText : null);
}

/////////////////////////////////////////////////////
//	This method controls the request for data the parameters
//	provided are a subset of the ones for loadXHTMLFragment.
//
//	If the request fails, or non-XHTML is returned then the
//	method will insert the result into the main document.
//	Really this is for debugging only....

function retrieveXMLDoc(href, data, isFormData)
{
	var xmlHttp = XmlHttp.Create();
	
	try
	{
		//	If data is provided, the request should be a POST
		xmlHttp.open(data == null ? "GET" : "POST", href, false);	// false = sync call
		
		//	In-order for the web-server to decode the form data, the content-type
		//	needs to be adjusted
		if (isFormData)
			xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");

		//	Do the request.
		xmlHttp.send(data);
		
		return xmlHttp;
	}
	catch (e)
	{
		//	Keep silent about errors for now, allow the calling code to handle the null returned
	}
	
	xmlHttp = null;
	
	return null;
}

/////////////////////////////////////////////////////
//	Simply inserts the supplied HTML inside the named
//	tag, and extracts and runs the script contained
//	within.

var scriptExp = '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)';

function replaceTag(tagName, withHTML)
{
	if (withHTML == null)
		withHTML = "";

	var scriptMatcher = new RegExp(scriptExp, 'img');
	var response = withHTML.replace(scriptMatcher,'');
	var scripts = withHTML.match(scriptMatcher);

	if (tagName != null)
	{
		var responseTarget = getRef(tagName);
		
		if (responseTarget)
			responseTarget.innerHTML = response;
		else
		{
			try {		
		//		console.info("Missing element " + tagName);   (Y 31150 comment out this line which cause error in IE)
				return;
			} catch (ex) {}
		}
	}
	
	if (scripts != null) {
		scriptMatcher = new RegExp(scriptExp, 'im');

		if (scripts.length > 0) {
			for (var i = 0; i < scripts.length; i++) {
				var closeBrace = scripts[i].indexOf('>');
				var openBrace = scripts[i].lastIndexOf('<');
				var s = scripts[i].substring(closeBrace+1,openBrace);//.match(scriptMatcher)[1];
				//alert(s.substring(0,Math.min(200,s.length)));
				try {
					eval(s);
				}
				catch (e) {
					alert( e + ":" + s);
				}
			}
		}
	}
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//
//	Class provides a wrapper around the XmlHttpRequest
//	capablilities of Internet Explorer, Mozilla and
//	Firefox.

/////////////////////////////////////////////////////
//	Declare the new class of object.

function XmlHttp() {}

/////////////////////////////////////////////////////
//	Method to create the browser specific object that
//	will handle the request.
//	Note: The Mozilla and Firefox versions add an event
//	listener to support notification that the data has
//	been loaded. Generally this is only useful when
//	using the resulting object with an aync request.

XmlHttp.Create = function ()
{
	try
	{
		if (window.XMLHttpRequest)
		{
			var req = new XMLHttpRequest();

			//	Ensure that the readyState is supported
			if (req.readyState == null)
			{
				req.readyState = 1;
				req.addEventListener("load", function () {
					req.readyState = 4;
					if (typeof req.onreadystatechange == "function")
						req.onreadystatechange();
				}, false);
			}
			
			return req;
		}

		if (window.ActiveXObject)
		{
			return new ActiveXObject("Microsoft.XmlHttp");
		}
	}
	catch (ex) {}
	// fell through
	throw new Error("Your browser does not support AJAX. Please check the product documentation for supported browsers");
};

/////////////////////////////////////////////////////
//	This method retrieves a chunk of XML from the server
//	without converting it into a string

function retrieveRawXMLDoc(href, data, isFormData)
{
	var xmlHttp = retrieveXMLDoc(href, data, isFormData);
	var response = (xmlHttp ? xmlHttp.responseXML : null);
	
	xmlHttp = null;
	
	return response;
}

/////////////////////////////////////////////////////
//	Retrieves a junk of XML and an associated XSL
//	stylesheet from the server, transforms the XML
//	using the XSL and inserts the resulting XML into
//	the document.
//
//	If no XSL href is provided then the XML document
//	is simply inserted into the document.

function loadXMLIntoDocument(xmlHref, xslHref, target, data, isFormData)
{
	//	Retrieve the XML and XSL from the server.
	var xml = retrieveRawXMLDoc(xmlHref, data, isFormData);
	var xsl = xslHref == null ? null : retrieveRawXMLDoc(xslHref, null, false);
	var transformedXml = null;
	
	if (xml)
	{
		//	If a stylesheet is available transform the data
		if (xsl)
		{
			var xslProcessor = null;
			
			try {
				xslProcessor = new XSLTProcessor();
			}
			catch(e) {
				//	Do nothing, xslProcessor already null
			}
			
			try
			{
				if (xslProcessor != null)
				{
					xslProcessor.importStylesheet(xsl);
					xml = xslProcessor.transformToFragment(xml, document);
					
					var xmlSerializer = new XMLSerializer();
					
					transformedXml = xmlSerializer.serializeToString(xml);
				}
				else
				{
					transformedXml = xml.transformNode(xsl);
				}
			}

			catch (e)
			{
				//	transformedXml will still be null, which is handled by replaceTag
			}
		}
	
		replaceTag(target, transformedXml);
	}	
}

/////////////////////////////////////////////////////

function CSAjax(url,data,errorcallback)
{
	this._url = url;
	this._data = data;
	this._onerror = errorcallback;
	this._target = null;
	this._callback = null;
	this._xmlCallback = null;
}
CSAjax.prototype.READY_STATE_UNINITIALIZED = 0;
CSAjax.prototype.READY_STATE_LOADING = 1;
CSAjax.prototype.READY_STATE_LOADED = 2;
CSAjax.prototype.READY_STATE_INTERACTIVE = 3;
CSAjax.prototype.READY_STATE_COMPLETE = 4;
CSAjax.prototype.setCallback = function(callback)
{
	this._callback = callback;
}
CSAjax.prototype.setXmlCallback = function(callback)
{
	this._xmlCallback = callback;
}
CSAjax.prototype.setTarget = function(target)
{
	this._target = target;
}
CSAjax.prototype.setErrorCallback = function(callback)
{
	this._onerror = callback;
}
CSAjax.prototype.cancel = function()
{
	if (this._xmlHttp)
	{
		var httpStatus = this._xmlHttp.status;
		if ((httpStatus != 200) || (httpStatus != 0))
			this._xmlHttp.abort();
		return httpStatus + " " + this._callbackData;
	}
}
CSAjax.prototype.makeRequest = function()
{
	this._xmlHttp = XmlHttp.Create();
	
	try
	{
		var instance = this;
		this._xmlHttp.onreadystatechange = function() {
			instance.onReadyState.call(instance);
		}
	
		var isPost = this._data != null;
	
		//	If data is provided, the request should be a POST
		this._xmlHttp.open(isPost ? "POST" : "GET", this._url, true);	// true = async call
		
		//	In-order for the web-server to decode the form data, the content-type
		//	needs to be adjusted
		if (isPost)
			this._xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");

		//	Do the request.
		this._xmlHttp.send(this._data);
	}
	catch (e)
	{
		if (this._onerror)
			this._onerror();
	}
}
CSAjax.prototype.onReadyState = function()
{
	var xmlHttp = this._xmlHttp;
	var ready = xmlHttp.readyState;
	if (ready == this.READY_STATE_COMPLETE)
	{
		var httpStatus = xmlHttp.status;
		if ((httpStatus == 200) || (httpStatus == 0))
		{
			if (this._target)
			{
				replaceTag(this._target, xmlHttp.responseText);
			}
			
			if (this._callback)
			{
				this._callback(xmlHttp.responseText, this);
			}
			
			if (this._xmlCallback)
			{
				this._xmlCallback(xmlHttp.responseXML);
			}
		}
		else if (this._onerror)
		{
			this._onerror(this);
		}
	}
}


