var initialize = function() {
	
	
		votingManager = new VotingManager();
}

window.addEvent('domready', function(event) {
	initialize();
});

EPISODES = [
	{
		name: 'Agents of Cracked',
		shortName: 'Agents of...',
		description: 'Michael and Daniel are Agents of Cracked.',
		url: 'http://www.youtube.com/show/agentsofcracked',
		duration: 434,
		durationString: '07:14',
		imageUrl: 'http://content1.episodic.com/assets/480/a107738.jpg',
		carouselImageUrl: 'images/aoc_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgv7z5v43qbl%2Fconfig.xml',
		id: 1,
		analyticsId: 2,
		votingId: 'PDI_answer13907332'
	},
	{
		name: 'Anyone But Me',
		shortName: 'Anyone But Me',
		description: 'New York teens coming of age in a post-9/11 world.',
		url: 'http://www.anyonebutmeseries.com/',
		duration: 844,
		durationString: '14:04',
		imageUrl: 'http://content1.episodic.com/assets/480/a107744.jpg',
		carouselImageUrl: 'images/anyone-but_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgx641qwzhmr%2Fconfig.xml',
		id: 2,
		analyticsId: 1,
		votingId: 'PDI_answer13907333'
	},
	{
		name: 'The Legend of Neil',
		shortName: 'Legend of Neil',
		description: 'Comedy series based on the Legend of Zelda.',
		url: 'http://effinfunny.com/legend-of-neil',
		duration: 562,
		durationString: '09:22',
		imageUrl: 'http://content1.episodic.com/assets/480/a107743.jpg',
		carouselImageUrl: 'images/lon_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgyx09nq69l0%2Fconfig.xml',
		id: 3,
		analyticsId: 3,
		votingId: 'PDI_answer13907339'
	},
	{
		name: 'Elevator',
		shortName: 'Elevator',
		description: 'The elevator: a place to stand uncomfortably close to whoever enters the car.',
		url: 'http://www.youtube.com/user/ElevatorShow',
		duration: 42,
		durationString: '00:42',
		imageUrl: 'http://content1.episodic.com/assets/480/a107747.jpg',
		carouselImageUrl: 'images/elev_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgv866f2jkea%2Fconfig.xml',
		id: 4,
		analyticsId: 4,
		votingId: 'PDI_answer13907335'
	},
	{
		name: 'Noob',
		shortName: 'Noob',
		description: 'A French series about a band of online gamers.',
		url: 'http://noob-tv.com/',
		duration: 910,
		durationString: '15:10',
		imageUrl: 'http://content1.episodic.com/assets/480/a107748.jpg',
		carouselImageUrl: 'images/noob_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgv7f7nv4kjl%2Fconfig.xml',
		id: 5,
		analyticsId: 5,
		votingId: 'PDI_answer13907336'
	},
	{
		name: 'Star-ving',
		shortName: 'Star-ving',
		description: 'Dave & Corin will do anything to get back on top.',
		url: 'http://crackle.com/c/Star-ving',
		duration: 469,
		durationString: '07:49',
		imageUrl: 'http://content1.episodic.com/assets/480/a107745.jpg',
		carouselImageUrl: 'images/starving_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgx5bjqufqx0%2Fconfig.xml',
		id: 6,
		analyticsId: 6,
		votingId: 'PDI_answer13907337'
	},
	{
		name: 'The Totally Rad Show',
		shortName: 'Totally Rad',
		description: 'The summer blockbuster of geek news shows.',
		url: 'http://www.totallyradshow.com',
		duration: 471,
		durationString: '07:51',
		imageUrl: 'http://content1.episodic.com/assets/480/a107739.jpg',
		carouselImageUrl: 'images/trs_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fphl065u35amr%2Fconfig.xml',
		id: 7,
		analyticsId: 7,
		votingId: 'PDI_answer13907340'
	},
	{
		name: 'Dorm Life',
		shortName: 'Dorm Life',
		description: 'This isn\'t real life. This is Dorm Life.',
		url: 'http://dorm-life.com',
		duration: 532,
		durationString: '08:52',
		imageUrl: 'http://content1.episodic.com/assets/480/a107740.jpg',
		carouselImageUrl: 'images/dorm_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgx6iyfbn7d1%2Fconfig.xml',
		id: 8,
		analyticsId: 8,
		votingId: 'PDI_answer1390733'
	},
	{
		name: 'The Young Turks',
		shortName: 'Young Turks',
		description: 'The first nationwide liberal talk show.',
		url: 'http://www.theyoungturks.com/',
		duration: 183,
		durationString: '03:02',
		imageUrl: 'http://content1.episodic.com/assets/480/a107741.jpg',
		carouselImageUrl: 'images/turks_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgvkycek7gn6%2Fconfig.xml',
		id: 9,
		analyticsId: 9,
		votingId: 'PDI_answer13907341'
	},
	{
		name: 'The Guild',
		shortName: 'The Guild',
		description: 'A web series about a group of online gamers: Over 10 million served!',
		url: 'http://watchtheguild.com',
		duration: 500,
		durationString: '08:20',
		imageUrl: 'http://content1.episodic.com/assets/480/a107746.jpg',
		carouselImageUrl: 'images/the-guild_thumb.png',
		configXmlUrl: 'http%3A%2F%2Fcdn.episodic.com%2Fshows%2Fpgt3ejsgtw5d%2Fpgvphgajfjlv%2Fconfig.xml',
		id: 10,
		analyticsId: 10,
		votingId: 'PDI_answer13907338'
	}
]

