
var TIMELINE_INIT_MONTH = 5;

var TIMELINE_MONTH_MIN_VALUE = 1;
var TIMELINE_MONTH_MAX_VALUE = 12;

var TIMELINE_SLIDER_UPDATE_CURRENT_TIMEOUT = 200;

var TIMELINE_ANIMATE_ITEMS = false;


var Timeline = {
	__isInitialized: false,
	__pageCenter: null,
	__slider: null,
	__months: null,
	__items: null,
	__commandQueue: null,
	
	init: function()
	{
		var self = this;
		
		$(document).ready(function(){
			self.__initAtDocReady();
		});
		
		$(window).load(function(){
			self.__initAtWinReady();
		});
	},
	
	__initAtDocReady: function()
	{
		this.__commandQueue = new TimelineCommandQueue();
		this.__pageCenter = new PageCenter();
		this.__items = new TimelineItems();
	},
	
	__initAtWinReady: function()
	{
		var self = this;
		
		this.__slider = new TimelineSlider(
			TIMELINE_INIT_MONTH,
			function(month)
			{
				self.openMonth(month);
			}
		);
		
		this.__months = new TimelineMonths(
			TIMELINE_INIT_MONTH,
			function(month)
			{
				self.openMonth(month);
			}
		);
		
		this.openMonth(TIMELINE_INIT_MONTH);
		this.__slider.setMonth(TIMELINE_INIT_MONTH, true);
		
		this.__isInitialized = true;
	},
	
	nextMonth: function()
	{
		if ( this.__isInitialized )
		{
			this.__slider.nextMonth();
		}
	},
	
	previousMonth: function()
	{
		if ( this.__isInitialized )
		{
			this.__slider.previousMonth();
		}
	},
	
	openMonth: function(month)
	{
		var url = window.location;
		var anchor = url.hash.substring(1);
		var anchorValue = anchor.substring(15);
		
		if( anchorValue )
		{
			var month = anchorValue;
		}
		
		var self = this;
		this.__commandQueue.queue(function(){
			self.__actualOpenMonth(month);
		});
		
		$(document).scrollTop(0);
	},
	
	openItemOfMonth: function(month, item)
	{
		var self = this;
		this.__commandQueue.queue(function(){
			self.__actualOpenItemOfMonth(month, item);
		});
	},
	
	__actualOpenMonth: function(month)
	{
		this.__slider.setMonth(month, true);
		this.__months.setMonth(month);
		
		if ( !IS_IE ) this.__pageCenter.pinAtMaxRecordedHeight();
		
		var self = this;
		var successEvent = function()
		{
			if ( !IS_IE ) self.__pageCenter.restoreHeight();
			resizePageHandler();
			self.__commandQueue.next();
		};
		
		this.__items.openMonth(month, successEvent);
	},
	
	__actualOpenItemOfMonth: function(month, item)
	{
		this.__slider.setMonth(month, true);
		this.__months.setItemOfMonth(month, item);
		
		if ( !IS_IE ) this.__pageCenter.pinAtCurrentHeight();
		
		var self = this;
		var successEvent = function()
		{
			if ( !IS_IE ) self.__pageCenter.restoreHeight();
			resizePageHandler();
			self.__commandQueue.next();
		};
		
		this.__items.openItemOfMonth(month, item, successEvent);
	}
};
Timeline.init();


