/**
 * @author Fred Ghosn <fred.ghosn@mtvncontractor.com>
 * @author Shawn Carrillo <shawn.carrillo@nick.com>
 */

var NICK_LOG_ERROR   = 0x00;
var NICK_LOG_WARNING = 0x02;
var NICK_LOG_DEBUG   = 0x04;
var NICK_LOG_INFO    = 0x08;
var NICK_LOG_FATAL   = 0x16;

var NickLog = function() {
	var isDebugging = KIDS && KIDS.IS_DEBUG;
	var hasConsole  = isDebugging && typeof window.console.log != "undefined";
	var hasFirebug  = isDebugging && !!window.console.firebug;
	var isSafari	= isDebugging && console.log.apply === "function"; 

	function getCallers( args ) {
		var currentObject = args.callee.caller;
		var methodList = [];

		while( currentObject != null ) {
			// Push the method name onto the method list
			var currentMethod = currentObject.name || getMethodName( currentObject.toString() );

			if ( currentMethod.length !== 0 ) {
				methodList.push( currentMethod );
			}

			// Set currentObject to the next caller
			currentObject = currentObject.caller;
		}

		return '[' + methodList.reverse().join(' -> ') + ']';
	}

	function getMethodName( string ) {
		var regex = /function\s*([\w\-$]+)?\s*\(/i;
		return regex.test( string ) ? RegExp.$1 : '';
	}

	return {
		addMessage: function( message, type, stack, args ) {
			if ( !isDebugging ) return;

			if ( hasFirebug ) {
				var method;

				switch( type ) {
					case NICK_LOG_FATAL:
						message = "[FATAL]: " + message;
					case NICK_LOG_ERROR:
						method = "error";
						break;
					case NICK_LOG_WARNING:
						method = "warn";
						break;
					case NICK_LOG_INFO:
						method = "info";
						break;
					default:
						method = "log";
				}

				console[method]( message + "\t%o", args.callee.caller );

				if ( stack === true ) {
					console.trace();
				}
			} else if ( hasConsole ) {
				if( isSafari ) {
					window.console.log.apply(window.console, arguments);
			    } else {	    	
					console.log(message);
			    }
			}

			if ( stack === true && !isSafari && !hasFirebug ) {
				console.log( "Stack: " + getCallers(args) );
			}
		},

		// We accept args as a 3rd parameter until the old NICK.utils.doLog() is completely
		// deprecated. This avoids us seeing doLog methods in our trace.
		debug: function( message, stack, args ) {
			this.addMessage( message, NICK_LOG_DEBUG, stack, args || arguments );
		},

		warn: function( message ) {
			this.addMessage( message, NICK_LOG_WARNING, false, arguments );
		},

		error: function( message ) {
			this.addMessage( message, NICK_LOG_ERROR, false, arguments );
		},

		info: function( message ) {
			this.addMessage( message, NICK_LOG_INFO, false, arguments );
		},

		fatal: function( message ) {
			this.addMessage( message, NICK_LOG_FATAL, false, arguments );
		}
	}
}();
