/**
 * BCHTML5 1.0.2 (03 JUNE 2010)
 *
 * AUTHORS:
 *	 Matthew Congrove, Professional Services Engineer, Brightcove
 *	 Brian Franklin, Professional Services Engineer, Brightcove
 *
 * CONTRIBUTORS:
 *	 Brian Crescimanno, Principal Software Engineer, Brightcove
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this
 * software and associated documentation files (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights to use, copy, modify,
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following
 * conditions:
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. YOU AGREE TO RETAIN IN THE SOFTWARE AND ANY
 * MODIFICATIONS TO THE SOFTWARE THE REFERENCE URL INFORMATION, AUTHOR ATTRIBUTION AND
 * CONTRIBUTOR ATTRIBUTION PROVIDED HEREIN.
 *
 * BCHTML5 utilizes the following libraries:
 *	 FlashDetect-JS Copyright (c) 2007, Carl S. Yestrau All rights reserved.
 *	 Code licensed under the BSD License: http://www.featureblend.com/license.txt
 */

var BCHTML5 = function () {
	this.active = false;
	this.templateReady = false;
	this.dataReceived = false;

	this.debug = false;
	this.encoding = 274000;
	this.id = "myExperience";
	this.indexPlaylist = 0;
	this.indexVideo = 0;
	this.parameters = {
		"preload": true
	};
	this.player = null;
	this.playlist = null;
	this.playlists = [];
	this.supportsFlash = FlashDetect.installed && FlashDetect.majorAtLeast(9);
	this.supportsH264 = false;
	this.supportsOgg = false;
	this.supportsWebM = false;
	this.template = false;
	this.token = "";
	this.video = null;
	this.videos = [];

	this.init = function (pInfo) {
		this.debug = pInfo.debug ? true : false;

		if (!document.getElementById(this.id)) {
			this.error("Player not found");
			return;
		}

		if (this.token.length < 1 && pInfo.token) {
			this.token = pInfo.token;
		} else {
			this.error("Token not provided");
			return;
		}

		if (this.supportsFlash && !this.debug) {
			return;
		}

		this.detect();

		if (!this.supportsH264 && !this.supportsWebM && !this.supportsOgg && !this.debug) {
			this.error("Browser does not support Flash or HTML5");
			return;
		}

		this.active = true;
		this.parameters.preload = pInfo.preload ? pInfo.preload : true;

		if (this.encoding == 274000 && pInfo.encoding) {
			this.encoding = pInfo.encoding;
		}

		if (this.id == "myExperience" && pInfo.id) {
			this.id = pInfo.id;
		}

		if (this.template || pInfo.template) {
			if (!this.template && pInfo.template) {
				this.template = pInfo.template;
			}

			if (this.template.slice(-6) != "/") {
				this.template += "/";
			}

			var pElJavaScript = document.createElement("script");
			pElJavaScript.src = this.template + "BCHTML5Player.js";
			pElJavaScript.type = "text/javascript";
			document.getElementsByTagName("head")[0].appendChild(pElJavaScript);

			var pElStyle = document.createElement("link");
			pElStyle.href = this.template + "BCHTML5Player.css";
			pElStyle.type = "text/css";
			pElStyle.rel = "stylesheet";
			document.getElementsByTagName("head")[0].appendChild(pElStyle);
		}

		this.events.fire("onLoad");

		this.getParameters();
		this.removeFlash();
		this.addVideoElement();
		this.determineContent();
	};

	this.detect = function () {
		if (typeof HTMLVideoElement !== "undefined") {
			var pEl = document.createElement("video");

			this.supportsH264 = pEl.canPlayType("video/mp4").length > 0 ? true : false;
			this.supportsWebM = pEl.canPlayType("video/webm").length > 0 ? true : false;
			this.supportsOgg = pEl.canPlayType("video/ogg").length > 0 ? true : false;

			if (this.debug) {
				this.supportsH264 = true;
			}
		}
	};

	this.getParameters = function () {
		var pEl = document.getElementById(this.id);
		var pParams = pEl.getElementsByTagName("param");

		for (var i = 0; i < pParams.length; i++) {
			var pKey = pParams[i].getAttribute("name").toLowerCase();

			switch (pKey) {
			case "autostart":
				this.parameters.autoStart = pParams[i].getAttribute("value") == "true" ? true : false;
				break;
			case "height":
				this.parameters.height = parseInt(pParams[i].getAttribute("value"), 10);
				break;
			case "playerid":
				this.parameters.playerID = parseInt(pParams[i].getAttribute("value"), 10);
				break;
			case "width":
				this.parameters.width = parseInt(pParams[i].getAttribute("value"), 10);
				break;
			case "@videoplayer":
			case "videoid":
				this.parameters.videoID = pParams[i].getAttribute("value");
				break;
			case "@playlisttabs":
			case "@playlistcombo":
			case "playlistid":
				this.parameters.playlistID = pParams[i].getAttribute("value");
				break;
			case "@videolist":
				this.parameters.videoIDs = pParams[i].getAttribute("value");
				break;
			}
		}
	};

	this.removeFlash = function () {
		try {
			document.getElementById(this.id).parentNode.removeChild(document.getElementById(this.id));
		} catch (e) {}
	};

	this.determineContent = function () {
		if (this.parameters.videoID) {
			this.getData("video", this.parameters.videoID);
		} else if (this.parameters.videoIDs) {
			this.getData("videos", this.parameters.videoIDs);
		} else if (this.parameters.playlistID) {
			this.getData("playlist", this.parameters.playlistID);
		} else if (this.parameters.playerID) {
			this.getData("player", this.parameters.playerID);
		} else {
			this.error("No content assigned");
			return;
		}
	};

	this.addVideoElement = function () {
		var pOptions = " controls='true'";
		pOptions += this.parameters.autoStart ? " autoplay='true'" : " autoplay='false'";
		pOptions += this.parameters.preload ? " preload='auto'" : " preload='none'";

		var pHtml = "<div id='BCHTML5_" + this.id + "' class='BCHTML5Container' style='width: " + this.parameters.width + "px; height: " + this.parameters.height + "px;'>";
		pHtml += "<video id='" + this.id + "' width='" + this.parameters.width + "' height='" + this.parameters.height + "'" + pOptions + " style='background: #000;'></video>";
		pHtml += "</div>";

		document.write(pHtml);

		this.getPlayer();
		this.assignListeners();
	};

	this.getPlayer = function () {
		this.player = document.getElementById(this.id);

		if (this.template) {
			this.events.add("onTemplateReady", function () {
				BCHTML5.templateReady = true;

				if (typeof BCHTML5Player !== "undefined") {
					BCHTML5Player.onTemplateReady();
				}
			});
		}

		this.events.fire("onTemplateReady");

		if (navigator.userAgent.toLowerCase().search("android") > -1) {
			this.player.addEventListener("click", function () {
				BCHTML5.player.play();

				this.events.fire("onMediaPlay");
			}, false);
		}
	};

	this.assignListeners = function () {
		this.player.addEventListener("ended", function () {
			BCHTML5.videoEventEnded();
		}, false);
	};

	/***************/
	/***************/
	/***************/

	this.getData = function (pType, pId) {
		var pUrl = "http://api.brightcove.com/services/library?command=";

		switch (pType) {
		case "video":
			if (pId.substr(0, 4) == "ref:") {
				pUrl += "find_video_by_reference_id&reference_id=" + pId.replace(/ref:/ig, "");
			} else {
				pUrl += "find_video_by_id&video_id=" + pId;
			}

			pUrl += "&callback=BCHTML5.handleVideo";

			break;
		case "videos":
			if (pId.substr(0, 4) == "ref:") {
				pUrl += "find_videos_by_reference_ids&reference_ids=" + pId.replace(/ref:/ig, "");
			} else {
				pUrl += "find_videos_by_ids&video_ids=" + pId;
			}

			pUrl += "&callback=BCHTML5.handleVideos";

			break;
		case "playlist":
			pUrl += "find_playlist_by_id&callback=BCHTML5.handlePlaylist&playlist_id=" + pId;
			break;
		case "player":
			pUrl += "find_playlists_for_player_id&callback=BCHTML5.handlePlaylists&player_id=" + pId;
			break;
		}

		pUrl += "&media_delivery=http&token=" + this.token + "&video_fields=id,name,shortDescription,linkURL,linkText,thumbnailURL,videoStillURL,renditions,FLVURL";

		this.inject(pUrl);
	};

	this.handleVideo = function (pData) {
		if (pData) {
			BCHTML5.videos = [pData];
			BCHTML5.video = pData;

			this.events.fire("onDataReceived");
			BCHTML5.dataReceived = true;

			BCHTML5.assignContent();
		}
	};

	this.handleVideos = function (pData) {
		pData = pData.items;

		if (pData) {
			BCHTML5.videos = pData;
			BCHTML5.video = pData[0];

			this.events.fire("onDataReceived");
			BCHTML5.dataReceived = true;

			BCHTML5.assignContent();
		}
	};

	this.handlePlaylist = function (pData) {
		if (pData) {
			BCHTML5.playlists = [pData];
			BCHTML5.playlist = pData;
			BCHTML5.videos = pData.videos;
			BCHTML5.video = pData.videos[0];

			this.events.fire("onDataReceived");
			BCHTML5.dataReceived = true;

			BCHTML5.assignContent();
		}
	};

	this.handlePlaylists = function (pData) {
		pData = pData.items;

		if (pData) {
			BCHTML5.playlists = pData;
			BCHTML5.playlist = pData[0];
			BCHTML5.videos = pData[0].videos;
			BCHTML5.video = pData[0].videos[0];

			this.events.fire("onDataReceived");
			BCHTML5.dataReceived = true;

			BCHTML5.assignContent();
		}
	};

	/***************/
	/***************/
	/***************/

	this.inject = function (pUrl) {
		var pScript = document.createElement("script");
		var pRand = Math.floor(Math.random() * 1001);
		var pId = "bc-" + pRand + "-" + (new Date()).getTime();

		pScript.id = pId;
		pScript.src = pUrl + "&" + pRand;
		pScript.type = "text/javascript";
		pScript.charset = "utf-8";
		document.getElementsByTagName("head")[0].appendChild(pScript);

		setTimeout("document.getElementsByTagName('head')[0].removeChild(document.getElementById('" + pId + "'))", 5000);
	};

	this.assignContent = function () {
		var pRendition = this.determineRendition();
		var pType;

		if (pRendition.videoCodec == "H264") {
			pType = "video/mp4; codecs='avc1.42E01E, mp4a.40.2'";
		} else if (pRendition.videoCodec == "WEBM") {
			pType = "video/webm; codecs='vp8, vorbis'";
		} else if (pRendition.videoCodec == "OGG") {
			pType = "video/ogg; codecs='theora, vorbis'";
		} else {
			return;
		}

		this.player.type = pType;
		this.player.src = pRendition.url;
		this.player.poster = this.video.videoStillURL;
		this.player.load();

		this.events.fire("onMediaChange");

		if (this.parameters.autoStart) {
			this.player.play();

			this.events.fire("onMediaPlay");
		} else {
			this.player.pause();
		}
	};

	this.determineRendition = function () {
		var pSelectedRendition = [];

		for (var i = 0; i < this.video.renditions.length; i++) {
			var pRendition = this.video.renditions[i];
			var pSupported = false;

			if (this.supportsH264 && pRendition.videoCodec == "H264") {
				pSupported = true;
			} else if (this.supportsWebM && pRendition.videoCodec == "WEBM") {
				pSupported = true;
			} else if (this.supportsOgg && pRendition.videoCodec == "OGG") {
				pSupported = true;
			}

			if (pSupported) {
				if (pSelectedRendition.length < 1) {
					pSelectedRendition = pRendition;
				} else {
					var pSelectedDistance = Math.abs(pSelectedRendition.encodingRate - this.encoding);
					var pNewDistance = Math.abs(pRendition.encodingRate - this.encoding);

					if (pNewDistance <= pSelectedDistance) {
						pSelectedRendition = pRendition;
					}
				}
			}
		}

		this.events.fire("onRenditionSelect", pSelectedRendition);

		return pSelectedRendition;
	};

	/***************/
	/***************/
	/***************/

	this.videoEventEnded = function () {
		if (this.videos[this.indexVideo + 1]) {
			this.indexVideo++;

			this.video = this.videos[this.indexVideo];
		} else if (this.playlists[this.indexPlaylist + 1]) {
			this.indexPlaylist++;
			this.indexVideo = 0;

			this.playlist = this.playlists[this.indexPlaylist];
			this.videos = this.playlists[this.indexPlaylist].videos;
			this.video = this.playlists[this.indexPlaylist].videos[0];
		} else {
			return;
		}

		this.events.fire("onMediaEnd");

		this.parameters.autoStart = true;
		this.assignContent();
	};

	/***************/
	/***************/
	/***************/

	this.tween = function (pEl, pType, pNewValue, pTime, pCallback) {
		if (pTime == 0 || typeof(pTime) != "number") {
			pTime = 1;
		}

		var pStartValue = this.getNum(pEl.style[pType])[0];
		var pValueDistance = pNewValue - pStartValue;
		var pTimeStart = new Date().getTime();
		var pTimeEnd = pTimeStart + pTime;

		this.tweenExecute(pEl, pType, pStartValue, pValueDistance, pTime, pTimeEnd, pCallback);
	};

	this.tweenExecute = function (pEl, pType, pStartValue, pValueDistance, pTime, pTimeEnd, pCallback) {
		var pCurrentTime = new Date().getTime();
		var pTimeRemaining = Math.max(0, pTimeEnd - pCurrentTime);
		var pCurrentMove;

		if (pType == "top" || pType == "right" || pType == "bottom" || pType == "left") {
			pCurrentMove = Math.round((pValueDistance - (Math.pow(pTimeRemaining, 3) / Math.pow(pTime, 3)) * pValueDistance) * 10) / 10;
		} else {
			pCurrentMove = Math.round((pValueDistance - (pTimeRemaining / pTime) * pValueDistance) * 10) / 10;
		}

		if (pTimeRemaining <= 0 || pValueDistance > 10) {
			pCurrentMove = parseInt(pCurrentMove);
		}

		var isPx = BCHTML5.getNum(pEl.style[pType])[1];

		if (isPx) {
			pEl.style[pType] = (pStartValue + pCurrentMove) + "px";
		} else {
			pEl.style[pType] = (pStartValue + pCurrentMove);
		}

		if (pTimeRemaining > 0) {
			setTimeout(

			function () {
				BCHTML5.tweenExecute(pEl, pType, pStartValue, pValueDistance, pTime, pTimeEnd, pCallback);
			}, 10);
		} else {
			if (typeof(pCallback) == "function") {
				pCallback();
			}
		}
	};

	this.getNum = function (pNum) {
		var ret = "";
		var bool = false;

		if (pNum.indexOf("px") > -1) {
			bool = true;
			ret = parseInt(pNum.substring(0, pNum.indexOf("px")));
		} else {
			ret = parseInt(pNum);
		}

		return new Array(ret, bool);
	};

	this.events = new function () {
		this.add = function (eName, fName) {
			if (!this.check(eName)) {
				this.map[eName] = [];
			}

			this.map[eName].push(fName);
		};

		this.remove = function (eName, fName) {
			if (this.check(eName)) {
				var temp = [];

				for (var i in this.map[eName]) {
					if (this.map[eName][i] != fName) {
						temp.push(this.map[eName][i]);
					}
				}

				this.map[eName] = temp;
			}
		};

		this.fire = function (eName, pData) {
			if (this.check(eName)) {
				for (var i in this.map[eName]) {
					this.map[eName][i](pData);
				}
			}
		};

		this.check = function (eName) {
			return ((typeof this.map[eName] !== "undefined") && (this.map[eName].length > 0));
		};

		this.map = [];
	}();

	this.error = function (pData) {
		if (this.debug) {
			if (typeof console !== "undefined") {
				console.log("BCHTML5: " + pData);
			}
		}
	};
};

