/**
 * CastFire Javascript player.
 * (c) CastFire.com 2009
 * @author Ivan Kirnev <ivan@castfire.com>
 */

var CastfirePlayer = { version: "1.0" };
 
/**
 * Constructor of player instance
 * @param conf configuration parameters
 */
function castfire_player(conf) {
	// private member: storing initial configuration values
	this.initConf = conf;
	// player id
	this.id = conf.playerID;
	this.guid = conf.playerGuid || this.playerGuid;
	this.scrollType = conf.scrollType || this.scrollType;
	this.scrollSpeed = conf.scrollSpeed || this.scrollSpeed;
	this.rows = conf.rows || this.rows;
	this.random = (conf.random != null ? conf.random : this.random); // for boolean variables
	this.mediaTemplateURL = conf.mediaTemplateURL || this.mediaTemplateURL;
	this.queueCaption = this.queueCaption || "Queue";
	this.playerInstance = null;
	this.embedID = "castfire_player-" + this.id;
	this.embedSRC = "http://p.castfire.com/" + this.guid + "/video/unloaded";
	this.browseId = 'cfp-tabs-browse'; // div Id of player's browse button object
	this.queueId = 'cfp-tabs-queue'; // div Id of player's queue button object
	this.tabInfos = {};     // helper object for internal usage
	this.selectedTabIdx = 0;
	this.selectedRightTabIdx = 0;
	this.selectedRightTabName = null;
	this.playlists = {};
	this.queueData = { shows: [], sources: [] };		// creating an empty queue
	this.currentPlayList = null;
	this.currentShow = null;
	this.isInited = false;
	this.is_iOS = (navigator.userAgent.match(/ipod|ipad|iphone/i) ? true : false);
};

