/* 
	FlangeLib - A JavaScript library
	adamv.com 
	
	Logging Module.
	
	Inspired by Bob Ippolito's description of his logging module:
	http://bob.pythonmac.org/archives/2005/07/03/bookmarklet-based-debugging/
*/

function LogItem(index, level, message){
	this.index = index;
	this.level = level;
	this.message = message;
	this.timestamp = new Date();
}

LogItem.prototype = {
	toString: function(format){
		var s;
		
		format = format || "[{index}] {level}: {message}";
		s = format.template({
			index: this.index+1,
			level: this.level,
			message: this.message,
			timestamp: this.timestamp
		});
			
		return s;
	}
};

function Logging_baseLog(level, objs, sep){
	Logging._log.push(
		new LogItem(
			Logging._logCount, 
			level, 
			Array.prototype.join.apply(objs, [sep])));
		
	Logging._logCount++;

	// Trim down the log size		
	if (Logging.maxSize)
		while(Logging.maxSize < Logging._log.length) Logging._log.shift();
	
	Logging.notifyListeners();
}

var Logging = {
	maxSize: null,
	_log: new Array(),
	_listeners: new Array(),
	_logCount : 0,
	
	baseLog: Logging_baseLog,
	
	log: Logging_baseLog.partial("Info"),
	logDebug: Logging_baseLog.partial("Debug"),
	logError: Logging_baseLog.partial("Error"),


	clear: function(){
		Logging._log = new Array();
		// Logging._logCount = 0; // clearing the log doesn't reset the count in a session
	
		Logging.notifyListeners();
	},
	
	addListener: function(f){
		Logging._listeners.push(f)
	},

	removeListener: function(f){
		Logging._listeners.remove(f)
	},
	
	notifyListeners: function(){
		foreach(Logging._listeners, function(listener){
			try{listener()}catch(e){}
		});
	},
	
	bookmarklet_popup: function(log_size){
		log_size = log_size || 15;
		
		var popup = window.open("", "log_", "height=400,width=500,statusbar=yes,resizable=yes,scrollbars=yes");
		if (popup.alreadyOpen)
			return;
			
		popup.alreadyOpen = true;

		popup.document.open();
		popup.document.write([
"<html><head>",
"<title>Flangelib Log</title>",
"<style>",
"body { margin:0; border:0; padding:0 0 25px 0; font-family:Verdana; font-size:10px; }",

"#toolbar { position:absolute; bottom:0; left: 0; width: 100%; height: 25px; border-top: 1px solid black; background:#9cf;}",

"@media screen { body>#toolbar{position: fixed}}",

"* html body {overflow:hidden;}",

"* html #log {height: 100%; overflow: auto}",

"b {font-weight:normal;color:#369}",
"</style>",
"</head><body onunload='window.opener.Logging.removeListener(window.logListener);'>",
"<div id='toolbar'><input type=submit onclick='window.opener.Logging.clear();' value='Clear' /></div>",
"<div id='log'></div>",
"</body></html>"].join(""));
		
		function f(){
			var items = Logging._log.slice(-log_size);
			items.reverse();
			var logText = "<ol type='1'>"+
				collect(items, function(item){
						return item.toString("<li value='{index}' title='{timestamp}'><b>{level}</b> {message}</li>");
					}
				).join("\n") + "</ol>";
			popup.document.getElementById('log').innerHTML = ws_to_html(link_to_html(logText));
		}

		f();
		Logging.addListener(f);
		popup.logListener = f;
		
		popup.document.close();
		popup.defaultStatus="Flangelib Log Window";
	},
	
	bookmarklet: function(log_size){
		log_size = log_size || 10;
		alert(Logging._log.slice(-log_size).join("\n"));
	}
};
