/* ********************
 * SINGLETON: Console
 */
X.createSingleton('X.Console', function()
{
	this._created = false;
    this._isShown = false;
	
	this._startTime = this._lastTime = this._totalSeconds = new Date().getTime();
	
	this._messages = [];
	this._counter = 0;
	this._linkedLogs = {};
	
	this._code = '37|39|37|39';
	this._resetTimer = null;
	this._attemps = [];
	
	jQuery(document).keydown(this._onKeyDown.delegate(this));
	
	return this;
},
{
    // one to one log linking
    log: function(message, id)
	{
	    var now = new Date().getTime();
	    if (id) { this._linkLog(id, now); }
	    var seconds = (now - this._lastTime) / 1000;
	    this._totalSeconds = (now - this._startTime) / 1000;
	    
	    var colorCss = '';
	    var borderTopCss = '';
	    var borderBottomCss = '';
	    var linkedLog = this._linkedLogs[id];
	    
		var classes = [];
		classes[classes.length] = (this._counter%2 === 0)? 'even' : 'odd';
		if (this._counter === 0) { classes[classes.length] = 'first'; }
		
		if (linkedLog)
	    {
	        classes[classes.length] = 'linked';
			classes[classes.length] = (linkedLog.stop)? 'linked-stop' : 'linked-start';
	    }
		
	    var item = ['<li class="' + classes.join(' ') + '">' + (++this._counter) + ') [' + seconds + ' secs, total: ' + this._totalSeconds + ' secs'];
	    if (linkedLog && linkedLog.stop)
	    {
	        item[item.length] = ', linked: ' + ((linkedLog.stop - linkedLog.start)/1000) + ' secs';
	    }
	    item[item.length] = ']<br /> - ' + message + '</li>';
		
		var html = item.join('');
		
	    this._lastTime = now;
	    
	    this._messages.push(html);
	    
	    if (this._isShown)
	    {
			var $container = jQuery('#xconsole');
			$container.find('> .header > .total').text('total: ' + this._totalSeconds + ' secs');
			$container.find('> .items > ul').append(html);
	    }
	    
		return this;
	},
	show: function()
	{
		if (this._isShown) { return; }
	    
		var $container;
		if (!this._created)
	    {
			this._created = true;
			
	        var html = [];
	        html.push('<div id="xconsole">');
	        html.push(' <div class="header">');
	        html.push('     <div class="total">total: 0 secs</div>');
	        html.push('     <a href="#" class="close"><span>x</span></a>');
	        html.push(' </div>');
	        html.push(' <div class="items">');
	        html.push('     <ul></ul>');
	        html.push(' </div>');
	        html.push('</div>');
	        
	        $container = jQuery(html.join('')).appendTo(document.body).bgiframe();
	        $container.find('> .header > a.close').click(this._onCloseClick.delegate(this));
	    }
		else
		{
			$container = jQuery('#xconsole');
		}

		if (this._messages.length > 0)
		{
			$container.find('> .header > .total').text('total: ' + this._totalSeconds + ' secs');
			$container.find('> .items > ul').html(this._messages.join(''));
		}
		$container.show('fast');
		
		this._isShown = true;
	},
	
	hide: function()
	{
	    if (!this._created || !this._isShown) { return; }
	    jQuery('#xconsole').hide();
	    this._isShown = false;
	},
    
    deleteLinkedLog: function(id)
    {
        if (!id || !this._linkedLogs[id]) { return; }
        delete this._linkedLogs[id];
    },
    
    _linkLog: function(id, timestamp)
    {
        if (!this._linkedLogs[id])
        {
            this._linkedLogs[id] = { start: timestamp, stop: 0 };
        }
        else
        {
            // can only link to log entries - so delete it
            if (this._linkedLogs[id].stop)
            {
                this.deleteLinkedLog();
            }
            this._linkedLogs[id].stop = timestamp;
        }
    },
    
    _onKeyDown: function(evt)
    {
        if (this._isShown) { return; }
        
        var key = (evt.charCode)? evt.charCode : (evt.keyCode)? evt.keyCode : 0;
        //if (window.console) { window.console.log(evt.shiftKey +':'+key+','+this._attemps.join('|')); }
        if (evt.ctrlKey && this._isInCode(key))
        {
            this._attemps.push(key);
            
            if (this._isValidCode())
            {
                this._reset();
                this.show();
            }
        }
        this._startReset();
    },
	_onCloseClick: function(evt)
	{
		evt.preventDefault();
		this.hide();
	},
    _startReset: function()
    {
        if (this._resetTimer)
        {
            clearTimeout(this._resetTimer);
            this._resetTimer = null;
        }
        this._resetTimer = setTimeout(this._reset.delegate(this), 500);
    },
    _reset: function()
    {
        this._attemps = [];
    },
    
    _isInCode: function(key)
    {
        return (('|'+this._code+'|').indexOf('|'+key+'|') > -1);
    },
    
    _isValidCode: function()
    {
        return (this._attemps.join('|') === this._code);
    }
});