(function($) { 
	// Extending CastfirePlayer
	$.extend(true, CastfirePlayer, {
		players: [],        // list of registered players

		// Creates new player instance
		createPlayer: function(conf) {
			var player = this.getPlayer(conf.playerID);
			if (!player) {
				player = new castfire_player(conf);
				// registering new player
				this.players.push(player);
				player.create();
			}
			return player;
		},

		releasePlayer: function(playerId) {
			var p = this.getPlayer(playerId);
			if (p) { this.players.remove(p); }
		},

		getPlayer: function(playerId) {
			for (var i = 0, len = this.players.length; i < len; i++) {
				if (this.players[i].id === playerId) { return this.players[i]; }
			}
			return null;
		}
	});

	// =============================================
	// Player
	// =============================================

	// Extending castfire_player class with members and methods
	$.extend(true, castfire_player.prototype, {
		/**
		 * Shows player object
		 */
		show: function() {
			$('#' + this.id).show();
		},

		/**
		 * Hides player object
		 */
		hide: function() {
			$('#' + this.id).hide();
		},

		create: function() {
			var player = this;	
			
			this.hide();
			$('#' + this.id).load(this.mediaTemplateURL + " #template-container", 
				(function(player) {
						return function() {
							player.init();
				}}) (this)
			);
		},
		
		init: function() {
			var player = this;	
			
			$('#' + this.id + ' .__player-container ' + (!this.is_iOS ? "video" : "object")).remove();
			
			this.render();
			if(this.initConf.dropdown){
				$("#" + this.id + " #myselectbox").selectbox({is_iOS:this.is_iOS});
			}
			$("#" + this.id + " .__playlist-container .__playlist-template").hide();
			this.show();

			this.playerInstance = this.getPlayerInstance(this.embedID);
			
			if(this.playerInstance && this.playerInstance.tagName == "VIDEO") {
				// init html5 callback
				this.playerInstance.addEventListener('ended', function(){player.onCompleteMedia();}, false);
			} else {
				// init flash callback
				castfire_videoComplete = function(url){player.onCompleteMedia()};
			}
			
			this.leftTabsWidth = 20;
			var tabEls = $("#" + this.id + " .__topnavigation li").each(function(i){
				var tabId = player.id + '-cfp-tabs-' + i;
				var tabEl = $(this);
				tabEl.attr("id", tabId).hover(
					function () { if (!$(this).hasClass("__active")) { $(this).addClass("__hover"); } },
					function () { $(this).removeClass("__hover"); }
				).click(
					(function(player, tabId) {
						return function() {
							if(player.initConf.dropdown){
								$($("#" + player.id + " #myselectbox"+"_container ul li")[0]).click();
							}
							player.onTabClicked(tabId); 
						}}) (player, tabId)
				);

				player.tabInfos[tabId] = {
					index: i, 
					width: tabEl.outerWidth(true), 
					cfg: player.initConf.tabs[i],
					_default: player.initConf.tabs[i]['default']
				};
				player.leftTabsWidth += tabEl.outerWidth(true);
			});

			if($("#" + this.id + " .__scrollTabs").divScroll){
				var divScroll = $("#" + this.id + " .__scrollTabs").divScroll({
					scrollType: "horizontal",
					//width: this.playerWidth, 
					scrollWidth: this.leftTabsWidth,
					scrollSpeed: this.scrollSpeed,
					scrollWrapper: "div.__scrollWrapper",
					scrollerBack: "div.__scrollLeft",
					scrollerForward: "div.__scrollRight",
					classScrollerDisabled: "__x-item-disabled",
					classScrollerBackHover: "",
					classScrollerForwardHover: ""
				});
			}
			if(this.initConf.dropdown){
				var selOts = $("#" + this.id + " #myselectbox").change(
						(function(player) {
							return function() {
							if(this.value == "-1") return;
							var tabId = player.id + '-cfp-tabs-' + this.value;
							player.onTabClicked(tabId); }}) (this)
					)[0].options;

				for (var i = 0, len = selOts.length; i < len; i++) {
					var tabId = this.id + '-cfp-tabs-' + (tabEls.length + i);
					var tabEl = $(selOts[i]);
					// set an id
					tabEl.attr("id", tabId);
					
					this.tabInfos[tabId] = {
						index: tabEls.length + i, 
						width: 0, 
						cfg: this.initConf.dropdown[i]
					};
				}
			}
			// counting tabs total width to show/hide scrollers
			tabEls = $("#" + this.id + " .__videonavigation li");
			for (var i = 0, len = tabEls.length; i < len; i++) {
				var tabEl = $(tabEls.get(i));
				var tabId = tabEl.attr("id");
				tabEl.hover(
					function () { if (!$(this).hasClass("__active")) { $(this).addClass("__hover"); } },
					function () { $(this).removeClass("__hover"); }
				).click(
					(function(player, tabId) {
						return function() { player.onRightTabClicked(tabId); }}) (this, tabId)
				);
				this.tabInfos[tabId] = { index: i, width: tabEl.width()};
			}
			
			if(this.initConf.containers){
				var ctrs = this.initConf.containers;
				for (var i = 0; i < ctrs.length; i++) {
					if(!ctrs[i] || !ctrs[i].id || !ctrs[i].feed) continue;
					$("#" + this.id + " #"+ctrs[i].id + " .__playlist-template").hide();
					this.fillContainer(ctrs[i].id, ctrs[i].feed, ctrs[i].scrollType, ctrs[i].rows, ctrs[i].random);
				}
			}

			if(this.is_iOS) {
				//$("#castfire_player-player1").removeAttr('controls');
				//$("#castfire_player-player1").attr('controls', 'controls');
			}
			// seting active tab
			this.onTabClicked(this.id + '-cfp-tabs-' + this.selectedTabIdx, true);
			this.selectedRightTabName = this.browseId;
			this.isInited = true;
		},

		render: function() {

			//fix for IE[7,8]
			var pcr = $('#' + this.id + ' .__player-container');
			if(pcr[0]){
				pcr[0].innerHTML = pcr[0].innerHTML
					.replace(/{embed_id}/ig, this.embedID)
					.replace(/{embed_src}/ig, this.embedSRC)
					.replace(/%7Bembed_src%7D/ig, this.embedSRC);
			}
			/*$('#' + this.id + ' .__player-container object').render({
				'embed_id': this.embedID,
				'embed_src': this.embedSRC
			});*/
			
			
			var tabs = this.initConf.tabs || [];
			var arrRender = new Array();
			for (var i = 0, len = tabs.length; i < len; i++) {
				if(!tabs[i] || !tabs[i].name || !tabs[i].feed) continue;
				var parts = /^([^ ]*) ?(.*)?$/i.exec( tabs[i].name );
				arrRender.push({
					'word1': parts[1],
					'word2': parts[2] || "",
					'class': tabs[i]['class'] || "_"
				});
				if (tabs[i]['default']) { this.selectedTabIdx = i; }
			}
			$('#' + this.id + ' .__topnavigation li').render(arrRender, {clone:true});
			
			var dropdown = this.initConf.dropdown;
			if(dropdown){
				var selVal = 0;
				arrRender = [];
				if (tabs.length > 0 ) {
					arrRender = [
						{
							'value': "-1",
							'inner': "More Channels"
						}
					];
				}
				for (var i = 0, len = dropdown.length; i < len; i++) {
					if(!dropdown[i] || !dropdown[i].name || !dropdown[i].feed) continue;
					arrRender.push({
						'value': (tabs.length + i),
						'inner': dropdown[i].name
					});
					if (dropdown[i]['default']) { 
						this.selectedTabIdx = tabs.length + i; 
						selVal = tabs.length + i;
					}
				}
				$("#" + this.id + " #myselectbox option").render(arrRender, {clone:true})
					.parent().val(selVal);
			}
		},
		getPlayerInstance: function (id){
			if(document.embeds[(id)] && !$.browser.msie) return document.embeds[id]; // !$.browser.msie - for ie9
			if(window.document[(id)]) return window.document[id];
			if(window[(id)]) return window[id];
			if(document[(id)]) return document[id];
			if($("#"+id)[0]) return $("#"+id)[0];
			return null;
		},
		fillContainer: function(tabId, feed, scrollType, rows, itemsPerPage, random) {
			$('#' + this.id + ' #' + tabId + ' .__playlist-loading').fadeIn();
			if(itemsPerPage){
				feed = feed.replace(/(^.*\/json\/)\d+(\/.*$)/i, "$1" + itemsPerPage + "$2");
			}
			var resp = $.ajax({
				type: "GET", cache: false, async: false,
				url: feed,
				dataType: feed.indexOf(".json") != -1 ?  "json" : "jsonp",
				success: (function(player, tabId) { return function(data, status) {
					player.updatePlayList(tabId, data, "container", scrollType, rows, itemsPerPage, random);
				}; }) (this, tabId)
			});
		},
		onTabClicked: function(tabId, isDefaultTab) {
			var tabObj = this.tabInfos[tabId];
			if (tabObj) {
				//if (tabObj.index === this.selectedTabIdx && this.isInited) { return; }
				var prevId = "#" + this.id + '-cfp-tabs-' + this.selectedTabIdx;
				$(prevId).removeClass("__active");
				$("#" + tabId).addClass("__active").removeClass("__hover");
				this.selectedTabIdx = tabObj.index;
				this.onRightTabClicked(this.browseId);

				if (this.currentPlayList) {
					var pl = this.playlists[this.currentPlayList];
					if (pl) { $("#" + pl.divId).hide(); }
					
					pl = this.playlists[tabId];
					if (pl) { 
						$("#" + pl.divId).show(); 
						this.currentPlayList = tabId;
						return;
					}
				}

				$('#' + this.id + " .__playlist-container .__playlist-loading").fadeIn();
				var info = this.tabInfos[tabId];
				var feed = info.cfg.feed;
				
				if(this.itemsPerPage){
					feed = feed.replace(/(^.*\/json\/)\d+(\/.*$)/i, "$1" + this.itemsPerPage + "$2");
				}
				
				if(this.is_iOS && this.initConf.iOS){
					var video_append = true;
					if(feed.indexOf("/video:")!=-1) {
						feed = feed.replace(/\/video:[^\/]+\//i, "/video:" + this.initConf.iOS + "/");
						video_append = false;
					}
					if(video_append && feed.indexOf("/?")!=-1) {
						feed = feed.replace("/?", "/video:" + this.initConf.iOS + "/?");
						video_append = false;
					}
					if(video_append) {
						feed = feed + "video:" + this.initConf.iOS + "/";
					}
				}
				
				if (isDefaultTab && this.initConf.sh) {
					feed = feed + "sh:" + this.initConf.sh + "/";
				}

				if (info) {
					var resp = $.ajax({
						type: "GET", cache: false, async: false,
						url: feed,
						dataType: info.cfg.feed.indexOf(".json") != -1 ?  "json" : "jsonp",
						success: (function(player, tabId) { return function(data, status) {
							player.updatePlayList(tabId, data, "browse", null, null, null, info.cfg.random);}; }) (this, tabId)
					});
				}
			}
		},
		onRightTabClicked: function(tabId) {
			if (tabId === this.selectedRightTabName) { return; }
			var re = new RegExp("cfp-tabs-(.*)", "gi");
			var res = re.exec(tabId);	// res[1] - tabCommand
			if (res != null) {
				var cmd = res[1];
				if (cmd === "browse") {
					var browsePl = (!this.currentPlayList) ? null :
							this.playlists[this.currentPlayList];
					var pl = this.playlists[this.selectedRightTabName];
					if (browsePl) { $("#" + browsePl.divId).show(); }
					if (pl) { $("#" + pl.divId).hide(); }

				} else if (cmd === "queue") {
					if (!this.playlists[tabId]) {
						// create playlist for queue
						if (this.currentPlayList &&
							(!this.queueData || !this.queueData.shows || this.queueData.shows.length == 0)) {
							var divId = this.currentPlayList + "-playlist";
							var itemId = divId + "-" + this.currentShow.show_id;
							this.addToQueueClicked(itemId, this.currentShow);
							if (!this.isPlaying){ this.playMedia(this.currentShow); }
						}
						this.updatePlayList(tabId, this.queueData, "queue");
					}
					var browsePl = (!this.currentPlayList) ? null :
							this.playlists[this.currentPlayList];
					var pl = this.playlists[tabId];
					if (browsePl) { $("#" + browsePl.divId).hide(); }
					if (pl) { $("#" + pl.divId).show(); }
				} else {
					// unknown tab - quit
					return;
				}
				$("#" + this.selectedRightTabName).removeClass("__active");
				$("#" + tabId).addClass("__active");
				this.selectedRightTabName = tabId;
				this.selectItem(this.currentShow);
			}
		},
		updatePlayList: function(tabId, data, mode, scrollType, rows, itemsPerPage, random) {

			if(mode != "queue" && (this.random || random)){
				data.shows = this.randomizeShows(data.shows);
			}
			
			var divId = tabId + "-playlist";
			var plContainer = ( mode=="container" ? "#"+tabId : ".__playlist-container" );
			var divPL = $("#" + this.id + " " + plContainer + " .__playlist-template.__" + mode).clone()
				.attr("id", divId).removeClass("__playlist-template").removeClass("__" + mode);
			$('#' + this.id + " " + plContainer).append(divPL);
			
			if (data.shows && data.shows.length > 0) {
				var arrRender = new Array();
				// iterating thru the show array
				for (var i = 0, len = data.shows.length; i < len; i++) {
					var show = data.shows[i];
					show.itemId = divId + "-" + show.show_id;
					show.nextShow = data.shows[(i+1!=len)?i+1:0];
					show.nextShow.prevShow = show;
					if((rows && rows > 1) || (mode!="container" && this.rows && this.rows > 1)){
						var n = Math.floor(i/this.rows);
						if(!arrRender[n]) arrRender[n] = new Array();
						arrRender[n].push(this.getItemForRender(divId, show, mode, i));
					}else{
						arrRender.push(this.getItemForRender(divId, show, mode, i));
					}
				}
				divPL.find("ul.__scrollWrapper>li").render(arrRender, {clone:true});
				if((rows && rows > 1) || (mode!="container" && this.rows && this.rows > 1)){
					var arrLI = divPL.find("ul.__scrollWrapper li ul li");
					for(var i = arrLI.length-1; i>=0; i--){
						if(arrLI[i].id == "{"+ (i%this.rows) +".item_id}"){
							$(arrLI[i]).remove();
						}else{
							break;
						}
					}
				}
			} else {
				divPL.find("ul.__scrollWrapper>li").remove();
				divPL.append("<div class=\"__playlist-no-videos\" >No videos found.</div>");
			}
			divPL.show();
			$('#' + this.id + " " + plContainer + " .__playlist-loading").fadeOut();
			if(!this.noScrollArrows && $('#' + divId).divScroll){
				var divScroll = $('#' + divId).divScroll({
					scrollType: (mode=="container"?scrollType:this.scrollType),
					scrollSpeed:this.scrollSpeed,
					scrollerBack: "div.__scroller-up",
					scrollerForward: "div.__scroller-down",
					classScrollerBackHover: "__scroller-up-hover",
					classScrollerForwardHover: "__scroller-down-hover",
					classScrollerDisabled: "__x-item-disabled",
					scrollWrapper: "ul.__scrollWrapper",
					scrollEvent: this.scrollEvent,
					is_iOS: this.is_iOS,
					scrollBar: this.scrollBar,
					callbackEndForward: (function(player, tabId, random) { return function() {
										player.loadNextPage(tabId, random);}; }) (this, tabId, random)
				});
			}

			var pl = { 
				divId: divId, 
				data: data, 
				divScroll: divScroll, 
				mode: mode, 
				scrollType: scrollType, 
				rows: rows, 
				itemsPerPage: itemsPerPage
			};
			this.playlists[tabId] = pl;

			if (data.shows) {
				// binding events to buttons
				for (var i = 0, len = data.shows.length; i < len; i++) {
					var show = data.shows[i];
					var itemId = divId + "-" + show.show_id;
					if (mode === "browse") {
						$("#" + itemId + " .__add").click(
							(function(player, itemId, show) { return function(ev) {
								ev.stopPropagation();
								player.addToQueueClicked(itemId, show); }; }) (this, itemId, show)
						);
						
						if( this.queueData && this.queueData.sources && this.queueData.sources[itemId] ) {
							$("#" + itemId + " .__add").hide();
						} 
					}
					if (mode === "queue") {
						$("#" + itemId + " .__remove").click(
							(function(player, itemId, show) { return function(ev) {
								ev.stopPropagation();
								player.removeFromQueueClicked(itemId, show); 
								}; }) (this, itemId, show)
						);
					}
					this.setPlayItem(itemId, show);
				}
			}
			if (mode === "browse") {
				this.currentPlayList = tabId;
			}
			
			if (!this.currentShow && data && data.shows && data.shows.length > 0 && mode!="container" ) {
				if (this.initConf.autoplay || typeof(this.initConf.autoplay)=='undefined' && this.initConf.sh) {
					this.playMedia(this.initConf.show?this.initConf.show:data.shows[0]);
					castFirePlayerReady = (function(player, show, data) { return function() {
						player.playMedia(player.initConf.show?player.initConf.show:data.shows[0]);}; }) (this, show, data)
				} else {
					this.loadMedia(this.initConf.show?this.initConf.show:data.shows[0]);
					castFirePlayerReady = (function(player, show, data) { return function() {
						player.loadMedia(player.initConf.show?player.initConf.show:data.shows[0]);}; }) (this, show, data)
				}
				this.currentShow = data.shows[0];
			}
		},
		setPlayItem: function(itemId, show){
			$("#" + itemId + " .__image").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
			$("#" + itemId + " .__title").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
			$("#" + itemId + " .__play_click").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
		},
		getItemForRender: function(divId, show, mode, i) {
			var itemId = divId + "-" + show.show_id;
			var date = new Date(show.pubdate);
			return {
				"item_id" : itemId,
				"item_class" : (i%2 == 1 ? "__bg1" : "__bg0"),
				"item_add_remove" : (mode !== "browse" ? "__remove" : "__add"),
				"_src_" : "src", // workaround for Remote Sources in IE
				"item_img_src" : (show.images && show.images.tmb ? show.images.tmb : "no_image.png" ),
				"item_date" : (date.castfireFormat && date.castfireFormat('D, M j, Y') || ""),
				"item_title" : show.title,
				"item_description" : show.description
			}
		},
		loadNextPage: function(tabId, random){
			var pl = this.playlists[tabId];
			
			if( this.loading||
				pl.mode == "queue" || 
				pl.mode == "browse" && tabId != this.currentPlayList ){ return; }

			if ( !pl || !pl.data || !pl.data.pagination || "" == pl.data.pagination.next /*|| !pl.data.shows*/ ) { return; }

			var plContainer = ( pl.mode=="container" ? "#"+tabId : ".__playlist-container" );

			$('#' + this.id + " " + plContainer + " .__playlist-loading").fadeIn();
			this.loading = true;

			var itemsPerPage = (pl.mode=="container" ? pl.itemsPerPage : this.itemsPerPage) || 10;
			var feed = pl.data.pagination.next.replace(/(^.*\/json\/\d+:)\d+(\/.*$)/i, "$1" + itemsPerPage + "$2");
			var resp = $.ajax({
				type: "GET", cache: false, async: true,
				url: feed, //pl.data.pagination.next,
				dataType: pl.data.pagination.next.indexOf(".json") != -1 ?  "json" : "jsonp",
				success: (function(player, tabId, random) { return function(data, status) {
					player.loading = false;
					player.addNextPageToList(tabId, data, random)}; }) (this, tabId, random)

			});
			
		},
		addNextPageToList: function(tabId, data, random){

			if(this.random || random){
				data.shows = this.randomizeShows(data.shows);
			}
				
			var pl = this.playlists[tabId];
			if (!pl || !pl.data || !pl.data.shows || !data || !data.shows) { return; }
			
			var plContainer = ( pl.mode=="container" ? "#"+tabId : ".__playlist-container" );
			var divId = pl.divId;
			var htmlArr = [];

			var arrRender = new Array();
			// iterating thru the show array
			for (var i = 0, len = data.shows.length; i < len; i++) {
				var show = data.shows[i];
				var j = pl.data.shows.length;
				pl.data.shows[j] = show;
				show.itemId = divId + "-" + show.show_id;
				show.nextShow = pl.data.shows[0];
				show.nextShow.prevShow = show;
				show.prevShow = pl.data.shows[j-1];
				show.prevShow.nextShow = show;
				if((pl.rows && pl.rows > 1) || (pl.mode!="container" && this.rows && this.rows > 1)){
					var n = Math.floor(i/this.rows);
					if(!arrRender[n]) arrRender[n] = new Array();
					arrRender[n].push(this.getItemForRender(divId, show, "browse", j));
				}else{
					arrRender.push(this.getItemForRender(divId, show, "browse", j));
				}

			}

			var liItem = $("#" + this.id + " " + plContainer + " .__playlist-template.__" + pl.mode + " .__scrollWrapper>li").clone();
			pl.divScroll.append(liItem);
			liItem.hide().render(arrRender, {clone:true});

			if((pl.rows && pl.rows > 1) || (pl.mode!="container" && this.rows && this.rows > 1)){
				var arrLI = pl.divScroll.div.find("ul.__scrollWrapper li ul li");
				for(var i = arrLI.length-1; i>=0; i--){
					if(arrLI[i].id == "{"+ (i%this.rows) +".item_id}"){
						$(arrLI[i]).remove();
					}else{
						break;
					}
				}
			}

			
			//pl.divScroll.append(htmlArr.join(''));
			pl.data.pagination = data.pagination;
			
			for (var i = 0, len = data.shows.length; i < len; i++) {
				var show = data.shows[i];
				var itemId = divId + "-" + show.show_id;
				$("#" + itemId + " .__add").click(
					(function(player, itemId, show) { return function(ev) {
						ev.stopPropagation();
						player.addToQueueClicked(itemId, show); }; }) (this, itemId, show)
				);
				
				if( this.queueData && this.queueData.sources && this.queueData.sources[itemId] ) {
					$("#" + itemId + " .__add").hide();
				}
				
				this.setPlayItem(itemId, show);
			}	
			var itemId = divId + "-" + data.shows[data.shows.length-1].show_id;
			$("#" + itemId + " .tumb").ready(
				(function(player, pl, divId) { return function() {
					setTimeout(
						(function(player, pl, divId) { return function() {
							$('#' + player.id + " " + plContainer + " .__playlist-loading").fadeOut();
							pl.divScroll.show("li");
						}; }) (player, pl, divId)
					, 500)
				}; }) (this, pl, divId)
			);
		},
		addToQueueClicked: function(itemId, show) {
			this.queueData.shows.push(show);
			show.itemId = itemId;
			this.queueData.sources[itemId] = itemId;
			var tabId = "cfp-tabs-queue";
			var divId = tabId + "-playlist";
			$("#" + itemId + " .__add").hide();
			$("#" + tabId + " a").text(
					this.queueCaption + " (" + this.queueData.shows.length + ")");
			var pl = this.playlists[tabId];
			if (pl) {
				var liItem = $("#" + this.id + " .__playlist-container .__playlist-template.__queue .__scrollWrapper>li").clone();
				pl.divScroll.append(liItem);
				liItem.render(this.getItemForRender(divId, show, "queue", this.queueData.shows.length-1));
				if (this.queueData.shows) {
					// iterating thru the show array
					for (var i = 0, len = this.queueData.shows.length; i < len; i++) {
						var show = this.queueData.shows[i];
						show.itemId = divId + "-" + show.show_id;
						show.nextShow = this.queueData.shows[(i+1!=len)?i+1:0];
						show.nextShow.prevShow = show;
					}
				}
				
				var queueItemId = divId + "-" + show.show_id;
				$("#" + queueItemId + " .__remove").click(
						(function(player, queueItemId, show) { return function(ev) {
							ev.stopPropagation();
							player.removeFromQueueClicked(queueItemId, show); 
							}; }) (this, queueItemId, show)
				);
				
				this.setPlayItem(queueItemId, show);
				this.selectItem(this.currentShow);
			}
		},
		removeFromQueueClicked: function(itemId, show){
			this.queueData.shows.remove(show);
			this.queueData.sources[show.itemId] = null;
			var tabId = "cfp-tabs-queue";
			var divId = tabId + "-playlist";
			$("#" + show.itemId + " .__add").show();
			
			if (this.queueData.shows.length == 0){
				$("#" + tabId + " a").text(this.queueCaption);
			}else{
				$("#" + tabId + " a").text(
					this.queueCaption + " (" + this.queueData.shows.length + ")");
			}
			var pl = this.playlists[tabId];
			if (pl) {
				pl.divScroll.remove("#" + itemId);
			}
			show.prevShow.nextShow = show.nextShow;
			show.nextShow.prevShow = show.prevShow;
			show = null;
		},
		playMedia: function(show, deep) {
			deep = deep?deep:0;
			if(deep>10) return;

			if (this.playerInstance) {
				if(typeof(show) != "string"){
					this.selectItem(show);
				}
				try{
					if(this.playerInstance.tagName == "VIDEO") {
						this.playerInstance.poster = (typeof(show) != "string" && show.images && show.images.poster ? show.images.poster : "");
						this.playerInstance.src = (typeof(show) != "string" ? show.url : show); 
						this.playerInstance.load();
						this.playerInstance.play();
					} else {
						var silverlight_player = document.getElementById(this.embedID);
						if (silverlight_player.Content && silverlight_player.Content.CastFireMediaPlayer) 
							silverlight_player.Content.CastFireMediaPlayer.ExternalCastfirePlayVideo((typeof(show) != "string" ? show.url : show));
						else
							this.playerInstance.externalCastfirePlayVideo((typeof(show) != "string" ? show.url : show));

					}
					this.isPlaying = true;
				}catch(e){
					setTimeout(
					(function(player, show, deep) { return function() {
						player.playMedia(show,++deep); }; }) (this, show, deep)
					, 1000);
				}
			}
		},
		loadMedia: function(show, deep) {
			deep = deep?deep:0;
			if(deep>10) return;
			
			if (this.playerInstance) {
				if(typeof(show) != "string"){
					this.selectItem(show);
				}
				try{
					if(this.playerInstance.tagName == "VIDEO") {
						this.playerInstance.poster = (typeof(show) != "string" && show.images && show.images.poster ? show.images.poster : "");
						this.playerInstance.src = (typeof(show) != "string" ? show.url : show); 
						this.playerInstance.load();
					} else {
						var silverlight_player = document.getElementById(this.embedID);
						if (silverlight_player.Content && silverlight_player.Content.CastFireMediaPlayer) 
							silverlight_player.Content.CastFireMediaPlayer.ExternalCastfireLoadVideo((typeof(show) != "string" ? show.url : show));
						else
							this.playerInstance.externalCastfireLoadVideo((typeof(show) != "string" ? show.url : show));
					}
					this.isPlaying = false;
				}catch(e){
					setTimeout(
					(function(player, show, deep) { return function() {
						player.loadMedia(show,++deep); }; }) (this, show, deep)
					, 1000);
				}
			}
		},
		onCompleteMedia: function(){
			if(!this.currentShow) return;
			var tmpShow = this.currentShow;
			if(this.selectedRightTabName == this.queueId){
				this.removeFromQueueClicked(tmpShow.oDiv.attr("id"), tmpShow); 
				if( this.queueData.shows.length == 0 ){
					this.currentShow = null;
					return;
				}
			}
			this.playMedia(tmpShow.nextShow);

		},
		selectItem: function(show) {
			if(this.currentShow && this.currentShow.oDiv){
				this.currentShow.oDiv.removeClass("__playlist-item-selected");
			}
			if(show){
				var curPL = this.selectedRightTabName == this.queueId?this.queueId:this.currentPlayList;
				show.oDiv = $("#" + show.itemId);
				show.oDiv.addClass("__playlist-item-selected");
				this.currentShow = show;
			}
		},
		randomizeShows: function(shows) {
			shows.sort(function() {return 0.5 - Math.random()});
			return shows;
		}
	});

	$.extend(true, Array.prototype, {
		/**
		 * Checks whether or not the specified object exists in the array.
		 * @param {Object} o The object to check for
		 * @return {Number} The index of o in the array (or -1 if it is not found)
		 */
		indexOf : function(o){
			for (var i = 0, len = this.length; i < len; i++){
				if(this[i] == o) return i;
			}
			return -1;
		},

		/**
		 * Removes the specified object from the array.  If the object is not found nothing happens.
		 * @param {Object} o The object to remove
		 * @return {Array} this array
		 */
		remove : function(o) {
			var index = this.indexOf(o);
			if(index != -1) { this.splice(index, 1); }
			return this;
		}
	});
})(jQuery);
