/*jshint -W079*/

// 'use strict';

var Timetable = function() {
	this.scope = {
		hourStart: 9,
		hourEnd: 17
	};
	this.locations = TVGUIDEDATA
	this.events = TVGUIDEEVENT;
};

Timetable.Renderer = function(tt) {
	if (!(tt instanceof Timetable)) {
		throw new Error('Initialize renderer using a Timetable');
	}
	this.timetable = tt;
};

(function() {
	function isValidHourRange(start, end) {
		return isValidHour(start) && isValidHour(end);
	}
	function isValidHour(number) {
		return isInt(number) && isInHourRange(number);
	}
	function isInt(number) {
		return number === parseInt(number, 10);
	}
	function isInHourRange(number) {
		return number >= 0 && number < 24;
	}
	function locationExistsIn(loc, locs) {
		return locs.indexOf(loc) !== -1;
	}
	function isValidTimeRange(start, end) {
		var correctTypes = start instanceof Date && end instanceof Date;
		var correctOrder = start < end;
		return correctTypes && correctOrder;
	}
	function getDurationHours(startHour, endHour) {
		return endHour >= startHour ? endHour - startHour : 24 + endHour - startHour;
	}

	Timetable.prototype = {
		setScope: function(start, end) {
			if (isValidHourRange(start, end)) {
				this.scope.hourStart = start;
				this.scope.hourEnd = end;
			} else {
				throw new RangeError('Timetable scope should consist of (start, end) in whole hours from 0 to 23');
			}

			return this;
		},
		addLocations: function(name, src, desc) {
			function hasProperFormat() {
				return name instanceof Array;
			}

			var existingLocations = this.locations;

			// console.log(existingLocations);

			// if (hasProperFormat()) {
			// 	name.forEach(function(loc) {
			// 		if (!locationExistsIn(loc, existingLocations)) {
			// 			// existingLocations.push(loc);
						
			// 		} else {
			// 			throw new Error('Location already exists');
			// 		}
			// 	});
			// } else {
			// 	throw new Error('Tried to add locations in wrong format');
			// }

			this.locations.push({
				name: name,
				src: src,
				desc: desc
			});

			return this;
		},
		addEvent: function(name, desc, location, start, end, options) {
			// if (!locationExistsIn(location, this.locations)) {
			// 	throw new Error('Unknown location');
			// }
			if (!isValidTimeRange(start, end)) {
				throw new Error('Invalid time range: ' + JSON.stringify([start, end]));
			}

			var optionsHasValidType = Object.prototype.toString.call(options) === '[object Object]';
			var locate = timetable.locations;

			this.events.push({
				name: name,
				desc: desc,
				location: location,
				startDate: start,
				endDate: end,
				options: optionsHasValidType ? options : undefined
			});

			return this;
		}
	};

	function emptyNode(node) {
		while (node.firstChild) {
			node.removeChild(node.firstChild);
		}
	}

	function prettyFormatHour(hour) {
		var prefix = hour < 10 ? '0' : '';
		return prefix + hour + ':00';
	}

	Timetable.Renderer.prototype = {
		draw: function(selector) {
			function checkContainerPrecondition(container) {
				if (container === null) {
					throw new Error('Timetable container not found');
				}
			}
			function appendTimetableAside(container) {
				var asideNode = container.appendChild(document.createElement('aside'));
				var asideULNode = asideNode.appendChild(document.createElement('ul'));
				asideNode.id = 'channel';

				appendRowHeaders(asideULNode);
			}
			function appendRowHeaders(ulNode) {
				var liSpace = ulNode.appendChild(document.createElement('li'));
				$(liSpace).attr('data-category', '');
				liSpace.className = 'aside__li__space';
				for (var k=0; k<timetable.locations.length; k++) {
					var liNode = ulNode.appendChild(document.createElement('li'));
					var imgNode = liNode.appendChild(document.createElement('img'));
					var smallNode = liNode.appendChild(document.createElement('small'));
					// var spanNode = liNode.appendChild(document.createElement('span'));
					$(liNode).attr('data-category', timetable.locations[k].channel_category_id);
					imgNode.src = timetable.locations[k].logo;
					imgNode.alt = "logo channel";
					smallNode.className = 's10';
					smallNode.textContent = timetable.locations[k].name;
					// spanNode.className = 'row-heading';
					// spanNode.textContent = timetable.locations[k].name;
					// console.log(timetable.locations[k].src);
				}
			}
			function appendTimetableSection(container) {
				var sectionNode = container.appendChild(document.createElement('section'));
				var timeNode = sectionNode.appendChild(document.createElement('time'));

				sectionNode.id = 'movie';

				appendColumnHeaders(timeNode);
				appendTimeRows(timeNode);
			}
			function appendColumnHeaders(node) {
				var headerNode = node.appendChild(document.createElement('header'));
				var headerULNode = headerNode.appendChild(document.createElement('ul'));

				var completed = false;
				var looped = false;

				for (var hour=timetable.scope.hourStart; !completed;) {
					var liNode = headerULNode.appendChild(document.createElement('li'));
					var spanNode = liNode.appendChild(document.createElement('span'));
					var smallNode = spanNode.appendChild(document.createElement('small'));
					spanNode.className = 'time-label';
					smallNode.textContent = prettyFormatHour(hour);

					if (hour === timetable.scope.hourEnd && (timetable.scope.hourStart !== timetable.scope.hourEnd || looped)) {
						completed = true;
					}
					if (++hour === 24) {
						hour = 0;
						looped = true;
					}
				}
			}
			function appendTimeRows(node) {
				var ulNode = node.appendChild(document.createElement('ul'));
				ulNode.className = 'room-timeline';
				for (var k=0; k<timetable.locations.length; k++) {
					var liNode = ulNode.appendChild(document.createElement('li'));
					$(liNode).attr('data-category', timetable.locations[k].channel_category_id);
					appendLocationEvents(timetable.locations[k], liNode);/**/
				}

				appendHourLine(ulNode);
			}
			function appendHourLine(node){
				var hourNode = node.appendChild(document.createElement('div'));

				hourNode.className = 'hourline';
			}
			function computeHourline(container){
				var containerScroll = container.querySelector('#tv-guide');
				var containerWidth = container.querySelector('.room-timeline').offsetWidth;
				var hourline = container.querySelector('.hourline');
				var now = new Date();
				var currentHour = now.getHours();
				var currentMinutes = now.getMinutes();
				var currentTimeInMinutes = (currentHour * 60) + currentMinutes;
				var timeToPixels = currentTimeInMinutes / 1440 * containerWidth;

				hourline.id = 'hour-line';

				hourline.style.left = timeToPixels + 'px';


				setTimeout(function(){
					$('#tv-guide').animate({
						scrollLeft: timeToPixels - 400 
					}, 1500);
				}, 1500);

			}
			function appendLocationEvents(location, node) {
				for (var k=0; k<timetable.events.length; k++) {
					var event = timetable.events[k];
					// console.log(location.name);
					// console.log(event.location);
					if (event.location === location.name) {
						appendEvent(event, node);
					}
				}
			}
			function appendEvent(event, node) {
				var hasOptions = event.options !== undefined;
				var hasURL, hasAdditionalClass, hasDataAttributes = false;

				if(hasOptions) {
					hasURL = (event.options.url !== undefined) ? true : false;
					hasAdditionalClass = (event.options.class !== undefined) ? true : false;
					hasDataAttributes = (event.options.data !== undefined) ? true : false;
				}

				var elementType = hasURL ? 'a' : 'span';
				var aNode = node.appendChild(document.createElement(elementType));
				var spanNodeTitle = aNode.appendChild(document.createElement('span'));
				var spanNodeDesc = aNode.appendChild(document.createElement('span'));
				spanNodeTitle.className = 'programme__title';
				spanNodeDesc.className = 'programme__desc';
				aNode.title = event.name;

				if (hasURL) {
					aNode.href = event.options.url;
				}
				// console.log(event.options)
				if(hasDataAttributes){
					for (var key in event.options.data) {
						aNode.setAttribute('data-'+key, event.options.data[key]);
					}
				}

				aNode.className = hasAdditionalClass ? 'time-entry ' + event.options.class : 'time-entry';
				aNode.style.width = computeEventBlockWidth(event);
				aNode.style.left = computeEventBlockOffset(event);
				spanNodeTitle.textContent = event.name;
				spanNodeDesc.textContent = event.desc;
			}
			function computeEventBlockWidth(event) {
				var start = event.startDate;
				var end = event.endDate;
				var durationHours = computeDurationInHours(start, end);
				return durationHours / 24 * 100 + '%';
			}
			function computeDurationInHours(start, end) {
				return (end.getTime() - start.getTime()) / 1000 / 60 / 60;
			}
			function computeEventBlockOffset(event) {
				var scopeStartHours = timetable.scope.hourStart;
				var eventStartHours = event.startDate.getHours() + (event.startDate.getMinutes() / 60);
				var hoursBeforeEvent =  getDurationHours(scopeStartHours, eventStartHours);
				return hoursBeforeEvent / 24 * 100 + '%';
			}

			var timetable = this.timetable;
			var scopeDurationHours = getDurationHours(timetable.scope.hourStart, timetable.scope.hourEnd);
			var container = document.querySelector(selector);
			checkContainerPrecondition(container);
			emptyNode(container);
			appendTimetableAside(container);
			appendTimetableSection(container);


			computeHourline(container);
			// setInterval(function(){ 
			// 	computeHourline(container); 
			// }, 1000 * 60);
		}
	};

})();
