/*
 * History Channel - Timeline
 * Greg Reed greg@pokelondon.com
 */


/*
 *	STILL TODO:
 *
 *	- currently loads data for the current period only
 *	- work on transition from one period to the next
 *
 */


/**
  * Define the History Channel Timeline
 **/
HC.timeline = {

	// LSHift JSON API vars
	jsonURL				: libraryFolder, //"/prototype-author/library/",
	mgnlUserId 			: "tester",
	mgnlUserPSWD 		: "teurivis",

	// use keyboard to control epg slider
	useKeyboard					: false,

	toggleTimelineInitState		: true, // true = closed | false = open
	toggleTimelineBtnOpenCopy	: 'open timeline',
	toggleTimelineBtnCloseCopy	: 'close timeline',

	// period and event variables
	currentEvent				: 0,
	increment					: 6,

	// event variables
	totalPeriods				: 0,
	totalEvents					: 0,

	// datetime varibles
	months						: ["January","February","March","April","May","June","July","August","September","October","November","December"],

	ajaxURL: function(page, extraParams)
	{
        login = "";

        /* Don't need login when running from server
        if (extraParams.length > 0)
            login = '&' + 'mgnlUserId='+HC.timeline.mgnlUserId+'&mgnlUserPSWD='+HC.timeline.mgnlUserPSWD+';
        */

        return HC.timeline.jsonURL+page+'?' + extraParams + login;
	},

	init : function(period){

		// basic framework of methods for timeline
		HC.timeline.getPeriodData();

		if (period == null)
		{
		    alert("Time period not set");
		}

		HC.timeline.currentPeriod = period;
	    HC.timeline.currentPeriodTitle = '';

		// inject the html framework
		HC.timeline.injectHTML();
		HC.timeline.buildFilterNav();

		// bind event clicks
		HC.timeline.bindEventHandlers();

		// init the scroller
		HC.timeline.scrollToThis(0);

		// set the default data
		HC.timeline.getEventData(defaultPeriod);

		// highlight default navs
		//var defaultPeriodLink = $('#period');
		var defaultFilterLink = $('#allEventsFilter');
		//HC.timeline.selectNav.call(defaultPeriodLink);
		HC.timeline.selectNav.call(defaultFilterLink);

		// if the timeline is hidden, hide it now
		// this must happen here of none of the values above will work
		// when the timeline property is set to hidden
		if(this.toggleTimelineInitState){
			$("#timelinewrapper").hide();
		}
	},

	injectHTML : function(){

		$("#timelinewrapper").empty();

		// inject EPG slider and programme details blocks
		$("#timelinewrapper").append("<div id=\"timelineSlider\"></div>");
		$("#timelinewrapper").append("<div id=\"detail\"></div>");

		// inject slider controls
		$("#timelineSlider").append("<div class=\"controls\"></div>");
		$("#timelineSlider").append("<div class=\"scroll\"></div>");

		// inject navigational elements (timeline, filters)
		$(".controls").append("<ul id=\"timeline\"></ul>");
		$(".controls").append("<ul id=\"filter\"></ul>");

		// inject scroll container (events listing)
		$(".scroll").append("<div class=\"scrollContainer\"></div>");

		$(".controls").append("<div id=\"nav\"><a href=\"#\" class=\"prev\"><em></em></a><a href=\"#\" class=\"next\"><em></em></a></div>");

		// inject sample event detail block elements
		$("#detail").append("<div id=\"relatedTimelineShows\">" +
								"<h2 class=\"decoratedSubHead decoratedSubHeadShort\"><span>Related Shows (<em></em>)</span></h2>" +
									"<ul>" +
									"</ul>" +
								"<!-- <a class=\"decoratedLink\" href=\"#\">See all related shows (<em></em>)</a> -->" +
							"</div>");
		$("#detail").append("<div id=\"relatedTimelineEntries\">" +
								"<h2 class=\"decoratedSubHead decoratedSubHeadShort\"><span>Related Encyclopaedia Content (<em></em>)</span></h2>" +
								"<ul>" +
								"</ul>" +
								"<a class=\"decoratedLink\" href=\"#\">See all encyclopaedia entries (<em></em>)</a>" +
							"</div>");

		if(this.toggleTimelineInitState){
			this.toggleTimelineBtnInitCopy = this.toggleTimelineBtnOpenCopy;
		} else {
			this.toggleTimelineBtnInitCopy = this.toggleTimelineBtnCloseCopy;
		}

		$("#timelinewrapper").after('<div id=\"timelineToggle\">' +
								'<a href=\"#\" class=\"closeTimeline\">'+this.toggleTimelineBtnInitCopy+'<br /><span class="currentPeriod"></span></a>' +
								'</div>');

	},

	buildTimelineNav : function(){
		// create the timeline navigation
		var totalCount = 0;
		jQuery.each(HC.timeline.periodData, function(i,val) {
			totalCount = totalCount + val.size;
			$('#timeline').append("<li id=\""+val.id+"\" class=\"period\" title=\""+val.range.start+"-"+val.range.end+" "+val.title+" <em>("+val.size+" Events)</em>\"><a href=\"#\"><span></span></a></li>");
			$('#timeline li#'+val.id).bind('click', function(){
				// TODO: fetch events for this period
				HC.timeline.currentPeriod = val.id;
				// highlight that period in the timeline
				HC.timeline.activeTimelinePeriod(val.id);
				// reset filter nav
				HC.timeline.selectNav.call($('#allEventsFilter'));
				// add loading events
				var $subcontainer = $('.scrollContainer');
				$subcontainer.empty();
				$subcontainer.html('<img class="loading" src="/docroot/images/loading.gif" alt="loading" />');
				HC.timeline.getEventData(val.id);
			});
			// tooltips
			$('#timeline li#'+val.id).hover(HC.timeline.showTooltip,HC.timeline.hideTooltip);
		});
		var $periodData = $('#timeline > .period');
		var $timeline = $('#timelinewrapper');

		HC.timeline.totalPeriods = HC.timeline.periodData.length;
		HC.timeline.totalEvents = totalCount;

		var unitWidth = $timeline.width() / HC.timeline.totalEvents;

		jQuery.each(HC.timeline.periodData, function(i,b) {
			if(Math.floor(unitWidth * b.size) == '0'){
				var w = Math.floor(unitWidth * b.size);
			} else {
				var w = Math.floor(unitWidth * b.size) - 2;
			};
			// calculate a new width for the period container
			$('#'+b.id).css({
				'width' : w
			});
		});

	},

	buildFilterNav : function(){
		// create the filter navigation - all events | key events | events with shows
		$("#filter").append("<li><a id=\"allEventsFilter\" href=\"#\"><span>All events</span></a></li><li><a id=\"keyEventsFilter\" href=\"#\"><span>Key Events</span></a></li><li><a id=\"eventsWithShowsFilter\" href=\"#\"><span>Events with Shows</span></a></li>");
	},

	bindEventHandlers : function(){
		// bind clickers
		$("a.prev").bind("click", function(e){ HC.timeline.moveSlider("prev");return false; });
		$("a.next").bind("click", function(e){ HC.timeline.moveSlider("next");return false; });

		$('.closeTimeline').click(function(e) {
			$('#timelinewrapper').slideToggle('slow',function() {
				if ($(this).is(':hidden')) {
					$('.closeTimeline').html('open timeline<br /><span>Currently in '+HC.timeline.currentPeriodTitle+'</span>');
				} else {
					HC.timeline.activeTimelinePeriod(HC.timeline.currentPeriod);
					$('.closeTimeline').html('close timeline<br /><span>Currently in '+HC.timeline.currentPeriodTitle+'</span>');
				}
			});
			return false;
		});

		// TODO: slide to beginning of period when any of these are clicked
		$("#allEventsFilter").bind("click", function(e){
			HC.timeline.selectNav.call($('#allEventsFilter'));
			$('.normal').parent().animate({opacity: 1}, 300);
			$('.noshows').parent().animate({opacity: 1}, 300);
			return false;
		});
		$("#keyEventsFilter").bind("click", function(e){
			HC.timeline.selectNav.call($('#keyEventsFilter'));
			$('.normal').parent().animate({opacity: 0.3}, 300);
			$('.noshows').parent().animate({opacity: 1}, 300);
			return false;
		});
		$("#eventsWithShowsFilter").bind("click", function(e){
			HC.timeline.selectNav.call($('#eventsWithShowsFilter'));
			$('.normal').parent().animate({opacity: 1}, 300);
			$('.noshows').parent().animate({opacity: 0.3}, 300);
			return false;
		});

		if(HC.timeline.useKeyboard){
			// bind left,right,up and down keypresses
			$(window).keydown(function (e) {

				if ((e.keyCode == 38 || e.keyCode == 39)) {
					HC.timeline.moveSlider("next");
					return false;
				}

				if ((e.keyCode == 37 || e.keyCode == 40)) {
					HC.timeline.moveSlider("prev");
					return false;
				}

			});
		}
	},

	showTooltip : function() {
		tipOffset = 90;
		this.tip = $(this).attr('title');
		$(this).append(
			'<div class="toolTip">' +
				'<p><span>'+this.tip+'</span></p>' +
			'</div>'
		);

		this.width = 280; // need to fix the width

		$(this).find('.toolTip p span').css({width:this.width});
		$(this).find('.toolTip').css({right:(($(this).width() / 2) - 8) - (this.width / 2),top:-18});
		$('.toolTip').show();
	},

	hideTooltip : function() {
		$('.toolTip').remove();
	},

	moveSlider : function(e) {

		// setup the scroll object
	    var $scroll = $('#timelineSlider .scroll').css('overflow', 'hidden');

		// scroll events - trigger hightlight on bucket change
		if(e == 'prev'){
			if(HC.timeline.currentEvent > 0){
				if(HC.timeline.currentEventsArray.length < (HC.timeline.increment * 2)){
					HC.timeline.currentEvent = 0;
				} else {
					HC.timeline.currentEvent = HC.timeline.currentEvent - HC.timeline.increment;
				}
				HC.timeline.scrollToThis('#event_'+HC.timeline.currentEventsArray[HC.timeline.currentEvent]);
			} else {
				var periodIndex = HC.timeline.currentPeriodsArray.indexOf(HC.timeline.currentPeriod) - 1;
				// load prev period
				if(periodIndex > 1) {
					HC.timeline.currentPeriod = HC.timeline.currentPeriodsArray[periodIndex];
					// highlight that period in the timeline
					HC.timeline.activeTimelinePeriod(HC.timeline.currentPeriod);
					// add events
					var $subcontainer = $('.scrollContainer');
					$subcontainer.empty();
					$subcontainer.html('<img class="loading" src="/docroot/images/loading.gif" alt="loading" />');
					HC.timeline.getEventData(HC.timeline.currentPeriod);
				}
			}
		}
		if(e == 'next'){
			if(HC.timeline.currentEvent < (HC.timeline.currentEventsArray.length - HC.timeline.increment)){
				if(HC.timeline.currentEventsArray.length < (HC.timeline.increment * 2)){
					HC.timeline.currentEvent = parseInt(HC.timeline.currentEventsArray.length - HC.timeline.increment);
				} else {
					HC.timeline.currentEvent = HC.timeline.currentEvent + HC.timeline.increment;
				}
				HC.timeline.scrollToThis('#event_'+HC.timeline.currentEventsArray[HC.timeline.currentEvent]);
			} else {
				var periodIndex = HC.timeline.currentPeriodsArray.indexOf(HC.timeline.currentPeriod) + 1;
				// load next period
				if(periodIndex < HC.timeline.totalPeriods) {
					HC.timeline.currentPeriod = HC.timeline.currentPeriodsArray[periodIndex];
					// highlight that period in the timeline
					HC.timeline.activeTimelinePeriod(HC.timeline.currentPeriod);
					// add events
					var $subcontainer = $('.scrollContainer');
					$subcontainer.empty();
					$subcontainer.html('<img class="loading" src="/docroot/images/loading.gif" alt="loading" />');
					HC.timeline.getEventData(HC.timeline.currentPeriod);
				}
			}
		}

	},

	scrollToThis : function(value) {
		// set the scroller and trigger the scrollTo action
		var $scroll = $('#timelineSlider .scroll').css('overflow', 'hidden');
		$scroll.stop().scrollTo( value, 500, {easing:'swing'});
	},

	// generic ul nav selection method
    selectNav : function () {
 		$(this)
            .parents('ul:first')
                .find('a')
                    .removeClass('selected')
                .end()
            .end()
			// select the nav item
            .addClass('selected');
    },

	getPeriodData : function() {
		// LShift API implementation
		$.ajax({
			url: HC.timeline.ajaxURL('periodsJSON.js', 'function=HC.timeline.periodsCallBack'),
			type: 'GET',
		    dataType: 'jsonp'/*,
			timeout: 1000*/
		});
	},

	getEventData : function(id){
		HC.timeline.currentPeriod = id;
		// LShift API implementation
		$.ajax({
			url: HC.timeline.ajaxURL('eventsJSON.js', 'function=HC.timeline.eventsCallBack&periods='+id),
			type: 'GET',
		    dataType: 'jsonp'/*,
			timeout: 1000*/
		});
	},

	periodsCallBack: function(e){
		// catch the JSONP for periods
		HC.timeline.periodData = e;
		HC.timeline.currentPeriodsArray = [];
		for(i = 0;i < e.length;i++){
			HC.timeline.currentPeriodsArray.push(e[i].id);
		};
		HC.timeline.buildTimelineNav(HC.timeline.periodData);
	},

	eventsCallBack: function(e){
		// catch the JSONP for events
		HC.timeline.currentEventsArray = [];
		for(i = 0;i < e.length;i++){
			HC.timeline.currentEventsArray.push(e[i].id);
		};

		HC.timeline.addEvents(e);
	},

	addEvents : function (data){
		// to scroll to end you don't want to scroll to the last item, rather, last item - 5
		var scrollOffset = 5;

		var $controls = $('.controls');

		$('.dateRange').remove();

		jQuery.each(HC.timeline.periodData, function(i, val) {
			if(HC.timeline.currentPeriod == val.id){
				// highlight current period in timeline
				// HC.timeline.activeTimelinePeriod(val.id);
				// set the period title
				HC.timeline.currentPeriodTitle = val.title;
				$('.currentPeriod').html('Currently in '+val.title);
				dateRange = '<span>'+val.range.start+' - '+val.range.end+'</span> '+val.title;
			}
		});

		if(data.length <= HC.timeline.increment){
			$controls.append("<div class=\"dateRange\">"+dateRange+"</div>");
		} else {
			$controls.append("<div class=\"dateRange\"><a href=\"#\" class=\"rangeStart\">start</a> "+dateRange+" <a href=\"#\" class=\"rangeEnd\">end</a></div>");
		}

		// add events
		var $subcontainer = $('.scrollContainer');

		$subcontainer.empty();

		$subcontainer.append("<div id=\"period_"+HC.timeline.currentPeriod+"\" class=\"period\"></div>");
		var $eventpanel = $('#period_'+HC.timeline.currentPeriod);

		$eventpanel.append("<ul id=\"events\"></ul>");

		var $events = $('#period_'+HC.timeline.currentPeriod+' ul');

		$eventpanel.hide();

		jQuery.each(data, function(i, val) {
			// convert timestamp date
			d = new Date(parseInt(val.date));
			$events.append("<li id=\"event_"+val.id+"\" class=\"event\"><a href=\"#\" rel=\""+val.id+"\"><span class=\"time\">"+HC.timeline.formatTime(d)+"</span><span class=\"eventImage\"><img src=\""+val.image+"\"><span class=\"\"></span></span><span class=\"title\">"+val.title+"</span></a></li>");

			var $el 	= $('#event_'+val.id+' a');
			var $elimg 	= $('li#event_'+val.id+' a .eventImage');

			$elimg.animate({opacity: 0.3}, 0);
			if(val.isKeyEvent){
				$el.addClass("key");
			} else {
				$el.addClass("normal");
			}
			if(val.relatedShows.length > 0){
				$el.addClass("show");
			} else {
				$el.addClass("noshows");
			}
			$el.bind('click', function(){
				HC.timeline.updateEventDetails(val);
				$('li').removeClass('selected');
				$('.eventImage > span').removeClass('imgBorderActive');
				$('li#event_'+val.id).addClass('selected');
				$('a .eventImage').animate({opacity: 0.7}, 100);
				$('li#event_'+val.id+' a .eventImage').animate({opacity: 1}, 100);
				$('li#event_'+val.id+' a .eventImage span').addClass('imgBorderActive');
				return false;
			});

		});

		$eventpanel.fadeIn("slow");

		var $subpanels = $('li.period');

		$events = $('.event');

		// calculate a new width for the period container
		$subcontainer.css({
			'width' : (200 * $events.length)
		});

		// hightlight the current event
		$('li#event_'+data[0].id+' a').click();

		// generate click events for the start end ranges
		$(".rangeStart").click(function(e) {
				HC.timeline.scrollToThis($("#event_"+data[0].id));
				HC.timeline.currentEvent = 0;
				return false;
		});
		$(".rangeEnd").click(function(e) {
				var l = data.length - 1;
				var endOfScroll = l - scrollOffset;
				HC.timeline.scrollToThis($("#event_"+data[endOfScroll].id));
				HC.timeline.currentEvent = endOfScroll;
				return false;
		});

		// reset current Event
		HC.timeline.currentEvent = 0;

		// scrollTo the correct period pane
		HC.timeline.scrollToThis(HC.timeline.currentEvent);

	},

	// trigger a mouseover on the current bucket
	activeTimelinePeriod : function (periodId) {
		$('.toolTipPeriod').remove();
		$('.period').removeClass('active');
		$('#'+periodId).addClass('active');

		tipOffset = 90;
		tip = $('#'+periodId).attr('title');
		$('#'+periodId).append(
			'<div class="toolTipPeriod">' +
				'<p><span>'+tip+'</p></span>' +
			'</div>'
		);

		tipwidth = 280; // need to fix the width

		var w = $('#'+periodId).css('width');
		w = parseInt(w.replace(/px/g, ""));

		$('#'+periodId).find('.toolTipPeriod p span').css({width:tipwidth});
		$('#'+periodId).find('.toolTipPeriod').css({right:((w / 2) - 8) - (tipwidth / 2),top:-18});
		$('.toolTipPeriod').fadeIn(0);

	},

	updateEventDetails: function(obj) {
		// related Shows
		$('#detail #relatedTimelineShows ul').empty();
		if(obj.relatedShows.length > 0) {
			$('#detail #relatedTimelineShows').show();
			for(i=0;(i < obj.relatedShows.length) && (i < 3);i++){
				$('#detail #relatedTimelineShows ul').append(
					"<li>" +
						"<a href=\""+obj.relatedShows[i].url+"\" title=\"\"><img src=\""+obj.relatedShows[i].thumbnailURL+"\" alt=\""+obj.relatedShows[i].title+"\" height=\"86\" width=\"154\">" +
						""+obj.relatedShows[i].title+"</a> <a class=\"infoLightbox\" title=\"\" href=\""+obj.relatedShows[i].url+"\"><span>More Information</span></a>" +
					"</li>"
				);
			};
		} else {
			$('#detail #relatedTimelineShows').hide();
		};
		$('#detail #relatedTimelineShows a.decoratedLink').attr('href',obj.articleLink);
		$('#detail #relatedTimelineShows a.decoratedLink em').html(obj.relatedShows.length);
		$('#detail #relatedTimelineShows h2 span em').html(obj.relatedShows.length);

		// related Timeline Entries
		$('#detail #relatedTimelineEntries ul').empty();
		// add the currently selected entry to the list of related articles
		$('#detail #relatedTimelineEntries ul').append("<li><a href=\""+obj.articleLink+"\" title=\"\">"+obj.title+"</a></li>");
		if(obj.relatedArticles.length > 0) {
			for(i=0;i < 10;i++){
				$('#detail #relatedTimelineEntries ul').append("<li><a href=\""+obj.relatedArticles[i].encUrl+"\" title=\"\">"+obj.relatedArticles[i].encTitle+"</a></li>");
			};
		};
		// TODO: Generate 'See all encyclopaedia entries' link
		$('#detail #relatedTimelineEntries a.decoratedLink').attr('href',obj.articleLink);
		$('#detail #relatedTimelineEntries a.decoratedLink em').html(obj.relatedArticles.length + 1); // note the +1 to include the currently selected article
		$('#detail #relatedTimelineEntries h2 span em').html(obj.relatedArticles.length + 1); // note the +1 to include the currently selected article
		return true;
	},

	// utility time format function
	formatTime : function(date) {
        var day = date.getDate(),
            month = date.getMonth();
			year =date.getFullYear();

         //return html encoded day + month + ' ' + year;
    	return "<span class=\"day\">"+day+"</span><span class=\"month\"><sup>"+HC.timeline.months[month]+"</sup><sup>"+year+"</sup></span>";
	},

	reset : function() {

	}

};

/**
  * CACHE REQUESTS
 **/
HC.timeline.dataManager = {

	init : function() {
	},

	get : function(id) {
	},

	eventsInRange: function(){
	}

};

// initialise the TIMELINE on document load
$(document).ready(function(){
	// HC.timeline.dataManager.timelineData = timelineData; 0c11d3ff-d1eb-4f52-9555-21b9c1bb0691 | fa848fe5-f86a-4142-8c3c-90bbb2ee2564
	HC.timeline.init(window.defaultPeriod ? window.defaultPeriod : null);
});