var FlashDetect=new function(){var self=this;self.JS_RELEASE="1.0.4"; self.installed=false;self.raw="";self.major=-1;self.minor=-1;self.revision=-1;self.revisionStr="";var activeXDetectRules=[{"name":"ShockwaveFlash.ShockwaveFlash.7","version":function(obj){return getActiveXVersion(obj);}},{"name":"ShockwaveFlash.ShockwaveFlash.6","version":function(obj){var version="6,0,21";try{obj.AllowScriptAccess="always";version=getActiveXVersion(obj);}catch(err){} return version;}},{"name":"ShockwaveFlash.ShockwaveFlash","version":function(obj){return getActiveXVersion(obj);}}];var getActiveXVersion=function(activeXObj){var version=-1;try{version=activeXObj.GetVariable("$version");}catch(err){} return version;};var getActiveXObject=function(name){var obj=-1;try{obj=new ActiveXObject(name);}catch(err){obj={activeXError:true};} return obj;};var parseActiveXVersion=function(str){var versionArray=str.split(",");return{"raw":str,"major":parseInt(versionArray[0].split(" ")[1],10),"minor":parseInt(versionArray[1],10),"revision":parseInt(versionArray[2],10),"revisionStr":versionArray[2]};};var parseStandardVersion=function(str){var descParts=str.split(/ +/);var majorMinor=descParts[2].split(/\./);var revisionStr=descParts[3];return{"raw":str,"major":parseInt(majorMinor[0],10),"minor":parseInt(majorMinor[1],10),"revisionStr":revisionStr,"revision":parseRevisionStrToInt(revisionStr)};};var parseRevisionStrToInt=function(str){return parseInt(str.replace(/[a-zA-Z]/g,""),10)||self.revision;};self.majorAtLeast=function(version){return self.major>=version;};self.minorAtLeast=function(version){return self.minor>=version;};self.revisionAtLeast=function(version){return self.revision>=version;};self.versionAtLeast=function(major){var properties=[self.major,self.minor,self.revision];var len=Math.min(properties.length,arguments.length);for(i=0;i<len;i++){if(properties[i]>=arguments[i]){if(i+1<len&&properties[i]==arguments[i]){continue;}else{return true;}}else{return false;}}};self.FlashDetect=function(){if(navigator.plugins&&navigator.plugins.length>0){var type="application/x-shockwave-flash";var mimeTypes=navigator.mimeTypes;if(mimeTypes&&mimeTypes[type]&&mimeTypes[type].enabledPlugin&&mimeTypes[type].enabledPlugin.description){var version=mimeTypes[type].enabledPlugin.description;var versionObj=parseStandardVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revisionStr=versionObj.revisionStr;self.revision=versionObj.revision;self.installed=true;}}else if(navigator.appVersion.indexOf("Mac")==-1&&window.execScript){var version=-1;for(var i=0;i<activeXDetectRules.length&&version==-1;i++){var obj=getActiveXObject(activeXDetectRules[i].name);if(!obj.activeXError){self.installed=true;version=activeXDetectRules[i].version(obj);if(version!=-1){var versionObj=parseActiveXVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revision=versionObj.revision;self.revisionStr=versionObj.revisionStr;}}}}}();};

var BCHTML5 = new BCHTML5();
