	/* Variables */
	
	var videoplayer;
	var updateInterval = 200; // milliseconds between visual progress updates
	var playlist = [];
	var isPlaylist = false;
	var currentVideoInPlaylist = -1 ;
	var playlistParentURL = '';
	
	/* Test video tag capability */
	
	function browserHasVideoSupport() {
		var v = document.createElement("video");
		return (v && typeof v.canPlayType != 'undefined');
	}
	/* At the moment these are really buggy */
	function canPlayType_WebM(){
    	var v = document.createElement('video');
    	return !!(v.canPlayType && ( v.canPlayType('video/webm').replace(/no/, '') || v.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, '') ) );
    }
	function canPlayType_H264(){
    	var v = document.createElement('video');
    	return !!(v.canPlayType && ( v.canPlayType('video/mp4').replace(/no/, '') || v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, '') || v.canPlayType('video/mp4; codecs="mp4v.20.8"').replace(/no/, '') ) );
	}
	function canPlayType_Theora(){
		var v = document.createElement('video');
    	return !!(v.canPlayType && ( v.canPlayType('video/ogg').replace(/no/, '') || v.canPlayType('video/ogg; codecs="theora, vorbis"').replace(/no/, '') ) );
	}
	
	/* Flash fallback */
	
	function embedFlash(videoId) {
		
		if(!videoId) videoId = 'videoplayer';
		
		var url = $('source').filter(function () { return this.type == 'video/mp4'; }).attr('src');
		var fullscreenUrl = $('#' + videoId).attr('fullscreenUrl');
		var autoStart = $('#'+videoId).attr('autoplay') ? 1 : 0;
		var loop = $('#'+videoId).attr('loop') ? 1 : 0;
		var width = $('#'+videoId).attr('width');
		var height = Number( $('#'+videoId).attr('height') ) + 23;

		var completeCall = 'showEndOverlay';
		var playingCall = 'clearOverlay';
		if (isPlaylist) {
			isPlaylist = false;
			completeCall = 'playAllNext';
			playingCall = 'onPlayAll';
		}
				
		//alert('url:'+url+' autoStart:'+autoStart+' loop:'+loop+' width:'+width+' height:'+height);
		
		var flashvars = {};
		flashvars.url = url;							// video url
		flashvars.fullscreenUrl = fullscreenUrl;		// video fullscreen url
		flashvars.autoStart = 1;						// autostart?
		flashvars.fullscreen = 1;						// fullscreen mode allowed?
		flashvars.loop = loop;							// does it loop when the video is finished?
		flashvars.infoClick = showInfo;					// javascript method when information button is clicked
		flashvars.completeCall = completeCall;			// javascript method when video is complete
		flashvars.playingCall = playingCall;			// javascript method when video is playing
		flashvars.controls = 0;							// controls disappears even in "non fullscreen" mode
		
		var params = {};
		params.menu = "false";
		params.quality = "high";
		params.bgcolor = "#000000";
		params.allowFullScreen = "true";
		params.allowScriptAccess = "always";
		params.wmode = "transparent";
		
		var attributes = {};
		attributes.id = "flash";
		attributes.name = "flash";
		
		if (document.getElementById(videoId) && document.getElementById(videoId).stop) {
			document.getElementById(videoId).stop();
			$('#' + videoId).empty();
		}
		
		swfobject.embedSWF("/assets/swfs/VideoPlayer.swf", videoId, width, height, "9.0.0","http://cdn.cloudfiles.mosso.com/c18541/expressInstall.swf", flashvars, params, attributes);
		
		clearOverlay();
	}
	
	function embedFlashThumbnail(videoId, videoURL, linkURL, imageURL, autoStart) {
		//var url = $('source[type="video/mp4"]').attr('src');
		var width = $('#'+videoId).attr('width');
		var height = $('#'+videoId).attr('height');
		
		
		var flashvars = {};
		flashvars.v = videoURL;							// video url
		flashvars.u = '#' + linkURL;							// link url
		flashvars.i = imageURL;							// image URL
		flashvars.autoStart = autoStart;
		flashvars.id = videoId;
		
		var params = {};
		params.menu = "false";
		params.quality = "high";
		params.bgcolor = "#000000";
		params.allowScriptAccess = "always";
		params.wmode = 'transparent';
		
		var attributes = {};
		attributes.id = videoId;
		attributes.name = videoId;
		
		swfobject.embedSWF("/assets/swfs/VideoPlayerRollOver.swf", videoId, width, height, "9.0.0","http://cdn.cloudfiles.mosso.com/c18541/expressInstall.swf", flashvars, params, attributes);
	}
	
	function playThumbnail(videoId) {
		$('#' + videoId).addClass('nobg');
		if( swfobject.getObjectById(videoId) ){
			swfobject.getObjectById(videoId).play();
		} else {
			document.getElementById(videoId).play()
		}
	}
	
	function pauseThumbnail(videoId) {
		$('#' + videoId).removeClass('nobg');	
		if( swfobject.getObjectById(videoId) ){
			swfobject.getObjectById(videoId).pause();
		} else {
			document.getElementById(videoId).pause();
		}
	}
	
	function flashVideoPlayer() {
		return swfobject.getObjectById('flash');
	}
	
	/* public methods:
	flashVideoPlayer().play();
	flashVideoPlayer().pause()
	flashVideoPlayer().stop()
	flashVideoPlayer().seek(percent)
	*/
	
	function destroyVideo() {
		
		removeEventListeners();
		stopTimer();
		clearOverlay();
		$('.controls').remove();
	}
	
	/* Event listeners */
	
	function addEventListeners() {
		
		videoplayer.addEventListener('canplay',onInit,false);
		videoplayer.addEventListener('progress',onProgress,false);
		videoplayer.addEventListener('play',onPlay,false);
		videoplayer.addEventListener('pause',onPause,false);
		videoplayer.addEventListener('volumechange',onVolumeChange,false);
		videoplayer.addEventListener('playing',onPlaying,false);
		videoplayer.addEventListener('ended',onEnded,false);
		videoplayer.addEventListener('error',onError,false);
	}
	
	function removeEventListeners() {
		
		videoplayer.removeEventListener('canplay',onInit,false);
		videoplayer.removeEventListener('progress',onProgress,false);
		videoplayer.removeEventListener('play',onPlay,false);
		videoplayer.removeEventListener('pause',onPause,false);
		videoplayer.removeEventListener('volumechange',onVolumeChange,false);
		videoplayer.removeEventListener('playing',onPlaying,false);
		videoplayer.removeEventListener('ended',onEnded,false);
		videoplayer.removeEventListener('error',onError,false);
	}
	
	/* Event handlers */
	
	function onInit(e){
      
      checkFullscreenSupport();
      
      if( !videoplayer.controls ){
      	$('.controls').show();
      }
      
       // for firefox as progress event may have stopped firing by this point
      if(ff_loaded && ff_total){
      	updateLoadingProgress(ff_loaded, ff_total);
      }
	}
	
	var ff_loaded, ff_total;
	function onProgress(e){
      if(e.total && e.loaded){
      	ff_loaded = e.loaded;
      	ff_total = e.total;
		updateLoadingProgress(e.loaded, e.total);
      }
	}
	
	function onPlay(e){
      	$('.play').hide();
		$('.pause').show();
		
		$('#overlay').removeClass('end');
	}
	
	function onPause(e){
      	$('.play').show();
		$('.pause').hide();
	}
	
	function onVolumeChange(e){
      	if( videoplayer.muted || videoplayer.volume == 0 ){
      		$('.sound.off').show();
			$('.sound.on').hide();
      	} else {
			$('.sound.off').hide();
			$('.sound.on').show();
		}
	}
	
	function onPlaying(e){
      	// started playing
      	clearOverlay();
      	
      	initialiseControlsShowHide();
	}
	
	function onEnded(e){
      	videoplayer.currentTime = 0;
      	videoplayer.pause();
      	// end, show replay or whatever
      	showEndOverlay();
	}
	
	function showEndOverlay() {
		clearOverlay();
		$('#overlay').addClass('end');
      	$('#overlay').unbind('click');
      	
      	var buttons = $('#overlay-buttons').clone(true).removeClass('hidden').attr('id', '').addClass('overlay-buttons');
      	buttons.find('.play-again').click(function (e) {  });
      	buttons.show();
      	
      	$('#overlay').append(buttons);
      	
//      	$('#overlay').click( function(e){ alert('end overlay clicked'); } );
      	$('#overlay').show();
      	Cufon.replace('.overlay-buttons', { fontFamily: 'Futura Bold', hover: true });
	}
	
	function clearOverlay() {
		$('#overlay').removeClass('play');
		$('#overlay').removeClass('end');
		$('#overlay').removeClass('error');
		$('#overlay').empty();
	}
	
	var MEDIA_ERR_ABORTED = 1;
	var MEDIA_ERR_NETWORK = 2;
	var MEDIA_ERR_DECODE = 3;
	var MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
	
	function onError(e) {
		  // video playback failed - show a message saying why
		  var error = '';
		  switch (e.target.error.code) {
		    case MEDIA_ERR_ABORTED:
		      error = 'MEDIA_ERR_ABORTED: The fetching process for the media resource was aborted by the user agent at the user\'s request.';
		      break;
		    case MEDIA_ERR_NETWORK:
		      error = 'MEDIA_ERR_NETWORK: A network error of some description caused the user agent to stop fetching the media resource, after the resource was established to be usable.';
		      break;
		    case MEDIA_ERR_DECODE:
		      error = 'MEDIA_ERR_DECODE: An error of some description occurred while decoding the media resource, after the resource was established to be usable.';
		      break;
		    case MEDIA_ERR_SRC_NOT_SUPPORTED:
		      error = 'MEDIA_ERR_SRC_NOT_SUPPORTED: The media resource indicated by the src attribute was not suitable.';
		      break;
		    default:
		      error = 'An unknown error occurred.';
		      break;
		  }
		  
		  $('#error').append( error );
		  if(typeof console != 'undefined')console.error( 'Video playback failed:', error );
		  
		  if( e.target.error.code == MEDIA_ERR_SRC_NOT_SUPPORTED ){
		  	destroyVideo();
		    embedFlash();
		  } else {
		  	showErrorOverlay( error );
		  }
	}
	
	function showErrorOverlay(error) {
		$('#overlay').addClass('error');
		$('#overlay').append( '<p>'+error+'</p>' );
		$('#overlay').unbind('click');
		$('#overlay').show();
	}
	
	/* controls */
	
	function createControls() {
		var controls = '<div class="controls">'
		+ '<a class="playpause play"></a>'
		+ '<a class="playpause pause"></a>'
		+ '<div class="track">'
		+ '<div class="progressBar back"></div>'
		+ '<div class="progressBar loading"></div>'
		+ '<div class="progressBar playback"></div>'
		+ '</div>'
		+ '<a class="sound on"></a>'
		+ '<a class="sound off"></a>'
		+ '<a class="fullscreen"></a>'
		+ '<a class="info"></a>'
		+ '</div>';
		
		$('#videoplayer').after( controls ); 
	}
	
	function configureControls() {
		
		$('.pause').hide();
		$('.sound.off').hide();
		
		$('.play').click( function(e){ videoplayer.play() } );
		$('.pause').click( function(e){ videoplayer.pause() } );
		$('.track').click( function(e){ onSeekBarClick(e, this) } );
		$('.sound.off').click( function(e){ videoplayer.muted = false; videoplayer.volume = 1; } );
		$('.sound.on').click( function(e){ videoplayer.muted = true; videoplayer.volume = 0; } );
		$('.fullscreen').click( function(e){ fullscreen(); } );
		$('.info').click( function(e){ showInfo() } );
	}
	
	function initialiseControlsShowHide() {
      	log('initialiseControlsShowHide');
      	$('#video').unbind('mousemove');
      	$('#video').mousemove( function(e) { showControls(); } )
      	showControls();
	}
	
	var controlsTimeout;
	function showControls() {
		
		clearTimeout( controlsTimeout );
		
		$('.controls').fadeIn('fast');
		
		controlsTimeout = setTimeout( hideControls, 4000 );
		
		//log('show controls');
	}
	
	function hideControls() {
		
		clearTimeout( controlsTimeout );
		
		$('.controls').fadeOut('slow');
		
		//log('hide controls');
	}
	
	
	/* Full screen */
	
	function fullscreenSupported() {
		return ( typeof videoplayer.webkitSupportsFullscreen != 'undefined' && typeof videoplayer.webkitEnterFullscreen != 'undefined' && typeof videoplayer.webkitSupportsFullscreen != 'undefined' && videoplayer.webkitSupportsFullscreen == true );
	}
	
	function checkFullscreenSupport() {
		if( !fullscreenSupported() ) {
			$('.controls').addClass('fullscreenDisabled');
		 }
		 log( '<br />fullscreenSupported ' + fullscreenSupported() );
	}
	
	function fullscreen() {
		if( fullscreenSupported(videoplayer) ){
			if( videoplayer.webkitDisplayingFullscreen ) {
				videoplayer.webkitExitFullscreen();
			} else {
				videoplayer.webkitEnterFullscreen();
			}
		}
	}
	
	/* Progress */
	
	var timer;
	function startTimer() {
		timer = window.setInterval(function() {
			
			//log(videoplayer.currentTime +'/'+ videoplayer.duration, true);
			
			//if (!videoplayer.ended) {
				
				updatePlaybackProgress();
				
				if( typeof videoplayer.buffered != 'undefined' ){// && videoplayer.buffered.end() < videoplayer.duration ){
					updateLoadingProgress( videoplayer.buffered.end(), videoplayer.duration );
				}
				
			//} else {
			//	stopTimer();
			//}
			
			if (videoplayer.ended){
				//alert('ended');
				//stopTimer();
				onEnded(null);
			}
			
		},updateInterval);		
	}
	
	function stopTimer() {
		window.clearInterval(timer);
	}
	
	function updatePlaybackProgress() {
		var progress = videoplayer.currentTime / videoplayer.duration;
		$('.progressBar.playback').width( Math.round( getTrackWidth() * progress ) );
	}
	function updateLoadingProgress(loaded, total) {
		var progress = loaded / total;
		$('.progressBar.loading').width( Math.round( getTrackWidth() * progress ) );
	}
	
	/* Seeking */
	 
	 function onSeekBarClick(e, obj) {
	 	var relativeX = e.pageX - getOffsetLeft(obj);//obj.offsetLeft;
		var percent = relativeX / getTrackWidth();
	 	seekPercent(percent);
	 }
	 
	 function seekPercent(percent) {
   		var seekSeconds = Math.round( videoplayer.duration*percent );
	 	videoplayer.currentTime = seekSeconds;
	 	updatePlaybackProgress();
	 }
	 
	 function getOffsetLeft(obj) {
	 	var offsetLeft = 0;
	 	if (obj.offsetParent) {
	 		do {
				offsetLeft += obj.offsetLeft;
			} while (obj = obj.offsetParent);
	 	}
	 	return offsetLeft;
	 }
	
	/* Track width */
	
	var trackWidth;
	function getTrackWidth() {
		if(!trackWidth || trackWidth == 0) trackWidth = $('.track').width();
		return trackWidth;
	}
	
	/* Log */
	
	function log(msg, empty) {
		//if(empty)$('#log').empty();
		//$('#log').append( msg );
		if( typeof console != 'undefined' ) console.log( msg );
	}
	
	/* Browser detection */
	
	var userAgent = navigator.userAgent.toLowerCase();
	
	function isAndroid() {
		return userAgent.indexOf("android") != -1;
	}
	
	function isIPhone() {
		return userAgent.indexOf("iphone") != -1 || userAgent.indexOf("ipod") != -1;
	}
	
	function isIPad() {
		return userAgent.indexOf("ipad") != -1;
	}
	
	function isFirefox() {
		return userAgent.indexOf("firefox") != -1;
	}
	
	function isChrome() {
		return userAgent.indexOf("chrome") != -1;
	}
	
	function isSafari() {
		return userAgent.indexOf("safari") != -1 && userAgent.indexOf("chrome") == -1;
	}
	
	function useHTML5() {
		return isSafari() || isAndroid() || isIPhone() || isIPad();
	}
	
	/* Codec detection */
	
	function codecAvailable() {
		return true;
		if( isFirefox() && !$('source[type="video/ogg"]').attr('src') ){
			return false;
		}
		
		return true;
	}
	
	/* inititialize */
	
	function inititializeVideo() {
		 //$('#videoFallback').remove();
		 
		 
		 //alert(videoplayer);

		 log( '<br />' + navigator.userAgent.toLowerCase() );
		 
		 if( !videoplayer.autoplay ){
	 		$('#overlay').click( function(e){ videoplayer.play(); } );
	 	 }
	 	 
	 	 if( !videoplayer.controls ) {
	 		createControls();
		 	configureControls();
	 	 }
		 
		 if( isAndroid() || isIPhone() ){
		 
			$('.controls').addClass('mobile');
			$('#videoplayer').click( function(e){ this.play() } );
	 		$('#overlay').click( function(e){ videoplayer.play(); showEndOverlay(); } );
			
		 } else {
		 	
		 	$('.controls').hide();
		 	
		 	if( !videoplayer.autoplay ){
		 		$('#overlay').click( function(e){ videoplayer.play(); } );
		 		videoplayer.play();
		 	}
		 	
		 	if( isIPad() ) {
		 		$('.controls').addClass('soundDisabled');
		 	}
		 	
		 	addEventListeners();
		 	startTimer();
	 	}
	}
	
	/* Ready */

	$(document).ready(function() {
	 
		
	});
	
	function initVideoPlayer() {
		log( 'browserHasVideoSupport ' + browserHasVideoSupport() );
		log( '<br />canPlayType_WebM ' + canPlayType_WebM() );
		log( '<br />canPlayType_H264 ' + canPlayType_H264() );
		log( '<br />canPlayType_Theora ' + canPlayType_Theora() );
		
		videoplayer = document.getElementById("videoplayer");
		
		if( videoplayer ){
		
			 //if( browserHasVideoSupport() && codecAvailable() ){
			 if( browserHasVideoSupport() && useHTML5() ){
				 
				 /* In Safari/Chrome error handling only works if src attrib of video tag is set */
				 if( isChrome() || isSafari() ){
					videoplayer.src = $('source[type="video/mp4"]').attr('src');
				 }
				 
				 inititializeVideo();
				 
			 } else {
			 	
			 	embedFlash();
			 	
			 	
			 }
		}
		
		initVideoThumbs();	
	}
	
	function initVideoThumbs() {
		
		if( browserHasVideoSupport() && useHTML5() ){
			 
			 $(".videoThumb[src$='.mp4']").parent().attr('style', '');
			 /*$('.videoThumb').each(function(index) {
			   //alert(index + ': ' + $(this).text());
			   var videoId = $(this).attr('id');
			   var videoURL = $(this).attr('src');
			   var linkURL = $('#'+videoId+'Link').attr('href');
			   log(videoId +', '+ videoURL +', '+ linkURL);
			   $(this).error( function(){embedFlashThumbnail(videoId, videoURL, linkURL, null, 1);});
			});*/
			 
		 } else {
		 	
			$('.videoThumb').each(function(index) {
			   //alert(index + ': ' + $(this).text());
			   var videoId = $(this).attr('id');
			   var videoURL = $(this).attr('src');
			   var linkURL = $('#'+videoId+'Link').attr('href');
			   log(videoId +', '+ videoURL +', '+ linkURL);
			   if (videoURL.length > 0) {
				   embedFlashThumbnail(videoId, videoURL, linkURL, null, 0);
			   }
			});
		 }
		
		
	}
	
	function showInfo(){
		showWorkInfo();
	}
	
	function playAll() {
		playlistParentURL = window.location.href;
		playlist = [];
		isPlaylist = true;
		currentVideoInPlaylist = -1;
		$('#reel li a').each(function () {
			playlist.push($(this).attr('href'));
		});
		playAllNext();
	}
	
	function playAllNext() {
		isPlaylist = true;

		currentVideoInPlaylist++;
		if (currentVideoInPlaylist > playlist.length - 1) {
			window.location.href = playlistParentURL;
			return;
		}

		window.location.hash = playlist[ currentVideoInPlaylist ];
	}
	
	function setPlaylistTitle() {
		return;
		if (!isPlaylist) {
			$('#playlistTitle').remove();
			return;
		}
		
		$('#work h2').height($('#work h2 span').height());
		var controls = $('<div />')
			.attr('id', 'controls');
		
		var title = $('<div />')
			.attr('id', 'playlistTitle')
			.html('Now playing ' + (currentVideoInPlaylist+1) + ' of ' + playlist.length);
		
		var prevnext = $('<div />')
			.addClass('prev-next');
			
		var a = $('<a />')
			.attr('href', 'javascript:void(0); ')
			.addClass('noxhr');
			
		var next = $(a).clone(true)
			.addClass('next')
			.text('next spot')
			.bind('click', function () {
				playAllNext();
			});
			
		var prev = $(a).clone(true)
			.addClass('prev')
			.text('previous spot')
			.bind('click', function () {
				currentVideoInPlaylist = Math.max(-1, currentVideoInPlaylist - 2);
				playAllNext();
			});
		
		if (currentVideoInPlaylist > 0) {
			$(prevnext).append(prev);
		}
		if (currentVideoInPlaylist < playlist.length - 1) {
			$(prevnext).append(next);
		}
		$(title).append(prevnext);
		$(controls).append(title);
		$('#work h2').after(controls);
	}
	
	function onPlayAll() {
		clearOverlay();
	}
 