function TimelineSlider(initMonth, changeEventHandler)
{
	this.__changeEventHandler = changeEventHandler;
	this.__currentMonth = initMonth;
	this.__suppressNextChangeEvent = false;
	this.__updateCurrentTimeoutHandler = null;
	
	var self = this;
	
	this.__slider = $('#slider').slider({
		value: initMonth,
		min: TIMELINE_MONTH_MIN_VALUE,
		max: TIMELINE_MONTH_MAX_VALUE,
		animate: true,//!IS_IE6,
		slide: function(e)
		{
			self.__updateCurrentTimeout();
		},
		change: function(e)
		{
			self.__updateCurrent();
		}
	});
	
	$('#slider-month-list li').each(function(index){
		var month = index + 1;
		$(this).click(function(e){
			self.setMonth(month);
		});
	});
	
	this.setMonth(initMonth);
}
TimelineSlider.prototype = {
	constructor: TimelineSlider,
	
	getMonth: function()
	{
		return this.__slider.slider('value');
	},
	
	setMonth: function(month, suppressNextChangeEvent)
	{
		if ( month < TIMELINE_MONTH_MIN_VALUE )
		{
			month = TIMELINE_MONTH_MIN_VALUE;
		}
		if ( month > TIMELINE_MONTH_MAX_VALUE )
		{
			month = TIMELINE_MONTH_MAX_VALUE;
		}
		if ( suppressNextChangeEvent )
		{
			this.__currentMonth = month;
		}
		this.__suppressNextChangeEvent = suppressNextChangeEvent;
		this.__slider.slider('value', month);
	},
	
	nextMonth: function()
	{
		this.setMonth(this.getMonth() + 1);
	},
	
	previousMonth: function()
	{
		this.setMonth(this.getMonth() - 1);
	},
	
	__updateCurrentTimeout: function()
	{
		if ( this.__updateCurrentTimeoutHandler != null )
		{
			clearTimeout(this.__updateCurrentTimeoutHandler);
		}
		var self = this;
		this.__updateCurrentTimeoutHandler = setTimeout(
			function()
			{
				self.__updateCurrent();
				clearTimeout(self.__updateCurrentTimeoutHandler);
			},
			TIMELINE_SLIDER_UPDATE_CURRENT_TIMEOUT
		);
	},
	
	__updateCurrent: function()
	{
		this.__triggerChangeEvent();
	},
	
	__triggerChangeEvent: function()
	{
		if ( !this.__suppressNextChangeEvent )
		{
			var month = this.getMonth();
			if ( this.__currentMonth != month )
			{
				this.__changeEventHandler(month);
				this.__currentMonth = month;
			}
		}
		this.__suppressNextChangeEvent = false;
	}
};


function TimelineMonths(initMonth, changeEventHandler)
{
	this.__container = $('#timeline-months-container');
	this.__content = $('#timeline-months-content');
	
	this.__content.css('margin-left', 0);
	
	var maxMargin = this.__content.width() - this.__container.width();
	this.__marginPerMonth = maxMargin / ( TIMELINE_MONTH_MAX_VALUE - 1 );
	
	this.__content.css('margin-left', this.__calcContentMargin(initMonth) + 'px');
	
	var self = this;
	
	var maxHeight = 0;
	$('.month', this.__container)
		.each(function(index){
			var month = index + 1;
			
			$(this).click(function(e){
				if ( e.target.tagName != 'A' )
				{
					changeEventHandler(month);
				}
			});
			
			$('.links a', this).each(function(item){
				self.__bindAnchorEvent(this, month, item);
			});
			
			$('.thumbs a', this).each(function(item){
				self.__bindAnchorEvent(this, month, item);
			});
			
			maxHeight = Math.max(maxHeight, this.offsetHeight);
		})
		.height(maxHeight);
}
TimelineMonths.prototype = {
	constructor: TimelineMonths,

	setMonth: function(month)
	{
		this.__setContentMargin(month);
		this.__setActiveMonth(month);
		this.__setAllItemsOfMonthActive(month);
	},
	
	setItemOfMonth: function(month, item)
	{
		this.__setContentMargin(month);
		this.__setActiveMonth(month);
		this.__setItemOfMonthActive(month, item);
	},
	
	__bindAnchorEvent: function(a, month, item)
	{
		$(a).attr('href', 'javascript:void(0)')
			.click(function(){
				Timeline.openItemOfMonth(month, item);
			});
	},
	
	__setContentMargin: function(month)
	{
		this.__content.animate({marginLeft: this.__calcContentMargin(month)});
	},
	
	__calcContentMargin: function(month)
	{
		return -Math.round( this.__marginPerMonth * ( month - 1 ) );
	},
	
	__setActiveMonth: function(month)
	{
		$('.month', this.__container).removeClass('active');
		$('.month:eq(' + ( month - 1 ) + ')', this.__container).addClass('active');
	},
	
	__setAllItemsOfMonthActive: function(month)
	{
		this.__removeActiveItemMarkers();
		$('#month-' + month + ' li').addClass('active');
	},
	
	__setItemOfMonthActive: function(month, item)
	{
		this.__removeActiveItemMarkers();
		$('#month-link-' + month + '-' + item + ', #month-thumb-' + month + '-' + item).addClass('active');
	},
	
	__removeActiveItemMarkers: function()
	{
		$('.month .active', this.__container).removeClass('active');
	}
};


