if (!sbweb.util.log) sbweb.util.log = function() {	

	// constants
	var PREFIX_DEBUG = "DEBUG";
	var PREFIX_ERROR = "ERROR";
	var LOG_DEBUG = 0;
	var LOG_ERROR = 5;
	var LOG_NONE = 10;
	
	var mLevel = LOG_NONE;
	function mLogger() {return(consoleLogger)};
	
	// log writer function calls the approriate logger
	this.callLogger = function (pMessage,pLevel) { 
		mLogger()(pMessage,pLevel);
	}
	
	// loggers
	var popupLogger = function(pMessage,pLevel) {
		
		var winName = "sb_log";
		var winAtt = "width=420,height=320,scrollbars=1,status=0,toolbars=0,resizable=1";
		var errorAlert = "The sb log window was blocked";
		var logTableId = "logTable";
		var logTableElement = "<table width='100%' id='" + logTableId + "'><tr><th align='left'>Time</th><th width='100%' colspan='2' align='left'>Message</th></tr></table>";
		
		// check if the window is already open
		if (!this._window || !this._window.document) {
			
			// open the window
			this._window = window.open("",winName,winAtt);
			if (!this._window) {
				alert(errorAlert);
				return;
			}
			if (!this._window.document.getElementById(logTableId)) {
				this._window.document.writeln(logTableElement);
				this._window.document.close();
			}
		};

		// add log message to window
		var tbl = this._window.document.getElementById(logTableId);
		var row = tbl.insertRow(-1);

		var cell_1 = row.insertCell(-1);
		var cell_2 = row.insertCell(-1);
		var cell_3 = row.insertCell(-1);
		cell_1.style.fontSize="12px";
		cell_1.style.fontWeight="bold";
		cell_1.style.paddingRight="6px";
		cell_2.style.fontSize="12px";
		cell_3.style.fontSize="12px";
		cell_3.style.whiteSpace="nowrap";
		cell_3.style.width="100%";
		
		if (tbl.rows.length % 2 == 0) {
			row.style.backgroundColor="#eeeeee";
		}

		var date = new Date();
		var hour = date.getHours();
		if (hour < 10) { hour = "0" + hour; }
		var minute = date.getMinutes();
		if (minute < 10) { minute = "0" + minute; }
		var second = date.getSeconds();
		if (second < 10) { second = "0" + second; }
		var date = (date.getMonth() +1 ) + "/" + date.getDate() + "/" + date.getFullYear() + "&nbsp;-&nbsp;" + hour + ":" + minute + ":" + second;
		
		cell_1.innerHTML=date
		cell_2.innerHTML=pLevel;
		cell_3.innerHTML=pMessage;
	}

	var writeLogger = function(pMessage,pLevel) {
		document.writeln(pLevel + "&nbsp;-&nbsp;" + pMessage + "<br/>");
	}

	var consoleLogger = function(pMessage,pLevel) {
		if (jQuery.browser.mozilla) {
			console.log(pLevel + " - " + pMessage);
		}
	}
	
	var alertLogger = function(pMessage,pLevel) {
		alert(pLevel + " - " + pMessage);
	}

	return{
		// public interfaces
		debug : function(pMessage) {
			if (mLevel <= LOG_DEBUG) {
				callLogger(pMessage,PREFIX_DEBUG);
			}
		},
		error : function(pMessage) {
			if (mLevel <= LOG_ERROR) {
				callLogger(pMessage,PREFIX_ERROR);
			}
		},
		
		// utility function that represents an object as a string
		dumpObject : function (pObject,pIndent) {
			if (!pIndent) { pIndent = " "; }
			var message="{ ";
			for (var property in pObject) {
				message += pIndent + property + ":";
				var type=typeof(pObject[property]);
				type = type.toLowerCase();
				if (type == "object") {
					message += this.dumpObject(pObject[property], pIndent + "----");
				}
				else {
					message += pObject[property];
				}
			}
			message += pIndent + "}";
			return(message);
		}
	}
	
}();