// RemoteScripting.js
// Author: Luke Sankey
// Browsers: ALL
//
// This little guy pulls data from the server via JavaScript.  It will try to
// use the XMLHttp functionality of the browser, but if it isn't supported,
// will default back to using the tried and true IFRAMEs, an HTML4 standard.
//
// If XMLHttp works, then the returned text will be treated as script and
// executed.  This is the preferred method because it hides the browser
// activity from the user and is much faster.
//
// If XMLHttp is not supported, then the code loads the returned text into an
// IFRAME.  The server receives the "&callback=" parameter, and should format
// the data correctly for executing from inside an IFRAME instead of from the
// caller's frame.  The callback parameter shall be treated as a function name,
// and executed upon completion of the IFRAME load.

var bUsingIFrames = false;

function callToServer(URL, callback)
{
	try
	{ //throw "error"; // debug iframes
		// Try xmlHttp
		var xmlHttp = XmlHttp.create();
		xmlHttp.open("GET", URL, true); // asynchronous
		xmlHttp.onreadystatechange = function ()
		{
			if (xmlHttp.readyState == 4)
			{
				eval(xmlHttp.responseText); // execute code when it comes back
				if (callback != undefined)
					eval(callback+"()");
			}
		}
		xmlHttp.send(null);
	}
	catch(ex)
	{
		bUsingIFrames = true;
		// use backup IFRAME method
		replaceIFrame(URL+"&callback="+callback);
	};
}



//////////////////////////////////////////////////////////////////////////
// Thanks http://webfx.eae.net/dhtml/xmlextras/xmlextras.html

// XmlHttp factory
function XmlHttp() {}
XmlHttp.create = function ()
{
	try
	{
		if (window.XMLHttpRequest) 
		{
			var req = new XMLHttpRequest();

			// some older versions of Moz did not support the readyState property
			// and the onreadystate event so we patch it!
			if (req.readyState == null)
			{
				req.readyState = 1;
				req.addEventListener(
					"load", // event = "load"
					function () // inline callback function
					{
						req.readyState = 4;
						if (typeof req.onreadystatechange == "function")
							req.onreadystatechange();
					},
					false); // usecapture = false
			}
			return req;
		}

		if (window.ActiveXObject)
			return new ActiveXObject(getControlPrefix() + ".XmlHttp");
	}
	catch (ex) {}

	// fell through
	throw new Error("Your browser does not support XmlHttp objects");
}

function getControlPrefix()
{
	// Only do this work once
	if (getControlPrefix.prefix)
		return getControlPrefix.prefix;

	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o, o2;
	for (var i = 0; i < prefixes.length; i++)
	{
		try
		{
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			o2 = new ActiveXObject(prefixes[i] + ".XmlDom");
			return getControlPrefix.prefix = prefixes[i];
		}
		catch (ex)
		{};
	}

	throw new Error("Could not find an installed XML parser");
}


//////////////////////////////////////////////////////////////////////////
// Thanks http://developer.apple.com/internet/webcontent/iframe.html

var IFrameObj; // our IFrame object
function replaceIFrame(URL)
{
	// Return true on error
	if (!document.createElement)
		return true;

	var IFrameDoc;
	if (!IFrameObj)
	{
		// create the IFrame and assign a reference to the
		// object to our global variable IFrameObj.
		// this will only happen the first time 
		// callToServer() is called
		try
		{
			var tempIFrame=document.createElement('iframe');
			tempIFrame.setAttribute('id','RSIFrame');
			tempIFrame.style.border='0px';
			tempIFrame.style.width='0px';
			tempIFrame.style.height='0px';
			IFrameObj = document.body.appendChild(tempIFrame);

			if (document.frames)
			{
				// this is for IE5 Mac, because it will only
				// allow access to the document object
				// of the IFrame if we access it through
				// the document.frames array
				IFrameObj = document.frames['RSIFrame'];
			}
		}
		catch(exception)
		{
			// This is for IE5 PC, which does not allow dynamic creation
			// and manipulation of an iframe object. Instead, we'll fake
			// it up by creating our own objects.
			iframeHTML='\<iframe id="RSIFrame" style="';
			iframeHTML+='border:0px;';
			iframeHTML+='width:0px;';
			iframeHTML+='height:0px;';
			iframeHTML+='"><\/iframe>';
			document.body.innerHTML+=iframeHTML;
			IFrameObj = new Object();
			IFrameObj.document = new Object();
			IFrameObj.document.location = new Object();
			IFrameObj.document.location.iframe = document.getElementById('RSIFrame');
			IFrameObj.document.location.replace = function(location)
			{ this.iframe.src = location; }
		}
	}

	if (navigator.userAgent.indexOf('Gecko') !=-1 && !IFrameObj.contentDocument)
	{
		// we have to give NS6 a fraction of a second
		// to recognize the new IFrame
		setTimeout('replaceIFrame('+URL+')',10);
		return false;
	}

	if (IFrameObj.contentDocument) // For NS6
		IFrameDoc = IFrameObj.contentDocument; 
	else if (IFrameObj.contentWindow) // For IE5.5 and IE6
		IFrameDoc = IFrameObj.contentWindow.document;
	else if (IFrameObj.document) // For IE5
		IFrameDoc = IFrameObj.document;
	else
		return true;

	// Success finding the IFrame
	IFrameDoc.location.replace(URL);
	return false;
}