function TimelineItems()
{
	this.__element = $('#timeline-items-content');
	
	this.__hideAllItems();
}
TimelineItems.prototype = {
	constructor: TimelineItems,
	
	openMonth: function(month, successEventHandler)
	{
		this.__performChange(
			function()
			{
				$('#month-items-' + month + ' .item').show();
			},
			successEventHandler
		);
	},
	
	openItemOfMonth: function(month, item, successEventHandler)
	{
		this.__performChange(
			function()
			{
				$('#month-item-' + month + '-' + item).show();
			},
			successEventHandler
		);
	},
	
	__hideAllItems: function()
	{
		$('.item', this.__element).hide();
	},
	
	__performChange: function(afterHideEventHandler, afterShowEventHandler)
	{
		var self = this;
		this.__hide(function(){
			afterHideEventHandler();
			self.__show(afterShowEventHandler);
		});
	},
	
	__hide: function(successEventHandler)
	{
		var self = this;
		var eventHandlerWrapper = function()
		{
			self.__hideAllItems();
			self.__element.hide();
			successEventHandler();
		};
		if ( !TIMELINE_ANIMATE_ITEMS || IS_IE6 || IS_IE7 )
		{
			eventHandlerWrapper();
		}
		else
		{
			this.__element.slideUp('normal', eventHandlerWrapper);
		}
	},
	
	__show: function(successEventHandler)
	{
		if ( !TIMELINE_ANIMATE_ITEMS || IS_IE6 || IS_IE7 )
		{
			this.__element.show();
			successEventHandler();
		}
		else
		{
			this.__element.slideDown('normal', successEventHandler);
		}
	}
};


function PageCenter()
{
	this.__element = $('#center');
	this.__maxRecordedHeight = 0;
}
PageCenter.prototype = {
	constructor: PageCenter,
	
	pinAtMaxRecordedHeight: function()
	{
		var height = this.__element.height();
		if ( height > this.__maxRecordedHeight )
		{
			this.__maxRecordedHeight = height;
		}
		this.__element.height(this.__maxRecordedHeight);
	},
	
	pinAtCurrentHeight: function()
	{
		this.__element.height(this.__element.height());
	},
	
	restoreHeight: function()
	{
		this.__element.css('height', 'auto');
	}
};


function TimelineCommandQueue()
{
	this.__queue = null;
	this.__isProcessing = false;
}
TimelineCommandQueue.prototype = {
	constructor: TimelineCommandQueue,
	
	queue: function(command)
	{
		// Queue only the last added command.
		// Other not yet processed commands will be ignored this way.
		this.__queue = command;
		if ( !this.__isProcessing )
		{
			this.next();
		}
	},
	
	next: function()
	{
		this.__isProcessing = this.__queue != null;
		if ( this.__isProcessing )
		{
			var command = this.__queue;
			this.__queue = null;
			command();
		}
	}
};


var TimelineMouseWheelEventManager = {
	init: function()
	{
		var self = this;
		var handler = function(e)
		{
			self.handleEvent(e);
		};
		if ( window.addEventListener )
		{
			window.addEventListener('DOMMouseScroll', handler, false);
		}
		document.onmousewheel = handler;
	},
	
	handleEvent: function(e)
	{
		e = e || window.event;
		var target = e.target || e.srcElement;
		if ( $(target).parents('#slider-month-list, #slider, #timeline-months-container').length == 0 )
		{
			return;
		}
		var delta = 0;
		if ( e.wheelDelta )
		{
			delta = e.wheelDelta / 120;
		}
		else if ( e.detail )
		{
			delta = -e.detail / 3;
		}
		if ( $.browser.safari )
		{
			delta /= 3;
		}
		if ( delta )
		{
			this.performAction(delta);
		}
		if ( e.preventDefault )
		{
			e.preventDefault();
		}
		e.returnValue = false;
	},
	
	performAction: function(delta)
	{
		Timeline[( delta < 0 ? 'next' : 'previous' ) + 'Month']();
	}
};
TimelineMouseWheelEventManager.init();