VotingManager = new Class({
	Implements: [Options, Events],
	initialize: function(options) {
		this.setOptions(options);
		this.bootstrapElements();
	},
	bootstrapElements: function() {
		this.episodeList = $('related_episodes');
		this.populateEpisodeList();
		// this.carousel = new Carousel({
		// 	container: this.episodeList,
		// 	opacity: 1,
		// 	scrollSetLength: 3
		// });

		var _this = this;
		
		this.relatedEpisodes = $$('#related_episodes li img');
		this.relatedEpisodes.addEvent('mouseover', function(event) {
			_this.handleRelatedEpisodeMouseOver(event);
		});
		this.relatedEpisodes.addEvent('mouseout', function(event) {
			_this.handleRelatedEpisodeMouseOut(event);
		});
		
		this.relatedEpisodes.addEvent('click', function(event) {
			_this.handleRelatedEpisodeClick(event);
		});
		
		this.votingButtons = $$('#related_episodes a');
		this.votingButtons.addEvent('click', function(event) {
			_this.handleVotingClick(event);
		});
		
		this.closeModal = $('keep_watching');
		if (this.closeModal) {
			this.closeModal.addEvent('click', function(event) {
				_this.dismissVotingModal(event);
			});
		}
		
		this.voteButton = $$('.pds-votebutton')[0];
		this.votingResult = $('overlay');
		this.player = $('ep_player');
		this.loadingMessage = $('loading_message');
		this.loadingMessageWrapper = $('loading_message_wrapper');

		this.timelines = {};
		
		this.episodeTitleBar = $$('#player_meta h2')[0];
		this.originalTitleText = this.episodeTitleBar.innerHTML;
		
		this.episodeCarousel = $('episode_carousel');
		// if (this.episodeCarousel) {
		// 	this.episodeCarousel.addEvent('mouseout', function(event) {
		// 		var from = event.getRelatedTarget() || event.getFromElement();
		// 		if (from && ((from.getParent && from.getParent('#episode_carousel') != null) || (from.get && from.get('tag') == 'h2') || (from.getParent && from.getParent('h2') != null))) {
		// 			return;
		// 		}
		// 		_this.resetTitle(event);
		// 	});
		// }
		// 
		// if (this.episodeTitleBar) {
		// 	this.episodeTitleBar.addEvent('mouseout', function(event) {
		// 		var from = event.getRelatedTarget() || event.getFromElement();
		// 		if (from && from.getParent && from.getParent('h2') != null) {
		// 			return;
		// 		}
		// 		_this.resetTitle(event);
		// 	});
		// }
		
		this.analyticsForm = $('analytics_form');
		if (this.analyticsForm) {
			this.analyticsForm.getElements('select').addEvent('change', function() {
				_this.updateAnalytics();
			});
			this.analyticsImg = $$('#chart img')[0];
		}
		
		this.currentEpisode = EPISODES[0]
	},
	resetTitle: function(event) {
		this.episodeTitleBar.innerHTML = this.originalTitleText;
	},
	populateEpisodeList: function() {
		var shuffle = function(o) {
			for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
			return o;
		};
		
		var _this = this;
		var episodes = shuffle(EPISODES);
		episodes.forEach(function(item, index) {
			var episodeItem = new Element('li', {
				id: ('episode_' + item.id)
			});
			var episodeImg = new Element('img', {
				src: item.carouselImageUrl
			});
			var episodeTitle = new Element('small', {
				html: ('<span>' + item.shortName + '</span> (' + item.durationString + ')')
			});
			var voteButton = new Element('a', {
				href: '#'
				});
			var playImg = new Element('img', {
				src: 'images/btn-play-big.png',
				'class': 'play-button'
			})
			
			episodeItem.adopt([episodeImg, episodeTitle, voteButton, playImg]);
			_this.episodeList.adopt(episodeItem);
		});
	},
	getEpisodeById: function(id) {
		for (var i = 0; i < EPISODES.length; i++) {
			if (EPISODES[i].id == parseInt(id)) {
				return EPISODES[i];
			}
		}
	},
	setEpisodeTitle: function(episode) {
		this.episodeTitleBar.innerHTML =  episode.name + ' (' + episode.durationString + ') - ' + episode.description;
	},
	handleRelatedEpisodeMouseOver: function(event) {
		this.getTarget(event.getTarget(), 'li').addClass('hovered');
		//this.setEpisodeTitle(this.getEpisodeById(this.getEpisodeIdForElement(event.getTarget())));
		//clearTimeout(this.resetTitleTimeout);
	},
	handleRelatedEpisodeMouseOut: function(event) {
		this.getTarget(event.getTarget(), 'li').removeClass('hovered');
	},
	handleRelatedEpisodeClick: function(event) {
		if (event.getTarget().get('tag') == 'button') { return; }
		this.playEpisode(event);
	},
	handleVotingClick: function(event) {
		this.player.pauseVideo();
		var episode = this.getEpisodeById(this.getEpisodeIdForElement(event.getTarget()));
		$(episode.votingId).checked = true;

		this.voteButton.onclick();
		this.votingButtons.dispose();
		this.presentVotingModal(episode);
	},
	presentVotingModal: function(episode) {
		this.populateVotingModal(episode);

		this.votingResult.setStyle('display', 'block');
		this.votingResult.setStyle('left', (window.getScrollSize().x - this.votingResult.getSize().x)/2);
		$('blackout').setStyles({
			height: window.getScrollSize().y,
			width: '100%',
			display: 'block'
		});
	},
	populateVotingModal: function(episode) {
		$('voted_episode').empty();

		var ru = $('runners_up');
		ru.empty();
		
		$('voted_episode').adopt(this.generateMarkupForEpisode(episode));

		var count = 0;
		for (var episodeId in this.timelines) {
			if (parseInt(episodeId) != episode.id && count < 2) {
				count++;
				$('runners_up').adopt(this.generateMarkupForEpisode(this.getEpisodeById(episodeId)));
			}
		}
		
	},
	generateMarkupForEpisode: function(episode) {
		
		/*
		<img src="images/hayley_thumb.png" />
		<div class="checkmark">&nbsp;</div>
		<div class="meta">
			<h4><a href="#" target="_blank">Tiki Bar TV</a></h4>
			<h5 class="time">Watched <strong>01:23</strong> of <strong>04:53</strong> total.</h5>
			<h5 class="seeks"><span class="rewind">Total Rewinds:</span> <strong>5</strong><span class="fast-forward">Total Fast-Forwards:</span> <strong>3</strong></h5>
		</div>
		*/
		var outerDiv = new Element('div', { 'class': 'overlay-episode' });
		var img = new Element('img', { src: episode.carouselImageUrl });
		var checkmark = new Element('div', { 'class': 'checkmark', html: '&nbsp;' });
		var meta = new Element('div', { 'class': 'meta' });
		var title = new Element('h4');
		var titleInner = new Element('a', { href: episode.url, target: '_blank', html: episode.name });
		title.adopt(titleInner);

		var totalWatchedTime = this.getTotalTimeWatchedForEpisode(episode.id);

		if (totalWatchedTime > 0) {
			var youWatchedText = 'You watched <strong>' + this.toTime(totalWatchedTime) + '</strong> of <strong>' + episode.durationString + '</strong> total.';
		}
		else {
			var youWatchedText = 'You didn\'t watch any of this episode...';
		}

		var youWatched = new Element('h5', { html: youWatchedText, 'class': 'time' });

		var seeksText = '<span class="rewind">Total Rewinds:</span> <strong>' + this.getRewindsForEpisode(episode.id) + '</strong><span class="fast-forward">Total Fast-Forwards:</span> <strong>' + this.getFastForwardsForEpisode(episode.id) + '</strong>'
		var seeks = new Element('h5', { html: seeksText, 'class': 'seeks' });

		meta.adopt([title, youWatched,seeks])
		outerDiv.adopt([img, checkmark, meta]);

		return outerDiv;
	},
	toTime: function(secs) {
		var t = '';
		var tt = Math.floor(secs);
		
		var minutes = Math.floor(secs/60);
		var seconds = Math.floor((secs % 60));

		if (minutes < 10) minutes = '0' + minutes;
		if (seconds < 10) seconds = '0' + seconds;
		
		return minutes + ':' + seconds;
	},
	dismissVotingModal : function(event) {
		event.stop();
		$('blackout').setStyle('display', 'none')
		this.votingResult.setStyle('display', 'none');
	},
	playEpisode: function(event) {
		var episode = this.getEpisodeById(this.getEpisodeIdForElement(event.getTarget()));
		var configXmlUrl = episode.configXmlUrl;

		var handlePlayerReadyEvent = function(playerEvent) {
			if (playerEvent.name == 'ready') {
				this.loadingMessageWrapper.setStyle('display', 'none');
				this.loadingMessage.setStyle('display', 'none');
				this.player.playVideo();
			}
		}
		this.removeEvents('playerEvent')
		this.addEvent('playerEvent', handlePlayerReadyEvent);
		
		this.player.pauseVideo();
		this.loadingMessageWrapper.setStyle('display', 'block');
		
		this.loadingMessage.setStyle('display', 'block');
				
		this.currentEpisode = this.getEpisodeById(this.getEpisodeIdForElement(event.getTarget()));
		this.player.loadVideoByConfig(unescape(configXmlUrl));
		
		this.updateAnalytics();
		
		$('chart_title').innerHTML = this.currentEpisode.name;
		
		this.setEpisodeTitle(this.currentEpisode);
	},
	trackCurrentPlaybackPosition: function() {
		this.currentTime = $('ep_player').getCurrentTime();
		var currentTime = this.timeToBucket(this.currentTime);
		this.storeTimeForEpisode(this.currentEpisode.id, currentTime)
	},
	startTrackingEpisodePlayback: function() {
		this.stopTrackingEpisodePlayback();
		if (!this.timelines[this.currentEpisode.id]) {
			this.timelines[this.currentEpisode.id] = {};
		}
		var _this = this;
		var handlePlayback = function() {
			_this.trackCurrentPlaybackPosition()
		}
		this.playbackTrackerInterval = setInterval(handlePlayback, 1000);
	},
	stopTrackingEpisodePlayback: function() {
		if (this.playbackTrackerInterval) {
			clearInterval(this.playbackTrackerInterval);
		}
	},
	getTotalTimeWatchedForEpisode: function(id) {
		var allTimes = this.timelines[id];
		var timeArray = [];
		for (var time in allTimes) {
			timeArray.push(parseInt(time));
		}
		if (timeArray.length == 0) return 0;
		var sorted = timeArray.sort(function(a, b) { 
			return a - b; 
		});
		return sorted.pop();
	},
	getRewindsForEpisode: function(id) {
		if (!this.timelines[id]) return 0;
		return this.timelines[id]['rewinds'] || 0;
	},
	getFastForwardsForEpisode: function(id) {
		if (!this.timelines[id]) return 0;
		return this.timelines[id]['fastForwards'] || 0;
	},
	trackSeekEvent: function() {
		var currentTime = $('ep_player').getCurrentTime();
		var lastReportedTime = this.currentTime;
		var currentRewindCount = this.timelines[this.currentEpisode.id]['rewinds'] || 0;
		var currentFastForwardCount = this.timelines[this.currentEpisode.id]['fastForwards'] || 0;
		if (lastReportedTime > currentTime) {
			this.timelines[this.currentEpisode.id]['rewinds'] = currentRewindCount + 1;
		}
		else {
			this.timelines[this.currentEpisode.id]['fastForwards'] = currentFastForwardCount + 1;
		}
	},
	storeTimeForEpisode: function(episodeId, currentTime) {
		var ct = this.timelines[episodeId][currentTime] || 0;
		this.timelines[episodeId][currentTime] = ct + 1;
	},
	timeToBucket: function(seconds) {
		return Math.ceil(seconds);
	},
	getEpisodeIdForElement: function(element) {
		return this.getTarget(element, 'li').id.split('_')[1]
	},
	getTarget: function(element, tagName) {
		return element.get('tag') == tagName ? element : element.getParent(tagName);
	},
	updateAnalytics: function() {
		var queryString = this.analyticsForm.toQueryString() + '&video_id=' + this.currentEpisode.analyticsId;
		this.analyticsImg.src = 'http://mtstream.episodic.com/videos/gchart?' + queryString;
		
		$('jsonp').src = 'http://mtstream.episodic.com/videos/top_shows?video_id=' + this.currentEpisode.id;
	},
	updateTopShows: function(shows) {
		$('top_shows').innerHTML = 'People who liked this show also liked: ' + shows.join(', ');
	}
});

topShowsHandler = function(args) {
	votingManager.updateTopShows(args);
}

handlePlayerEvents = function(playerEvent) {
	if (playerEvent.name == 'playingStarted') {
		votingManager.startTrackingEpisodePlayback();
	}
	else if (playerEvent.name == 'paused') {
		votingManager.stopTrackingEpisodePlayback();
	}
	else if (playerEvent.name == 'seekCompleted') {
		votingManager.trackSeekEvent();
	}
	votingManager.fireEvent('playerEvent', playerEvent)
}

Event.implement({
	/**
	 * For performance reasons event.getTarget() is not extended with $. Here we provide a way to get the extened target when need.
	 */
	getTarget: function() {
		if (!this.extendedTarget)
			this.extendedTarget = $(this.target);

		return this.extendedTarget;
	},
	getRelatedTarget: function() {
		return $(this.relatedTarget);
	},
	getFromElement: function() {
		return $(this.fromElement);	
	}
});
