/**
 * Debug object for assisting in debugging javascript, acts as a console
 * that you can send messages to.
 *
 * @author David Spurr
 * @version 1.1 6th November 2005
 * @link http://www.defusion.org.uk/code/jsdebug/
 * @licence Creative Commons Attribution-ShareAlike 2.0 License (http://creativecommons.org/licenses/by-sa/2.0/)
 */
var Debug = {
	/**
	 * holds the console wrapper element
	 * @var div element
	 */
	wrap : null,
	/**
	 * holds the console menu bar
	 * @var ul element
	 */
	menu : null,
	/**
	 * holds the console
	 * @var textarea element
	 */
	console : null,
	/**
	 * whether the console is open or not
	 * @var boolean
	 */
	cnslOpen : null,
	/**
	 * holds the timeout for removing the notification border
	 * @var javascript timeout
	 */
	notifyTimeout : null,
	/**
	 * Whether the console should start minimised when it's first thrown
	 * @var boolean
	 */
	startMin : null,

	/**
	 * Initialises the object
	 *
	 * @access public
	 * @param boolean Start minimised (optional - default false)
	 * @param string The web path to the directory (or the Debug stylesheet) is in (e.g. /webfiles/) must include trailing slash
	 * @return void
	 */
	init : function(sMin) {
		wrap = null;
		menu = null;
		console = null;
		cnslOpen = false;
		notifyTimeout = null;
		startMin = typeof sMin != 'undefined' ? sMin : false;
	},

	/**
	 * Opens up the console window, creates a new one if it doesn't exist
	 *
	 * @access private
	 * @return void
	 * @todo Don't try and throw the console if we can't, ie if the document body isn't there, but cache messages sent to the console?
	 */
	throwConsole : function() {
		if(!cnslOpen) {
			if(console == null) {
				var style = document.createElement('LINK');
				style.rel = 'stylesheet';
				style.href = 'css/Debug.css';
				document.getElementsByTagName('head')[0].appendChild(style);
				var w = document.createElement('DIV');
				w.id = 'dbgWrap';
				var m = document.createElement('UL');
				m.id = 'dbgMenu';
				Debug.addMenuItem(m, Debug.closeCnsl,'X','Close');
				Debug.addMenuItem(m, Debug.restore,'+','Restore');
				Debug.addMenuItem(m, Debug.minimize,'-','Minimize');
				Debug.addMenuItem(m, Debug.clear,'C','Clear Output');
				var t = document.createElement('DIV');
				t.innerHTML = 'JS Debug output';
				m.appendChild(t);
				w.appendChild(m);
				var cnsl = document.createElement('DIV');
				cnsl.id = 'dbgConsole';
				w.appendChild(cnsl);
				document.body.appendChild(w);
				console = cnsl;
				if(startMin) Debug.minimize();
				wrap = w;
				menu = m;
				Debug.extendConsole();
			} else wrap.style.display = 'block';
			cnslOpen = true;
		}
	},

	/**
	 * A method to be used for initializing any extensions (called after the console is created)
	 *
	 * @access public
	 * @return void
	 * @abstract
	 */
	extendConsole : function() {
	},

	/**
	 * Adds a menu item to the consoles menu
	 *
	 * @access private
	 * @return void
	 */
	addMenuItem : function(m, o, t, a) {
		var mI = document.createElement('LI');
		mI.onclick = o;
		mI.innerHTML = t;
		mI.title = a;
		m.appendChild(mI);
	},

	/**
	 * Minimizes the console window
	 *
	 * @access public
	 * @return void
	 */
	minimize : function() {
		console.style.display = 'none';
	},

	/**
	 * Restores the minimized console window
	 *
	 * @access public
	 * @return void
	 */
	restore : function() {
		console.style.display = 'block';
	},

	/**
	 * 'Closes' the console window by hiding it
	 *
	 * @access public
	 * @return void
	 */
	closeCnsl : function() {
		wrap.style.display = 'none';
		Debug.clear();
		cnslOpen = false;
	},

	/**
	 * Clears the contents of the console window
	 *
	 * @access public
	 * @return void
	 */
	clear : function() {
		console.innerHTML = '';
	},

	/**
	 * Raises a message in the console window
	 *
	 * @access public
	 * @var string Message to raise
	 * @return void
	 */
	raise : function(msg) {
		Debug.throwConsole();
		console.innerHTML += '<span class="msg">' + msg + '</span><br />';
		clearTimeout(notifyTimeout);
		Debug.notify();
		notifyTimeout = setTimeout(Debug.clearNotification, 1000);
		console.scrollTop = console.scrollHeight; // scroll with the messages
	},

	/**
	 * Sets the class name of the wrapper to include 'notify', which
	 * can be used to highlight the fact that a message has being passed to the console.
	 * This is useful when the console is minimized.
	 *
	 * @access public
	 * @return void
	 */
	notify : function() {
		if(!wrap.className.match('notify')) wrap.className += ' notify';
	},

	/**
	 * Removes the notification class name from the wrapper
	 *
	 * @access public
	 * @return void
	 */
	clearNotification : function() {
		wrap.className = wrap.className.replace('notify', '');
	}
}

Debug.init();
