timeline.js

angular.module('homepage').
directive('timeline', function () {
	function timelineLinkerFn(scope, element, attributes) {}

    return {
		controller: 'TimelineController',
		link: timelineLinkerFn,
		restrict: 'E',
		replace: true,
		scope: {
			data: '=',
			isDemo: '='
		},
		transclude: true,
		templateUrl: 'components/content-components/timeline/timeline.html'
	};
}).
controller('TimelineController',
function ($rootScope, $scope, $timeout, DataStoreSrvc, GlobalDataService, ProcessTimelineService,
	TemplateService, TimelineService) {
	console.log('TimelineController called()');

	// Assigned reference of Timeline service object,
	// so that this would get auto updated whenever data in the service changes
	$scope.timelineItems = DataStoreSrvc.getPosts();
	$scope.habitItems = DataStoreSrvc.getHabits();
	$scope.isLoading = TimelineService.getLoadingStatus();
	if($scope.isDemo) {
		// Set demo dates to 7th Nov 2016 (Monday)
		var date = new Date(1478525916000);
		GlobalDataService.setSelectedDate(date);
	}
	$scope.currentDate = GlobalDataService.getSelectedDate();

	/**
	 * Change date globally updating widgets, timeline and sidebar items as per new date
	 * @param  {Number} value the number of days the current date is shifted
	 */
	$scope.changeDate = function (value) {
		if(!$scope.isDemo) {
			$scope.currentDate.setDate($scope.currentDate.getDate() + value);
			GlobalDataService.setSelectedDate($scope.currentDate);
			TemplateService.getTemplates();
			DataStoreSrvc.updateAll();
		}
	};

	/**
	 * Set sort order to reverse of current sort order
	 * and reverse timeline items
	 */
	$scope.reverseItems = function () {
		TimelineService.setSortOrder();
		DataStoreSrvc.updateAll();
	};
}).
factory('ProcessTimelineService', function (DateUtility, TimelineService) {
	// Arranges templates in ascending order
	// Process location templates
	// Items are reveresed using UI filter
	function processTimeline(templates) {
		if(templates && templates.length) {
			processLocationTemplate(templates);
		}

		sortOrder = TimelineService.getSortOrder();
		if(sortOrder === 'ASCDG') {
			// sort timeline items in ascending order
			templates.sort(function(a, b) {
				return parseFloat(a.timestamp) - parseFloat(b.timestamp);
			});
		}
		else if(sortOrder === 'DSCDG') {
			// sort timeline items in decending order
			templates.sort(function(a, b) {
				return parseFloat(b.timestamp) - parseFloat(a.timestamp);
			});
		}
	}

	/**
	 * set location attibutes if location template is found
	 */
	function processLocationTemplate(templates) {
		var isLocationInfoAvailable = false;

		// sort post items in acending order
		templates.sort(function(a, b) {
			return parseFloat(a.latertime) - parseFloat(b.latertime);
		});

		for(var index = 0; index<templates.length; index++) {
			var post = templates[index];

			if(post.type === 'PLCS') {
				isLocationInfoAvailable = true;
				post.isInSameLocation = false;
				post.isLocationInfoAvailable = isLocationInfoAvailable;
			}
			else {
				post.isInSameLocation = true;
				post.isLocationInfoAvailable = isLocationInfoAvailable;
			}

			post.timestamp = getTimestamp(post.timestamp, post.latertime);
			post.humantime = DateUtility.getTimeStr(post.timestamp);
			post.humandate = DateUtility.getDateStr(post.timestamp);
		}

		return (index);
	}

	/**
	 * Select timestamp from timestamp and latertime
	 * @param  {Number} timestamp date at which snippet was submitted
	 * @param  {Number} latertime past time selected from date-time picker
	 * @return {Number}           time to be used for ordering timeline items
	 */
	function getTimestamp(timestamp, latertime) {
		// If difference greater than 5min, return latertime
		var diff = Math.abs(timestamp - latertime) / 1000;
		if(diff > (5 * 60)) {
			return latertime;
		}
		return timestamp;
	}

	// Get location data based on location object passed
	function getLocationInfo(item) {
		return {
			type: 'PLCS',
			locntype: item.locntype,
			timestamp: item.time.checkin,
			humandate: DateUtility.getDateStr(item.time.checkin),
			humantime: DateUtility.getTimeStr(item.time.checkin),
			data: { title: item.name, source: item.source }
		};
	}

	return {
		processTimeline: processTimeline
	};
});