/*
 * flowplayer.html5 3.2.0 Flowplayer JavaScript plugin.
 * 
 * Author: Jack Doerner
 * Copyright (c) 2010 Jack Doerner
 *
 * Licensed under the GPL 2+ license
 * SEE: http://www.opensource.org/licenses
 * 
 * Date: July 16, 2010
 * Revision: 002 
 */ 
 
(function($) {

	$f.addPlugin("html5", function(options) {

		var self = this;
		html5_active = false;
		var html5_error = false;
		
		var opts = {
			fail_html:"<div id='flowplayer_html5_fail' style='margin-left:auto; margin-right:auto; margin-top:auto; margin-bottom:auto; padding:5px;'>\
					This video could not be played. <br />\
					Please install Adobe Flash, or possibly an HTML5 compatible browser</div>",
			h264_baseurl:"",
			webm_baseurl:"",
			html5_force:false
		};		
		
		$.extend(opts, options);
		
		
		//methods
		
		//append the individual url to the baseurl
		function buildurl(base,url) {
			var ret = "";
			if (typeof base == "string" && base.slice(0,7) == "http://") {
				ret += base;
				if (base.slice(-1) != "/") { ret += "/"; }
			}
			ret += url;
			return ret;
		}
		
		//checks whether flash is installed
		function supports_flash() {
			// Major version of Flash required
			var requiredMajorVersion = 9;
			// Minor version of Flash required
			var requiredMinorVersion = 0;
			// Minor version of Flash required
			var requiredRevision = 0;
			//actually detect flash
			return flashembed.isSupported([requiredMajorVersion, requiredRevision]);
		}
		
		//checks whether HTML5 video is supported
		function supports_video() {
			return !!document.createElement('video').canPlayType;
		}
		
		//checks to for the h.264 codec
		function supports_h264() {
			if (!supports_video()) { return false; }
			var v = document.createElement("video");
			if (v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"') == "probably") {return true;}
		}
		
		//checks for the webm codec
		function supports_webm() {
			if (!supports_video()) { return false; }
			var v = document.createElement("video");
			if (v.canPlayType('video/webm; codecs="vp8, vorbis"') == "probably") {return true;}
		}
		
		//is the user running iOS? This is a Hack... for some reason regular h.264 detection doesn't work
		function is_iOS() {
			var agent = navigator.userAgent;
			return ((agent.indexOf('iPhone') != -1) || (agent.indexOf('iPod') != -1) || (agent.indexOf('iPad') != -1) );
		}
		
		
		//callbacks!
		
		//bulk of the code is here, it seems.
		self.onBeforeLoad(function(){
			
			//first, check to see if flash is installed
			if (typeof has_flash == "undefined") {
				var has_flash = supports_flash();
			};
			if (has_flash & (typeof opts.html5_force == "undefined" || opts.html5_force == false)) {
				return true;
			};
			
			//I cannot think of a reason why it wouldn't be set... but something caused me to put this here.
			if (typeof globalClip == "undefined") {
				globalClip = 0;
			};
						
			
			//check for webm support
			if (supports_webm() & typeof self.getClip(globalClip).webm != "undefined") {
				var html5_url = buildurl(opts.webm_baseurl,self.getClip(globalClip).webm);
				var html5_type = "video/webm"
				if (typeof self.getClip(globalClip).webm_codecs != "undefined") { var html5_codecs=self.getClip(globalClip).webm_codecs}
				else {var html5_codecs = "vp8, vorbis"};
			//then check for h264
			} else if ((is_iOS() || supports_h264()) & (typeof self.getClip(globalClip).h264 != "undefined" || self.getClip(globalClip).url.slice(-4) == ".mp4")) {
				if (typeof self.getClip(globalClip).h264 != "undefined") {
					var html5_url = buildurl(opts.h264_baseurl, self.getClip(globalClip).h264);
				} else {
					var html5_url = buildurl(opts.baseurl, self.getClip(globalClip).url);
				}
				var html5_type = "video/mp4"
				if (typeof self.getClip(globalClip).h264_codecs != "undefined") { var html5_codecs=self.getClip(globalClip).h264_codecs}
				else {var html5_codecs = ""};
			//display an error if there is no flash and no HTML5
			} else {
				if (!html5_active && !html5_error) {html = self.getParent().innerHTML;
				} else if (html5_active) {
					//for some reason, leaving these bound causes some weird bugs
					$(self.html5_element).unbind("play");
					$(self.html5_element).unbind("pause");
				}
				self.getParent().innerHTML = opts.fail_html
				html5_active = false;
				html5_error = true;
				self._fireEvent("onUnload");
				self._fireEvent("onLoad");
				return false;
			}
				
			//code to run if video is already loaded; toggles the play status
			if (html5_active && html5_url == self.html5_element.src) {
				if (self.html5_element.paused || self.html5_element.ended) {
					self.html5_element.play();
				} else {self.html5_element.pause(); };
				return false;
			}
			
			//finally, load the video
			if (!html5_active && !html5_error) {html = self.getParent().innerHTML;}
			self.getParent().innerHTML = "";
			self.html5_element = document.createElement('video');
			self.html5_element.src = html5_url;
			self.html5_element.type = html5_type + "; codecs='" + html5_codecs + "'";
			self.html5_element.setAttribute('width','100%');
			self.html5_element.setAttribute('height','100%');
			self.html5_element.preload = self.getConfig(true).clip.autoBuffering;
			self.html5_element.autoplay = self.getConfig(true).clip.autoPlay;
			self.html5_element.controls = true;
			//bindings so that HTML5 video fires flowplayer events
			$(self.html5_element).bind("play", function() { self._fireEvent(["onBegin", globalClip]);});
			$(self.html5_element).bind("pause", function() { self._fireEvent(["onPause", globalClip]);});
			
			//prevent propagation of click to the wrapper, which would conflict with builtin controls
			$(self.html5_element).bind('click', function(event){
				if (event.stopPropagation) {event.stopPropagation();}
				else {event.cancelBubble = true;}
			});
			
			//install the player that's just been created
			self.getParent().appendChild(self.html5_element);
			html5_active=true;
			html5_error = false;
			self._fireEvent("onLoad");
			self._fireEvent(["onStart", globalClip]);
			return false;
		});
		
		//Unload does not work at all for the HTML5 plugin in webkit
		self.onBeforeUnload(function(){
			if (html5_active || html5_error) {
				html5_active = false;
				html5_error = false;
				//for some reason, leaving these bound causes some weird bugs
				$(self.html5_element).unbind("play");
				$(self.html5_element).unbind("pause");
				self.getParent().innerHTML = html;
				self._fireEvent("onUnload");
				return false;
			} else {
				return true;
			}
		});
		
		self.onBeforeMute(function(){
			if (html5_active) {
				self.html5_element.muted=true;
				self._fireEvent("onMute");
				return false;
			} else {
				return true;
			}
		});
		
		self.onBeforeUnmute(function(){
			if (html5_active) {
				self.html5_element.muted=false;
				self._fireEvent("onUnmute");
				return false;
			} else {
				return true;
			}
		});
		
		self.onBeforePause(function(){
			if (html5_active) {
				self.html5_element.pause();
				return false;
			} else {
				return true;
			}
		});
		
		self.onBeforeResume(function(){
			if (html5_active) {
				self.html5_element.play();
				return false;
			} else {
				return true;
			}
		});
		
		self.onBeforeStop(function(){
			if (html5_active) {
				self.html5_element.pause();
				self.html5_element.currentTime = 0;
				return false;
			} else {
				return true;
			}
		});
		
		// the player instance should be returned to enable plugin and method chaining
		return this;

	});
	
})(jQuery);
