// -------------------------
// --- utility functions ---
// -------------------------

// requires:
// 	nothing

function sEscapeHTML(sText) {
  if (sText == null) {
		return "";
	}
  sText = sText.replace(/'/g,"&#39;");
  sText = sText.replace(/\"/g,"&#34;");
  sText = sText.replace(/>/g,"&gt;");
  sText = sText.replace(/</g,"&lt;");
  return sText;
}

function sEscapeAmpersands(sText) {
	return sText ? String(sText).replace(/&/g,"&amp;") : '';
}

function sEscapeFinalHTML(sText) {
  if (sText == null) {
		return "";
	}
  sText = sText.replace(/>/g,"&gt;");
  sText = sText.replace(/</g,"&lt;");
  return sText;
	
	function sEncodeUnicode(sCharacter) {
		return "&#" + (sCharacter.charCodeAt(0)) + ";";
	}
}

function oValidate(sObject) {
	try {
		return eval(sObject);
	}
	catch (e) {
		return null;		
	}
}

function CancelEvent(oEvent) {
	if (typeof(window.event) != "undefined") {
		oEvent.cancelBubble = true;
		oEvent.returnValue = false;
	}
	else {
		oEvent.stopPropagation();
		oEvent.preventDefault();
	}
}

var sTryCatchTest = "try { } catch(e) { }";
var bInTryCatchTest = false;
var bInWindowAccessTest = false;
var bInWindowUnload = false;
var oWindowParent = null;
var oWindowOpener = null;

function TestCrossWindowAccess() {
	bInTryCatchTest = true;
	if (sTryCatchTest != null) {
		eval(sTryCatchTest); // check if try/catch is available, causes error if not
	}
	bInTryCatchTest = false;
	var sTryCatchPrefix = (sTryCatchTest != null) ? "try {" : "";
	var sTryCatchPostfix = (sTryCatchTest != null) ? "} catch(oEvent) { }" : "";
	
	// each of these tests causes an error if windows are cross-domain - handled by CatchCrossWindowError
	bInWindowAccessTest = true;
	eval (sTryCatchPrefix + "oWindowParent = (window.parent && window.parent != window && window.parent.location.href != null) ? window.parent : null;" + sTryCatchPostfix);
	eval (sTryCatchPrefix + "oWindowOpener = (window.opener && window.opener != window && window.opener.location.href != null) ? window.opener : null;" + sTryCatchPostfix);
	eval (sTryCatchPrefix + "oWindowOpener = (window.parent && window.parent != window && window.parent.opener != null && window.parent.opener.location.href != null) ? window.parent.opener : oWindowOpener;" + sTryCatchPostfix);
	bInWindowAccessTest = false;
	// cross-window tests are performed first, so that onload handlers can access other windows safely if needed
	ExecuteOnloadHandlers()	
}

function CatchCrossWindowErrors() {
	if (bInTryCatchTest) {
		sTryCatchTest = null;
		setTimeout("TestCrossWindowAccess()", 5);
		return true;
	}
	if (bInWindowAccessTest == true) { // were testing parent window access before error
		bInWindowAccessTest = false; // simply reset test flag - access is set true only if no error occurs
		ExecuteOnloadHandlers(); // proceed with other onload handlers
		return true; // cancel normal error mesage
	}
	if (bInWindowUnload == true) { // suppress error messages from unload functions (may refer to non-existent windows)
		bInWindowUnload = false;
		return true; // cancel normal error message
	}
	return false; // all other errors proceed as normal
}

var aoOnloadHandlers = new Array;

function AddOnloadHandler(oFunction) {
	aoOnloadHandlers[aoOnloadHandlers.length] = (typeof(oFunction) == "string") ? new Function(oFunction) : oFunction;
}

function ExecuteOnloadHandlers() {
	for (var i=0; i< aoOnloadHandlers.length; ++i) {
		aoOnloadHandlers[i]();
	}
}

var aoOnunloadHandlers = new Array;

function AddOnunloadHandler(oFunction) {
	aoOnunloadHandlers[aoOnunloadHandlers.length] = (typeof(oFunction) == "string") ? new Function(oFunction) : oFunction;
}

function ExecuteOnunloadHandlers() {
	bInWindowUnload = true; 
	for (var i=0; i< aoOnunloadHandlers.length; ++i) {
		aoOnunloadHandlers[i]();
	}
	bInWindowUnload = false;
}

window.onerror = CatchCrossWindowErrors;
window.onload = TestCrossWindowAccess;
window.onunload = ExecuteOnunloadHandlers;

// --------------------------------------------
// --- HTML-handling extensions for Firefox ---
// --------------------------------------------

if (typeof(HTMLElement) != 'undefined') {

	HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode) {
		switch (where) {
			case 'beforeBegin':
				this.parentNode.insertBefore(parsedNode,this)
				break;
			case 'afterBegin':
				this.insertBefore(parsedNode,this.firstChild);
				break;
			case 'beforeEnd':
				this.appendChild(parsedNode);
				break;
			case 'afterEnd':
				if (this.nextSibling) {
					this.parentNode.insertBefore(parsedNode,this.nextSibling);
				}
				else {
					this.parentNode.appendChild(parsedNode);
				}
				break;
		}
	}
	
	HTMLElement.prototype.insertAdjacentHTML = function (where,htmlStr) {
		var r = this.ownerDocument.createRange();
		r.setStartBefore(this);
		var parsedHTML = r.createContextualFragment(htmlStr);
		this.insertAdjacentElement(where,parsedHTML);
	}
	
	HTMLElement.prototype.__defineGetter__("outerHTML",	function() {
		return (new XMLSerializer()).serializeToString(this); 
	});
	
	HTMLElement.prototype.__defineSetter__("outerHTML",	function(sHTML) {
		var oRange = this.ownerDocument.createRange();
		oRange.setStartBefore(this);
		this.parentNode.replaceChild(oRange.createContextualFragment(sHTML), this);
	});
}

$(function() {
	fluxdocumentready = true;
});
