/**
 * jQuery UI : panel history
 *
 * @author  Marc Mignonsin
 * @version 2010-11-24
 *
 */

(function( $ ) {
	$.widget("ui.panelhistory", {
		// default options
		options: {		
			panelsCount : 0,
			panelsConfigs : [],
			maxTitleLength : 24,
			minItemWidth : 48
		},
		
		_create: function() {
			//window.log('ui.panelhistory._create', this.options);
			
			// --- internal configuration ---
			
			this.sliderSelector = '#slider';
			this.menuBarSelector = '#menu-bar';
			this.appNavigationSelector = '#app-navigation';
			this.menuOptionsSelector = '#menu-options';
			this.panelClass = 'panel';
			this.maskSelector = '#mask';
						
			// --- state variables ---
			
			this.uiHistory = this.element;
			
			this.panelsCount = this.options.panelsCount;
			this.panelsConfigs = this.options.panelsConfigs;
			this.index = [];
			
			// ---- init ---
			
			this._bindHistoryEvents();
		},
		
		_bindHistoryEvents: function() {
			//window.log('uipanelhistory._bindHistoryEvents');
			
			// history layout
			this.uiHistory.bind('history-layout', delegate(this, function(eventObject){
				this._doLayout();
			}));
			
			// disable/enable
			this.uiHistory.bind('history-disable', delegate(this, function(eventObject){
				this.disable();
			}));
			this.uiHistory.bind('history-enable', delegate(this, function(eventObject){
				this.enable();
			}));
			
			// history destruction
			this.uiHistory.bind('history-destroy', delegate(this, function(eventObject){
				this.destroy();
			}));
		},
		
		_getIndex: function(panelID) {
			//window.log('uipanelhistory._getIndex', arguments);
			
			var index = this.index[panelID];
			if (typeof index == 'undefined')		
			{
				/*window.warn('History: panel ID='+panelID+' not found!');
				window.warn(this.panelsConfigs);
				window.warn(this.index);*/
				return null;
			}
			
			//window.log('Index found: '+index);
			return index;
		},
		
		_buildDocumentTitle: function() {
		    //window.log('uipanelhistory._buildDocumentTitle', arguments);
		    var docTitle = '';
		    for (var i=this.panelsConfigs.length-1; i>0; i--)
		    {
		        docTitle += this.panelsConfigs[i].title + ' > ';
		    }
		    if (this.panelsConfigs.length > 0)
		    {
		    	docTitle += this.panelsConfigs[0].title;
		    }
		    document.title = docTitle;
		},
		
		_doLayout: function() {
			//window.log('uipanelhistory._doLayout', arguments);
			var maxWidth = $(this.menuBarSelector).width() - $(this.menuOptionsSelector).width();
			$(this.appNavigationSelector).css('max-width', maxWidth+'px');
			
			/* Firefox only*/
			//var currentWidth = $(this.appNavigationSelector).width();
			
			/* Webkit fix */
			var currentWidth = 0;
			this.uiHistory.find('li').each(function(){
				currentWidth += $(this).width();
			});
			$(this.appNavigationSelector).css('width', maxWidth+'px');

			//window.log(currentWidth, maxWidth);						
			if (currentWidth >= maxWidth)
			{
				var items2Shrink = [];
				var minItemWidth = this.options.minItemWidth, availSpaceWidth = maxWidth, itemWidth, width2Shrink = 0;
				
				this.uiHistory.find('li').each(function(){
					itemWidth = $(this).width();
					if (itemWidth > minItemWidth)
					{
						items2Shrink.push($(this));
						width2Shrink += itemWidth;
					}
					else
					{
						availSpaceWidth -= itemWidth;
					}
				});
				
				//window.log('Shrink: avail=', availSpaceWidth);
				
				if (availSpaceWidth <= minItemWidth)
				{
					window.warn('TODO: scroll!');
					return;
				}
				var shrinkRatio = availSpaceWidth / width2Shrink;
				for (var i=0, newWidth, currentItem; currentItem=items2Shrink[i]; i++)
				{
					newWidth = Math.floor(currentItem.width() * shrinkRatio);
					if (newWidth < minItemWidth) newWidth = minItemWidth;
					currentItem.css('width', newWidth+'px');
					this._doItemLayout(currentItem);
				}
			}
			else
			{
				var availSpaceWidth = maxWidth - currentWidth, maxItemWidth, self = this;
				//window.log('Expand: avail=', availSpaceWidth);
				this.uiHistory.find('li').each(function(){
					maxItemWidth = parseInt($(this).css('max-width'));
					//$(this).log();
					widthDiff = maxItemWidth - $(this).width();
					//window.log(maxItemWidth, $(this).width(), widthDiff);
					if (widthDiff > 0)
					{
						//window.log('Expand: next avail=', availSpaceWidth - widthDiff);
						if (availSpaceWidth < widthDiff) return;
						$(this).css('width', maxItemWidth+'px');
						self._doItemLayout($(this));
						availSpaceWidth -= widthDiff;
					}
				});
			}
		},
		
		_doItemLayout: function(item)
		{
			//window.log('uipanelhistory._doItemLayout', arguments);
			//item.log();
			var link = item.children('a');		
			if (item.prev('li').length == 0)
			{
				// prevent miscalculation...
				var middle = 9;
				item.css('max-width', '42px');
			}
			else 
			{
				// 20px corresponds to the right edge of the arrow, width of the active image = 11px
				link.width(item.width()-20); 
				var middle = Math.round((link.width() - 11) / 2) + parseInt(link.css('padding-left')); 
			}
			
			link.css('background-position', middle+'px bottom');			
		},
		
		add: function(config) {
			//window.log('uipanelhistory.add', arguments);			
			// update window title
			document.title = config.title + ' > ' + document.title;
			
			// crop long titles
			config.shortTitle = config.title;
			if (config.shortTitle.length > this.options.maxTitleLength)
			{
				config.shortTitle = config.shortTitle.substr(0, this.options.maxTitleLength) + '...';
			}
			
			this.panelsConfigs.push(config);
			this.index[config.ID] = this.panelsCount++;			
			
			//window.log(this.panelsCount+' panel(s)');
			//window.log(this.panelsConfigs);
			//window.log(this.index);
			
			// create new list item and new link
			var newListItem = $('<li></li>').appendTo(this.uiHistory);
			newListItem.addClass('last').prev().removeClass('last'); 
			
			if (this.panelsCount == 1)
			{
				var newLink = $('<a href="#" accesskey="h"><img src="'+config.icon+'" /></a>').addClass('icon visible-link');
				newLink.attr('id', 'panel-link-'+config.ID).attr('title', config.title).appendTo(newListItem);
			}
			else 
			{
				var newLink = $('<a href="#">'+config.shortTitle+'</a>').addClass('visible-link');
				newLink.attr('id', 'panel-link-'+config.ID).attr('title', config.title).appendTo(newListItem);
			}
			
			var sliderSelector = this.sliderSelector;
			newLink.click(function(){
				$(sliderSelector).trigger('slider-panelgoto', config.ID);
				return false;
			});
			
			var maxWidth = newListItem.width();
			newListItem.css('max-width', maxWidth+'px');
			
			this._doItemLayout(newListItem);
			this._doLayout();
						
			return this.index[config.ID];
		},
		
		updateLabel: function(panelID, newLabel) {
			//window.log('uipanelhistory.updateLabel', arguments);
			var link = $('#panel-link-'+panelID).html(newLabel).attr('title', newLabel);
			
			var listItem = link.parent('li');			
			var maxWidth = listItem.width();
			listItem.css('max-width', maxWidth+'px');
			
			this._doItemLayout(listItem);
			this._doLayout();
		},
		
		updateVisibility: function(panelID, visible) {
			//window.log('uipanelhistory.updateVisibility', arguments);			
			if (visible == true)
			{
				var link = $('#panel-link-'+panelID).addClass('visible-link');
				this._doItemLayout(link.parent('li'));
			}
			else
			{
				$('#panel-link-'+panelID).removeClass('visible-link');
			}
		},
		
		cut: function(panelID) {
			//window.log('uipanelhistory.cut', arguments);			
			var cuttedIDs = [];
			
			var targetIndex = this._getIndex(panelID);
			if (targetIndex != null)
			{
				for (var i=this.panelsCount-1; i>=targetIndex; i--)
				{			
					var currentConfig = this.panelsConfigs.pop();
					
					$('#panel-link-'+currentConfig.ID).parent().remove();
					this.panelsCount--;				
					
					cuttedIDs.push(currentConfig.ID);
				}
				
				if (targetIndex > 0)
				{
					$('#panel-link-'+this.panelsConfigs[targetIndex-1].ID).parent().addClass('last');
					
					this._doLayout();
					this._buildDocumentTitle();
				}
			}
			
			return cuttedIDs;
		},
		
		lastID: function() {
			//window.log('uipanelhistory.lastID', arguments);
			return (this.panelsCount > 0) ? this.panelsConfigs[this.panelsCount-1].ID : -1;
		},
		
		disable: function()
		{
			//window.log('uipanelhistory.disable', arguments);
			$(this.menuBarSelector).find(this.maskSelector).show();
		},
		
		enable: function()
		{
			//window.log('uipanelhistory.enable', arguments);
			$(this.menuBarSelector).find(this.maskSelector).hide();
		},

		destroy: function() {
			window.log('uipanelhistory.destroy');
			
			this._trigger('beforeDestroy', 0, this);
			
			// custom cleanup	
			this.uiHistory.unbind();
			
			delete this.panelsConfigs;
			this.panelsConfigs = null;
			
			delete this.index;
			this.index = null;
			
			// call default
			$.Widget.prototype.destroy.apply(this, arguments); 
						
			this._trigger('afterDestroy', 0, this);
		}
	});
})(jQuery);