//NOTE: For writeXML to work you need to include: <xml id='defaultss' src='../globalXSL/defaultss.xsl'></xml>
//-----------------------------------------
// Copy & Paste this bit into your code:
if(typeof(debugOut) == 'undefined') { //This kicks in when we don't include MDOLNet/includes/debugOut.js
	var debugOut = new Object();
	for(var n in (new Array("getStackTrace","amIChild","getWindow","writeHTML","writeXML","write")))
		debugOut[n] = new Function();
}
//-----------------------------------------

debugOut();
function debugOut() {
	var debugWindow = null;
	var pendingWriteQueue = new Array();

	function write(sText) {
		var wnd = this.getWindow();
		if(wnd != null && wnd.document != null && wnd.document.body != null)
			wnd.document.writeln(sText + "</BR>");
		else
			wnd.pendingWriteQueue[pendingWriteQueue.length] = sText;
	}
	debugOut.write = write;

	function writeHTML(sText) {
		if(typeof(sText) != 'string') return null;
		sText = sText.replace(/\</gi, "&lt;");
    		sText = sText.replace(/\>/gi, "&gt;");
		return("<PRE>\n" + this.write(sText) + "</PRE>");
	}
	debugOut.writeHTML = writeHTML;

	function writeXML(sText) {
		if(typeof(sText) != 'string') {
			this.write("<FONT color='red'>" + getFunctionName(arguments.caller.callee) + ": Called debugOut.writeXML with an invalid (non-string) argument.</FONT>");
			return null;
		}
		if(typeof(defaultss) == 'object' && typeof(defaultss.documentElement) == 'object') {
			var sTransformOut;
			var oXml;
			try {
				oXml = new ActiveXObject("MSXML2.DOMDocument.3.0");
				oXml.loadXML(sText);
				sTransformOut = (oXml.transformNode(defaultss.XMLDocument));
				//sTransformOut = oXml.transformNode(defaultss.documentElement);
			} catch(e) {
				var sTextParseError = "";
				if(oXml.parseError.errorCode != 0) {
	   				var myErr = oXml.parseError;
	   				sTextParseError = "(Could not parse sText parameter as an XML document: " + myErr.reason + ")";
				}

				this.write("<FONT color='red'>" + getFunctionName(arguments.caller.callee) + ": Using writeHTML instead of writeXML as a transform error was encounted while formatting as XML:" + e.description + " " + sTextParseError + "</FONT>");
				this.writeHTML(sText);
			}
			this.write(sTransformOut);
		} else {
			this.write("<FONT color='red'>" + getFunctionName(arguments.caller.callee) + ": Using writeHTML instead of writeXML as defaultss is not defined. (try including: &lt;xml id='defaultss' src='../globalXSL/defaultss.xsl'&gt;&lt;/xml&gt;)</FONT>");
			this.writeHTML(sText);
		}
	}
	debugOut.writeXML = writeXML;

	function getWindow( ) {
		var wndopen = false;
		if(debugWindow == null) {
			debugWindow = window.open("about:blank", "debugOutPopup" + Math.round(Math.random() * 1000000));
			debugWindow.pendingWriteQueue = new Array();
			window.setTimeout(onWindowInit,50);
		}
		//check pendingWriteQueue
		return(debugWindow);
	}
	debugOut.getWindow = getWindow;

	function onWindowInit() {
		//for(var i = 0; i < debugWindow.window.pendingWriteQueue.length; i++)
		//	document.writeln(debugWindow.window.pendingWriteQueue[i] + '</BR>');

		debugWindow.setInterval("try { if(!window.opener.debugOut.amIChild(window)) window.close(); } catch(e) { window.close();}", 500);
	}

	function amIChild(oWindow) {
		return(oWindow == debugWindow);
	}
	debugOut.amIChild = amIChild;



	function genericWindowOnErrorHandler(sMsg,sUrl,sLine) {
		debugOut.write("<FONT color='red'>An error was thrown and caught.</FONT><br>" +
						"Error: " + sMsg + "<br>" +
						"Line: " + sLine + "<br>" +
						"URL: " + sUrl + "<br>" +
						"Stack Trace: </br><ol><PRE>" + getStackTrace() + "</PRE></ol>");

		//FIXME: Offer a key combination (ALT-SHIFT? JUST SHIFT?) which does not suppress default error popup so you can debug.
		return false; //return false to supress the default ie error popup.
	}

	//If we wait until after the window has completely loaded to override the error handler then IE will
	//	report better messages about script syntax errors (ie WHERE the missing ")" or "{" is at).
	function enableGenericWindowOnErrorHandler() {
		if(document.readyState == 'complete') {
			document.onreadystatechange = enableGenericWindowOnErrorHandler.oldOnReadyStateChange;

			if(typeof(enableGenericWindowOnErrorHandler.oldOnReadyStateChange) != 'undefined' && enableGenericWindowOnErrorHandler.oldOnReadyStateChange != null)
				enableGenericWindowOnErrorHandler.oldOnReadyStateChange();

			if(window.onerror == null)
				window.onerror = genericWindowOnErrorHandler;

		}
		if(typeof(enableGenericWindowOnErrorHandler.oldOnReadyStateChange) != 'undefined' && enableGenericWindowOnErrorHandler.oldOnReadyStateChange != null)
			enableGenericWindowOnErrorHandler.oldOnReadyStateChange();
	}
	enableGenericWindowOnErrorHandler.oldOnReadyStateChange = document.onreadystatechange;
	document.onreadystatechange = enableGenericWindowOnErrorHandler;
	debugOut.enableGenericWindowOnErrorHandler = enableGenericWindowOnErrorHandler;
	enableGenericWindowOnErrorHandler();



	function getFunctionName(f) {
	 var s = f.toString().match(/function (\w*)/)[1];
	 if ((s == "anonymous") || (s == null) || (s.length==0)) return("(" + f.toString()+")");
	 return s;
	}

	function getStackTrace() {
	 var s = "";
	 for (var a = arguments.caller.caller; a !=null; a = a.caller) {
	   s += "-> "+getFunctionName(a.callee) + "()\n";
	   if (a.caller == a) {s+="*"; break;}
	 }
	 return s;
	}
	debugOut.getStackTrace = getStackTrace;

//Enhancements:
//Add a function that will automatically add debug comments at runtime to a function. So do something like parse the text and add a debugOut.writeHTML(..); after every ";^p"
//Add a function which looks at a set of references ie "var1[index2].var4.method6().var1" and attempts evaluate the expression one step at a time to find any null of undefined badness.
}
