// < Utility functions >

// global variables
var isIE = navigator.userAgent.toLowerCase().indexOf("msie") != -1;
var logWindow = null; // used by log and profiler functions
var callstack = new Array(); // used by profiler functions
var logging = false; // global toggle to indicate whether debug logging should be output

var ELEMENT_NODE = 1;
var TEXT_NODE = 3;

var logger = new Object();
logger.enabled = logging;
logger.log = function(msg) {
	if (logger.enabled) {
		if (!logWindow || logWindow.closed) {
			logWindow = window.open("about:blank", "logWindow", "left=500, top=300, width = 500, height=500, resizable=yes, scrollbars=yes");
			logWindow.document.open();
			logWindow.document.write("<BODY></BODY>");
			logWindow.document.close();
		}
		if (logWindow && !logWindow.closed) {
			var date = new Date();
			var prefix = "" + date.getMinutes() + ":" + date.getSeconds() + ">"; // + "." + date.getMilliseconds().toString() + ">";
			for (var i=0; i < callstack.length; i++) {
				prefix = prefix + "  ";
			}
			preElement = logWindow.document.createElement("pre");
			logWindow.document.body.appendChild(preElement);
			msg = msg.replace("\n", "\n"+prefix);
			preElement.innerHTML = prefix + msg;
			preElement.scrollIntoView();
		} else {
			alert(msg);
		}
	}
}
logger.info = function(msg) {
	this.log(msg);
}
logger.warning = function(msg) {
	this.log("WARNING: "+msg);
}
logger.error = function(msg) {
	this.log("ERROR: "+msg);
	//alert(msg);
}
logger.enterMethod = function (methodName) {
	this.info("->"+methodName);
	callstack.push(methodName);
}
logger.exitMethod = function () {
	var methodName = callstack.pop();
	this.info("<-"+methodName);
}



// Returns the textual contents of the given element
function getTextValue(element) {
	var result = "";
	var node;
	for (node = element.firstChild; node != null; node = node.nextSibling) {
		if (node.nodeType == TEXT_NODE) {
			result += node.nodeValue;
		} else if (node.nodeType == ELEMENT_NODE) {
			result += getTextValue(node);
		}
	}
	return result;
}
function trim(str) {
	return str.replace(/^\s*|\s*$/g,"");
}

function parseXML(XML) {
	var result;
	if (isIE) {
		var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
		xmlDoc.async = false;
		xmlDoc.loadXML(XML);
		if (xmlDoc.parseError.errorCode != 0) {
			error("Unable to parse XML: "+XML+"\nError=: "+xmlDoc.parseError);
		} else {
			log("parsed XML in IE: "+xmlDoc.xml);
			result = xmlDoc;
		}
	} else {
		var parser = new DOMParser();
		var document = parser.parseFromString(XML, "text/xml");
		if (document.documentElement.localName == "parsererror") {
			error("Unable to parse XML: "+XML);
		} else {
			result = document;
		}
	}
	return result;
}
function serializeNode(node) {
	if (isIE) {
		return ""+node;
	} else {
		var serializer = new XMLSerializer();
		return serializer.serializeToString(node);
	}
}

function enterMethod(methodName) {
	logger.enterMethod(methodName);
}
function exitMethod() {
	logger.exitMethod();
}
function log(msg) {
	logger.log(msg);
}
function error(msg) {
	logger.error(msg);
}
function warning(msg) {
	logger.warning(msg);
}

// ------------------------------------------------------------------
// formatDate (date_object, format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as the
// java.text.SimpleDateFormat class.
// This function is copied from
// http://www.mattkruse.com/javascript/date/source.html
// ------------------------------------------------------------------
var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}

function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
}

// </ Utility functions >
