(function(){
	var $ = jQuery;
	var player, video, poster, videoTag, title;
	var c = {};
	uberPlayer = function(element, params){
		var _this = this;

		this.virgin = true; // untouched
		this.isplaying = false;

		params = params || {};
		player = $('#' + element);
		player.addClass('uberPlayer notselectable');
		player.css({'position': 'relative'});

		player.width(params.width);
		player.height(params.height);

		title = (typeof params.watch == 'string') ? params.watch : 'Watch the ' + params.name + ' video' || 'Watch the video';

		poster = params.poster;
		if(poster && !iosmode()){
			poster = $("<div class='poster'><img src='" + poster + "'></div>");
			player.append(poster);
			poster.find('img').bind('load', function(){
				c.bigPlay.show();
			});
		}

		video = $("<video preload='auto'></video>").hide();
		player.append(video);
		this.addSource(params.m4v);
		this.addSource(params.webm);

		if(iosmode()){
			video.attr({'controls': 'controls', 'poster': params.poster}).show();
			video.width(params.width);
			video.height(params.height);
			return false; // no need to do anything else for iPads and co
		}

		c.bigPlay = $('<div class="bigPlay">' + title + '</div>').hide();
		player.append(c.bigPlay);

		c.bigAgain = $('<div class="bigPlay bigAgain">Watch again</div>').hide();
		player.append(c.bigAgain);

		c.bar = $('<div class="panel"></div>');

		c.volume = $('<div class="volume"></div>');
		c.volumeBar = $('<div class="bar"></div>');
		c.volumeProgress = $('<div class="progress"></div>');
		c.volumeWrap = $('<div class="wrap"></div>');
		c.volumeSlider = $('<div class="slider"></div>');
		c.volumeMute = $('<div class="mute"></div>');
		c.volumeFull = $('<div class="full"></div>');
		c.volume.append(c.volumeBar.append(c.volumeProgress, c.volumeWrap.append(c.volumeSlider)), c.volumeMute, c.volumeFull);
		c.bar.append(c.volume);

		c.buttons = $('<div class="buttons"></div>');
		c.play = $('<div class="play"></div>');
		c.pause = $('<div class="pause"></div>').hide();
		c.rewind = $('<div class="rewind"></div>');
		c.forward = $('<div class="forward"></div>');
		c.buttons.append(c.play, c.pause, c.rewind, c.forward);
		c.bar.append(c.buttons);

		c.seek = $('<div class="seek"></div>');
		c.seekBar = $('<div class="bar"></div>');
		c.seekBuffer = $('<div class="buffer"></div>');
		c.seekProgress = $('<div class="progress"></div>');
		c.seekWrap = $('<div class="wrap"></div>');
		c.seekSlider = $('<div class="slider"></div>');
		c.timeCurrent = $('<div class="current">00:00</div>');
		c.timeTotal = $('<div class="total">--:--</div>');
		c.seek.append(c.timeCurrent, c.seekBar.append(c.seekBuffer, c.seekProgress, c.seekWrap.append(c.seekSlider)), c.timeTotal);
		c.bar.append(c.seek).css({'opacity': 0});

		player.append(c.bar);

		// some post append adjustments
		c.bigPlay.css({'margin-top': -c.bigPlay.outerHeight()/2, 'margin-left': -c.bigPlay.outerWidth()/2});
		c.bigAgain.css({'margin-top': -c.bigAgain.outerHeight()/2, 'margin-left': -c.bigAgain.outerWidth()/2});

		// media object events
		videoTag = video[0];
		videoTag.addEventListener('loadeddata', function(){
			if(_this.isplaying){
				poster.hide();
				video.show();
			}
		}, false);
		videoTag.addEventListener('loadedmetadata', function(){
			c.timeTotal.text(toTime(videoTag.duration));
			var temp = readCookie('volume') || videoTag.volume; // need to set the volume to something and back again for the controller to init
			videoTag.volume = videoTag.volume * 0.9;
			videoTag.volume = temp;
		}, false);
		videoTag.addEventListener('progress', function(){
			updateBufferState();
		}, false);
		videoTag.addEventListener('timeupdate', function(){
			var p = (videoTag.currentTime / videoTag.duration * 100),
				w = c.seekSlider.outerWidth() / 2;
			c.seekSlider.css({'left': p + '%'});
			c.seekProgress.width(c.seekSlider.position().left + w);
			updateBufferState();
			c.timeCurrent.text(toTime(videoTag.currentTime));
		}, false);
		videoTag.addEventListener('volumechange', function(e){
			updateVolumeState();
		}, false);
		videoTag.addEventListener('ended', function(){
			$(document).unbind('mouseup');
			$(document).unbind('mousemove');
			if(typeof params.onEnd == 'function'){
				params.onEnd();
			}
			player.trigger('mouseleave');
			_this.virgin = true;
			_this.ended = true;
			c.bigAgain.show();
			$(videoTag).hide();
			poster.show();
			_this.pause();
		}, false);

		// media control events
		player.bind('mouseenter', function(){
			if(!_this.virgin)
				c.bar.stop(false, true).fadeIn();
		});
		player.bind('mouseleave', function(){
			if(!_this.virgin)
				c.bar.stop(false, true).fadeOut();
		});
		player.bind('mousedown', function(e){ e.preventDefault(); e.stopPropagation(); return false; });
		c.bigPlay.add(c.bigAgain).bind('click', function(e){
			if(e.which !== 1) return false;
			c.bar.css({'opacity': 1});
			_this.ended = false;
			_this.virgin = false;
			$(this).hide();
			player.trigger('mouseenter');
			_this.play();
			if(videoTag.readyState){
				poster.hide();
				video.show();
			}
			return false;
		});
		c.bigAgain.bind('click', function(){
		});
		c.seekBar.bind('mousedown', function(e){
			if(e.which !== 1) return false;
			c.seekSlider.addClass('focus');
			$(document).bind('mouseup', function(){
				$(document).unbind('mouseup');
				c.seekSlider.removeClass('focus');
			});
			if(videoTag.readyState){
				_this.seekToPx(e, e.pageX - c.seekBar.offset().left);
			}
		});
		c.seekSlider.bind('mousedown', function(e){
			if(e.which !== 1) return false;
			c.seekSlider.addClass('focus');
			$(document).bind('mouseup', function(){
				$(document).unbind('mouseup');
				c.seekSlider.removeClass('focus');
			});
			if(videoTag.readyState){
				_this.seekToPx(e, c.seekSlider.position().left);
			}
		});
		c.volumeBar.bind('mousedown', function(e){
			if(e.which !== 1) return false;
			c.volumeSlider.addClass('focus');
			$(document).bind('mouseup', function(){
				$(document).unbind('mouseup');
				c.volumeSlider.removeClass('focus');
			});
			if(videoTag.readyState){
				_this.volumeToPx(e, e.pageX - c.volumeBar.offset().left);
			}
		});
		c.volumeSlider.bind('mousedown', function(e){
			if(e.which !== 1) return false;
			if(videoTag.readyState){
				_this.volumeToPx(e, c.volumeSlider.position().left);
			}
		});
		c.volumeMute.bind('mousedown', function(e){ if(e.which !== 1) return false; videoTag.volume = 0; });
		c.volumeFull.bind('mousedown', function(e){ if(e.which !== 1) return false; videoTag.volume = 1; });
		c.play.bind('mousedown', function(e){ if(e.which !== 1) return false; _this.play(); return false; });
		c.pause.bind('mousedown', function(e){ if(e.which !== 1) return false; _this.pause(); return false; });
		c.rewind.bind('mousedown', function(e){ if(e.which !== 1) return false; videoTag.currentTime -= 5; _this.play(); return false; });
		c.forward.bind('mousedown', function(e){ if(e.which !== 1) return false; videoTag.currentTime = (videoTag.currentTime + 5 < videoTag.duration) ? videoTag.currentTime + 5: videoTag.duration - 0.01; _this.play(); return false; });
	};
	uberPlayer.prototype = {
		play: function(){
			this.isplaying = true;
			videoTag.play();
			c.play.hide();
			c.pause.show();
		},
		pause: function(){
			this.isplaying = false;
			videoTag.pause();
			c.play.show();
			c.pause.hide();
		},
		addSource: function(source){
			if(source){
				video.append($("<source src='" + source + "'>"));
			}
			return this;
		},
		volumeToPx: function(e, px){
			var _this = this;
			var pageX = e.pageX,
				barX = parseInt(px, 10);

			_this.setVolume(barX / c.volumeBar.width());

			$(document).bind('mousemove', function(e){
				var diff = e.pageX - pageX + barX;
				_this.setVolume(diff / c.volumeBar.width());
			});
			$(document).bind('mouseup', function(e){
				$(document).unbind('mousemove');
				$(document).unbind('mouseup');
				var diff = e.pageX - pageX + barX;
				_this.setVolume(diff / c.volumeBar.width());
			});
		},
		setVolume: function(val){
			videoTag.volume = (val > 1) ? 1 : (val < 0) ? 0 : val;
		},
		seekToPx: function(e, px){
			var _this = this;
			var pageX = e.pageX,
				barX = parseInt(px, 10);
			videoTag.currentTime = barX * videoTag.duration / c.seekBar.width();
			_this.pause();

			$(document).bind('mousemove', function(e){
				var diff = e.pageX - pageX + barX;
				videoTag.currentTime = diff * videoTag.duration / c.seekBar.width();
			});
			$(document).bind('mouseup', function(e){
				$(document).unbind('mousemove');
				$(document).unbind('mouseup');
				var diff = e.pageX - pageX + barX;
				videoTag.currentTime = diff * videoTag.duration / c.seekBar.width();
				_this.play();
			});
		}
	};

	function toTime(seconds){
		var hours = parseInt( seconds / 3600 ) % 24;
		var minutes = parseInt( seconds / 60 ) % 60;
		seconds = Math.ceil(seconds % 60);
		return (hours ? (hours < 10 ? "0" + hours : hours) + ':' : '') + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds  < 10 ? "0" + seconds : seconds);
	}
	function updateBufferState(){
		if(videoTag.readyState){
			var p = Math.ceil(videoTag.buffered.end(videoTag.buffered.length - 1) / videoTag.duration * 100);
			c.seekBuffer.css({'width': p + '%'});
		}
	}
	function updateVolumeState(){
		var p = (videoTag.volume * 100);
		c.volumeProgress.width(p + '%');
		c.volumeSlider.css({'left': p + '%'});
		createCookie('volume', videoTag.volume, 123);
	}
})(window.uberPlayer);

var tknVideoPlayer = uberPlayer; // TODO: update links

// TODO: Move these to a lib
function createCookie(name, value, days){
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name){
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

function iosmode(){
	return /ipad|iphone|ipod/i.test(navigator.userAgent);
}

// a temporary fix to make the comment form on the tutorials work (e.g. the space key)
jQuery(function(){
    jQuery('form#tutorialcomment *').bind('keydown', function(e){
        e.stopPropagation();
    });
});
