/**
 * CastFire Javascript player.
 * (c) CastFire.com 2009
 * @author Ivan Kirnev <ivan.kirnev@gmail.com>
 */

var CastfirePlayer = { version: "1.0" };
// 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.init();
		}
		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
// =============================================
/**
 * Constructor of player instance
 * @param conf configuration parameters
 */
function castfire_player(conf) {
	// private member: storing initial configuration values
	var navigationHeight = 31;
	this.initConf = conf;
	// player id
	this.id = conf.playerID;
	this.guid = conf.playerGuid;
	this.playerInstance = null;
	this.mainContainerId = this.id + '-cfp-mainContainer';     // div Id of main container
	this.leftPanelId = this.id + '-cfp-leftPanel';     // div Id of left panel
	this.rightPanelId = this.id + '-cfp-rightPanel';     // div Id of left panel
	this.tabsId = this.id + '-cfp-tabs';     // div Id of player tabs
	this.embedId = this.id + '-cfp-embedId'; // div Id of player embeded object
	this.playlistId = this.id + '-cfp-playlistId'; // div Id of player playlist object
	this.browseId = this.id + '-cfp-tabs-browse'; // div Id of player's browse button object
	this.queueId = this.id + '-cfp-tabs-queue'; // div Id of player's queue button object
	this.playlistUpId = this.id + '-cfp-playlistUpId'; // div Id of up button in playlist
	this.playlistDownId = this.id + '-cfp-playlistDownId'; // div Id of down button in playlist
	this.totalWidth = conf.totalWidth;
	this.totalHeight = conf.totalHeight;
	this.playerWidth = conf.playerWidth;
	this.playerHeight = conf.totalHeight-navigationHeight;//conf.playerHeight;
	this.description = conf.description;
	this.tabInfos = {};     // helper object for internal usage
	this.selectedTabIdx = 0;
	this.currentOffset = 0;
	this.currentLeftTab = 0;
	this.maxLeftTab = 0;
	this.selectedRightTabIdx = 0;
	this.selectedRightTabName = null;
	this.currentRightOffset = 0;
	this.currentRightLeftTab = 0;
	this.showLeftScrollers = true;
	this.showRightScrollers = true;
	this.leftScrollers = {};
	this.rightScrollers = {};
	this.mouseDown = false;
	this.scrollClicked = false;
	this.leftTabsWidth = 0;
	this.rightTabsWidth = 0;
	this.el = null;
	this.playlists = {};
	this.queueData = { shows: [], sources: [] };		// creating an empty queue
	this.currentPlayList = null;
	this.currentShow = null;
	this.isInited = false;
};

// Extending castfire_player class with members and methods
$.extend(true, castfire_player.prototype, {
	/**
	 * Shows player object
	 */
	show: function() {
	},

	/**
	 * Hides player object
	 */
	hide: function() {
	},

	init: function() {

		var player = this;	
		// init callback
		castfire_videoComplete = function(url){player.onCompleteMedia(url)};
		
		document.body.onmousedown = function() { 
			player.mouseDown = true;
		}
		document.body.onmouseup = function() {
			player.mouseDown = false;
		}


		this.el = $('#' + this.id);
		if( this.el && this.el.length > 0 ){
			this.el[0].innerHTML = this.generateHtml();
		}

		// setting up sizes of elements
		$('#' + this.leftPanelId).
			width(this.playerWidth).height(this.totalHeight);
		$('#' + this.leftPanelId + " .wrap2").width(this.playerWidth);
		var rightPanelWidth = this.totalWidth - this.playerWidth;
		$('#' + this.rightPanelId).
			width(rightPanelWidth).height(this.totalHeight);
		$('#' + this.rightPanelId + " .wrap2").width(rightPanelWidth);
		$('#' + this.rightPanelId + " .playlist-container").height(this.playerHeight);
		$('#' + this.embedId).height(this.playerHeight);
		

		this.playerInstance = this.getPlayerInstance("castfire_player-" + this.id);
		
		// setting up style changes on events
		$("#" + this.mainContainerId + " .wrap2 li").hover(
			function () { if (!$(this).hasClass("active")) { $(this).addClass("hover"); } },
			function () { $(this).removeClass("hover"); }
		);

		// counting tabs total width to show/hide scrollers
		this.leftTabsWidth = 0;
		var tabEls = $("#" + this.leftPanelId + " .wrap2 li");
		
		for (var i = 0, len = tabEls.length; i < len; i++) {
			var tabId = this.id + '-cfp-tabs-' + i;
			var tabEl = $(tabEls.get(i));
			// set an id
			tabEl.attr("id", tabId).click(
				(function(player, tabId) {
					return function() { player.onTabClicked(tabId); }}) (this, tabId)
			);
			var off = tabEl.position().left;
			
			this.tabInfos[tabId] = {
				index: i, 
				width: tabEl.outerWidth(), 
				offset: off, 
				cfg: this.initConf.tabs[i]
				//, 
				//pageFirstItem: pageFirstItem, 
				//pageCountItems: pageCountItems
			};
			this.leftTabsWidth += tabEl.outerWidth();
		}
		this.showLeftScrollers = (this.leftTabsWidth > this.playerWidth);
		var leftScrollerId = '#' + this.leftPanelId + " .wrap2 .x-tab-scroller-left";
		var rightScrollerId = '#' + this.leftPanelId + " .wrap2 .x-tab-scroller-right";
		var tabsWrapperId = '#' + this.leftPanelId + " .wrap2 .tabs-wrapper";
		this.leftScrollers = { left: $(leftScrollerId).outerWidth(), right: $(rightScrollerId).outerWidth() };
		$(leftScrollerId).toggle(this.showLeftScrollers).addClass("x-item-disabled");
		$(rightScrollerId).toggle(this.showLeftScrollers);
		// move tab div to left border
		$(tabsWrapperId).css("left", this.showLeftScrollers ? "0" : "-" + this.leftScrollers.left + "px");
		$(leftScrollerId).mousedown(
			(function(player, dir) { return function() { player.onScrollerClicked(dir, this); }}) (this, "left")
		);
		$(rightScrollerId).mousedown(
			(function(player, dir) { return function() { player.onScrollerClicked(dir, this); }}) (this, "right")
		);

		// counting tabs total width to show/hide scrollers
		this.rightTabsWidth = 0;
		tabEls = $("#" + this.rightPanelId + " .wrap2 li");
		for (var i = 0, len = tabEls.length; i < len; i++) {
			var tabEl = $(tabEls.get(i));
			var tabId = tabEl.attr("id");
			tabEl.click(
				(function(player, tabId) {
					return function() { player.onRightTabClicked(tabId); }}) (this, tabId)
			);
			this.tabInfos[tabId] = { index: i, width: tabEl.width(), offset: this.rightTabsWidth };
			this.rightTabsWidth += tabEl.width();
		}
		leftScrollerId = '#' + this.rightPanelId + " .wrap2 .x-tab-scroller-left";
		rightScrollerId = '#' + this.rightPanelId + " .wrap2 .x-tab-scroller-right";
		tabsWrapperId = '#' + this.rightPanelId + " .wrap2 .tabs-wrapper";
		this.rightScrollers = { left: $(leftScrollerId).width(), right: $(rightScrollerId).width() };
		this.showRightScrollers = (this.rightTabsWidth > rightPanelWidth);
		$(leftScrollerId).toggle(this.showRightScrollers);
		$(rightScrollerId).toggle(this.showRightScrollers);
		$(tabsWrapperId).css("left", this.showRightScrollers ? "0" : "-" + this.rightScrollers.left + "px");
		$(leftScrollerId).click(
			(function(player, dir) { return function() { player.onRightScrollerClicked(dir); }}) (this, "left")
		);
		$(rightScrollerId).click(
			(function(player, dir) { return function() { player.onRightScrollerClicked(dir); }}) (this, "right")
		);
		
		// seting active tab
		this.onTabClicked(this.id + '-cfp-tabs-' + this.selectedTabIdx);
		// calculating max left tab
		for (var i = 0; i < this.initConf.tabs.length; i++) {
			var tabId = this.id + '-cfp-tabs-' + i;
			var info = this.tabInfos[tabId];
			var w = info.offset + this.playerWidth -
					(this.leftScrollers.left + this.leftScrollers.right);
			if (w > this.leftTabsWidth) {
				this.maxLeftTab = i; break;
			}
		}
		this.selectedRightTabName = this.browseId;
		this.isInited = true;
	},

	/**
	 * Returns player's html code
	 */
	generateHtml: function() {
		var arr = [
			"<div id=\"" + this.mainContainerId + "\" class=\"main-container\">",   // main container
			"<div id=\"" + this.leftPanelId + "\" class=\"left-column\">",      // left column
			"<div class=\"wrap2\">",            // tab wrapper
			"<div class=\"x-tab-scroller-left\"></div>",    // left tab scroller
			"<div class=\"x-tab-scroller-right\"></div>",   // right tab scroller
			"<div class=\"tabs-wrapper\"><ul>"
		];
		var tabs = this.initConf.tabs;
		for (var i = 0, len = tabs.length; i < len; i++) {
			if(!tabs[i] || !tabs[i].name || !tabs[i].feed) continue;

			var el = "<li><div class=\"tab-link\"><span>" + tabs[i].name + "</span></div></li>";
			arr.push(el);
			if (tabs[i]['default'] && i !== 0) { this.selectedTabIdx = i; }
		}
		arr.push(
			"</ul></div><div class=\"strip-spacer\"></div></div>",
			"<div id=\"" + this.embedId + "\"class=\"castfire-player-container\">",
			this.generateEmbed(),
			"</div></div>"
		);
		arr.push(
			"<div id=\"" + this.rightPanelId + "\" class=\"right-column\">",
			"<div class=\"wrap2\">",
			"<div class=\"x-tab-scroller-left\"></div>",    // left tab scroller
			"<div class=\"x-tab-scroller-right\"></div>",   // right tab scroller
			"<div class=\"tabs-wrapper\"><ul>",
			"<li id=\"" + this.id + "-cfp-tabs-browse\" class=\"active\"><div class=\"tab-link\"><span>Browse</span></div></li>",
			"<li id=\"" + this.id + "-cfp-tabs-queue\"><div class=\"tab-link\"><span>Queue (0)</span></div></li>",
			"</ul></div><div class=\"strip-spacer\"></div></div>",

			"<div class=\"playlist-container\">",
			"</div></div>"
		);
		return arr.join('');
	},
	getPlayerInstance: function (id){	
		if(document.embeds[(id)])return document.embeds[id];
		if(window.document[(id)])return window.document[id];
		if(window[(id)])return window[id];
		if(document[(id)])return document[id];
		return null;
	},
	onTabClicked: function(tabId) {	
		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;
				}
			}

			var divId = tabId + "-playlist";
			//$("#" + divId).remove();
			var htmlArr = [
				"<div id=\"" + divId + "\">",
				"<div class=\"playlist-scroller-up\"></div>",
				"<div class=\"playlist-wrapper\">",
				"<div class=\"playlist-loading\"> </div>",
				"</div>", 
				"<div class=\"playlist-scroller-down\"></div>", 
				"</div>"
			]
			$('#' + this.rightPanelId + " .playlist-container").
				append(htmlArr.join(''));
			
			var info = this.tabInfos[tabId];
			if (info) {
				var resp = $.ajax({
					type: "GET", cache: false, async: false,
					url: info.cfg.feed,
					dataType: info.cfg.feed.indexOf(".json") != -1 ?  "json" : "jsonp",
					success: (function(player, tabId) { return function(data, status) {
								player.updatePlayList(tabId, data, "browse");}; }) (this, tabId)

				});
			}
		}
	},
	onRightTabClicked: function(tabId) {
		if (tabId === this.selectedRightTabName) { return; }
		var re = new RegExp("(.*)-cfp-tabs-(.*)", "gi");
		var res = re.exec(tabId);	// res[1] - playerId; res[2] - tabCommand
		if (res != null) {
			var cmd = res[2];
			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
					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").removeClass("hover");
			this.selectedRightTabName = tabId;
			this.selectItem(this.currentShow);
		}
	},
	onScrollerClicked: function(dir, target, speed) {
		if(this.scrollClicked) { return; }
		speed = speed?speed:"slow";
		if (dir === "left") {
			if (this.currentLeftTab === 0) { return; }
			if ($(target).hasClass("x-item-disabled")) { return; }
			this.currentLeftTab--;
			var info = this.tabInfos[this.id + '-cfp-tabs-' + this.currentLeftTab];
			if (!info) { return; }
			var rightScrollerId = '#' + this.leftPanelId + " .wrap2 .x-tab-scroller-right";
			$(rightScrollerId).removeClass("x-item-disabled");
			var tabsWrapperId = '#' + this.leftPanelId + " .wrap2 .tabs-wrapper";
			this.scrollClicked = true;
			$(tabsWrapperId).animate({left: (info.offset > 0) ?
					"-" + (info.offset) + "px" : "0"}, speed,
				(function(player, dir, target) { return function() {
					player.scrollClicked = false;
					if (player.currentLeftTab === 0) { $(target).addClass("x-item-disabled"); }
					if(player.mouseDown && !$(target).hasClass("x-item-disabled")){
						player.onScrollerClicked(dir, target, 100);
					}
				}; }) (this, dir, target)
			);

		} else if (dir === "right") {
			if (this.currentLeftTab === this.maxLeftTab) { return; }
			if ($(target).hasClass("x-item-disabled")) { return; }
			this.currentLeftTab++;
			var info = this.tabInfos[this.id + '-cfp-tabs-' + this.currentLeftTab];
			if (!info) { return; }
			var leftScrollerId = '#' + this.leftPanelId + " .wrap2 .x-tab-scroller-left";
			$(leftScrollerId).removeClass("x-item-disabled");
			var tabsWrapperId = '#' + this.leftPanelId + " .wrap2 .tabs-wrapper";
			this.scrollClicked = true;
			$(tabsWrapperId).animate({left: (info.offset > 0) ?
					"-" + (info.offset) + "px" : "0"}, speed,
				(function(player, dir, target) { return function() {
					player.scrollClicked = false;
					if (player.currentLeftTab === player.maxLeftTab) {$(target).addClass("x-item-disabled");}
					if(player.mouseDown && !$(target).hasClass("x-item-disabled")){
						player.onScrollerClicked(dir, target, 100);
					}
				}; }) (this, dir, target)
			);
		}
	},
	onRightScrollerClicked: function(dir) {
		// alert("onRightScrollerClicked(" + dir + ")");
	},
	updatePlayList: function(tabId, data, mode) {
		var divId = tabId + "-playlist";
		$("#" + divId).remove();
		var htmlArr = [
			"<div id=\"" + divId + "\">",
			"<div class=\"playlist-scroller-up\"></div>",
			"<div class=\"playlist-wrapper\">"
		];
		if (data.shows) {
			// iterating thru the show array
			for (var i = 0, len = data.shows.length; i < len; i++) {
				var show = data.shows[i];
				show.nextShow = data.shows[(i+1!=len)?i+1:0];
				show.nextShow.prevShow = show;
				htmlArr.push(this.getItemHtml(divId, show, mode));
			}
		}
		htmlArr.push(
			//mode === "browse" ? "<div class=\"playlist-loading\"> </div>" : "",
			"</div>", 
			"<div class=\"playlist-scroller-down\"></div>", 
			"</div>"
		);
		$('#' + this.rightPanelId + " .playlist-container").
			append(htmlArr.join(''));
			
		$("#" + divId + " .playlist-scroller-up").hover(
			function () { if (!$(this).hasClass("x-item-disabled")) {
				$(this).addClass("playlist-scroller-up-hover"); } },
			function () { $(this).removeClass("playlist-scroller-up-hover"); }
		).mousedown(
			(function(player, tabId) { return function() {
				if (!$(this).hasClass("x-item-disabled")) {
				player.onPlayListUpClicked(tabId, this); } }; }) (this, tabId)
		);
		$("#" + divId + " .playlist-scroller-down").hover(
			function () { if (!$(this).hasClass("x-item-disabled")) {
				$(this).addClass("playlist-scroller-down-hover"); } },
			function () { $(this).removeClass("playlist-scroller-down-hover"); }
		).mousedown(
			(function(player, tabId) { return function() {
				if (!$(this).hasClass("x-item-disabled")) {
					player.onPlayListDownClicked(tabId, this); } }; }) (this, tabId)
		);
		var pl = { divId: divId, data: data, topItem: 0,
			maxItem: (data.shows && data.shows.length > 0) ? data.shows.length - 1 : 0};
		this.playlists[tabId] = pl;
		this.updatePlayListScrollers(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-button").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-button").hide();
					} else {
						$("#" + itemId + " .added-mark").hide();
					}

				}
				if (mode === "queue") {
					$("#" + itemId + " .remove-button").click(
						(function(player, itemId, show) { return function(ev) {
							ev.stopPropagation();
							player.removeFromQueueClicked(itemId, show); 
							}; }) (this, itemId, show)
					);
					$("#" + itemId + " .added-mark").hide();
				}
				$("#" + itemId + " .image-wrapper").click(
					(function(player, show) { return function() {
						player.playMedia(show); }; }) (this, show)
				);
				$("#" + itemId + " .text-wrapper .title").hover(
					function () { $(this).addClass("title-hover"); },
					function () { $(this).removeClass("title-hover"); }
				).click(
					(function(player, show) { return function() {
						player.playMedia(show); }; }) (this, show)
				);
			}
		}
		if (mode === "browse") {
			this.currentPlayList = tabId;
		}
		
		if (!this.currentShow && data && data.shows && data.shows.length > 0 ){
			this.loadMedia(data.shows[0]);
		}
	},

	getItemHtml: function(divId, show, mode, hidden) {
		var itemId = divId + "-" + show.show_id;
		var htmlArr = [
			"<div class=\"playlist-item\" id=\"" + itemId + "\" " + (hidden == "hidden"? "style=\"display: none;\"":"") + " >",
			"<table cellpadding=\"0\" cellspacing=\"0\"><tr><td valign=\"top\">",
			"<div class=\"image-wrapper\">",
			(!show.images || !show.images.tmb) ? "" :
				"<img class=\"tumb\" src=\"" + show.images.tmb + "\" alt=\"" + show.title + "\"/>",
			(mode !== "browse") ? "<div class=\"remove-button\" title=\"Remove\"><span class=\"caption\"></span></div>" :
				"<div class=\"add-button\" title=\"Add\"><span class=\"caption\"></span></div>" +
				"<div class=\"added-mark\"><span class=\"caption\">Added</span></div>",
			"</div></td></tr><tr><td valign=\"top\">",
			"<div class=\"text-wrapper\">",
			"<span class=\"title\">" + show.title + "</span><br/>",
			(this.description == "true") ? "<div class=\"item-text\">" + show.description + "</div><br/>":"",
			"</div></td></tr></table></div>"
		];
		return htmlArr.join('');
	},
	getButtonHtml: function(cfg) {
		var arr = [
			"<table id=\"" + cfg.id + "\" class=\"button\" cellpadding=\"0\" cellspacing=\"0\">",
			"<tr><td valign=\"middle\" align=\"center\" class=\"button-icon\">",
			(!cfg.iconCls) ? "" : "<div class=\"" + cfg.iconCls + "\"></div>",
			"</td><td>" + cfg.text + "</td></tr></table>"
		];
		return arr.join('');
	},
	onPlayListUpClicked: function(tabId, target, speed) {
		if(this.scrollClicked) { return; }
		var pl = this.playlists[tabId];
		if (!pl || !pl.data || !pl.data.shows) { return; }
		pl.topItem-=1;
		var show = pl.data.shows[pl.topItem];
		var divId = pl.divId;
		var itemId = divId + "-" + show.show_id;
		var h = $("#" + itemId).outerHeight(true);
		speed = speed?speed:500;
		this.scrollClicked = true;
		$("#" + divId + " .playlist-wrapper").animate({top: "+=" + 1*h + "px"}, speed,
			(function(player, tabId, pl, target) { return function() {
				player.scrollClicked = false;
				player.updatePlayListScrollers(pl);
				if(player.mouseDown && !$(target).hasClass("x-item-disabled")){
					player.onPlayListUpClicked(tabId, target, 100);
				}
			}; }) (this, tabId, pl, target)
		);
	},
	onPlayListDownClicked: function(tabId, target, speed) {
		if(this.scrollClicked) { return; }
		var pl = this.playlists[tabId];
		if (!pl || !pl.data || !pl.data.shows) { return; }
		var show = pl.data.shows[pl.topItem];
		var divId = pl.divId;
		var itemId = divId + "-" + show.show_id;
		var h = $("#" + itemId).outerHeight(true);
		pl.topItem+=1;
		speed = speed?speed:500;
		this.scrollClicked = true;
		
		$("#" + divId + " .playlist-wrapper").animate({top: "-=" + 1*h + "px"}, speed,
			(function(player, tabId, pl, target) { return function() {
				player.scrollClicked = false;
				player.updatePlayListScrollers(pl);
				if ( !$(target).hasClass("x-item-disabled") ){
					if ( player.mouseDown ) { player.onPlayListDownClicked(tabId, target, 100); }
				}else{
					player.loadNextPage(tabId, target);
				}
			}; }) (this, tabId, pl, target)
		);
	},
	loadNextPage: function(tabId, scrollerDownTarget){
		if( tabId == this.queueId || 
			tabId != this.currentPlayList ){ return; }

		var info = this.tabInfos[tabId];
		var pl = this.playlists[tabId];
		if ( !info || !pl || !pl.data || !pl.data.pagination || "" == pl.data.pagination.next /*|| !pl.data.shows*/ ) { return; }

		var divId = pl.divId;
		$("#" + divId + " .playlist-wrapper").
			append("<div class=\"playlist-loading\"> </div>");

		var 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: info.cfg.feed.indexOf(".json") != -1 ?  "json" : "jsonp",
			success: (function(player, tabId, scrollerDownTarget) { return function(data, status) {player.addNextPageToList(tabId,  data, scrollerDownTarget)}; }) (this, tabId, scrollerDownTarget)

		});
		
	},
	addNextPageToList: function(tabId,  data, scrollerDownTarget){
		var pl = this.playlists[tabId];
		if (!pl || !pl.data || !pl.data.shows || !data || !data.shows) { return; }
		var divId = pl.divId;
		var htmlArr = [];

		// 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.nextShow = pl.data.shows[0];
			show.nextShow.prevShow = show;
			show.prevShow = pl.data.shows[j-1];
			show.prevShow.nextShow = show;
			
			htmlArr.push(this.getItemHtml(divId, show, "browse", "hidden"));
		}

		$("#" + divId + " .playlist-wrapper").
			append(htmlArr.join(''));
		pl.maxItem = pl.data.shows.length - 1;
		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-button").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-button").hide();
			} else {
				$("#" + itemId + " .added-mark").hide();
			}

			$("#" + itemId + " .image-wrapper").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
			$("#" + itemId + " .text-wrapper .title").hover(
				function () { $(this).addClass("title-hover"); },
				function () { $(this).removeClass("title-hover"); }
			).click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
		}	
		var itemId = divId + "-" + data.shows[data.shows.length-1].show_id;
		$("#" + itemId + " .tumb").ready(
			(function(player, tabId, scrollerDownTarget, divId) { return function() {
				setTimeout(
					(function(player, tabId, scrollerDownTarget, divId) { return function() {
						player.updatePlayListScrollers(pl);
						$("#" + divId + " .playlist-wrapper .playlist-loading").remove();
						$("#" + divId + " .playlist-wrapper .playlist-item").show();
						if ( player.mouseDown ) { player.onPlayListDownClicked(tabId, scrollerDownTarget, 500); }
						}; }) (player, tabId, scrollerDownTarget, divId)
				, 500)
			}; }) (this, tabId, scrollerDownTarget, divId)
		);
	},
	addToQueueClicked: function(itemId, show) {
		this.queueData.shows.push(show);
		show.itemId = itemId;
		this.queueData.sources[itemId] = itemId;
		var tabId = this.id + "-cfp-tabs-queue";
		var divId = tabId + "-playlist";
		$("#" + itemId + " .added-mark").show();
		$("#" + itemId + " .add-button").hide();
		$("#" + tabId + " .tab-link span").text(
				"Queue (" + this.queueData.shows.length + ")");
		var pl = this.playlists[tabId];
		if (pl) {
			var txt = this.getItemHtml(divId, show, "queue");
			$("#" + divId + " .playlist-wrapper").append(txt);
			pl.maxItem++;
			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.nextShow = this.queueData.shows[(i+1!=len)?i+1:0];
					show.nextShow.prevShow = show;
				}
			}
			
			var queueItemId = divId + "-" + show.show_id;
			$("#" + queueItemId + " .remove-button").click(
					(function(player, queueItemId, show) { return function(ev) {
						ev.stopPropagation();
						player.removeFromQueueClicked(queueItemId, show); 
						}; }) (this, queueItemId, show)
			);
			
			$("#" + queueItemId + " .image-wrapper").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
			$("#" + queueItemId + " .text-wrapper .title").hover(
				function () { $(this).addClass("title-hover"); },
				function () { $(this).removeClass("title-hover"); }
			).click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
			this.updatePlayListScrollers(pl);
			this.selectItem(this.currentShow);
		}
	},
	removeFromQueueClicked: function(itemId, show){//debugger;
		this.queueData.shows.remove(show);
		this.queueData.sources[show.itemId] = null;
		var tabId = this.id + "-cfp-tabs-queue";
		var divId = tabId + "-playlist";
		$("#" + show.itemId + " .added-mark").hide();
		$("#" + show.itemId + " .add-button").show();
		$("#" + tabId + " .tab-link span").text(
				"Queue (" + this.queueData.shows.length + ")");
		var pl = this.playlists[tabId];
		if (pl) {
			pl.maxItem--;
			$("#" + itemId).remove();
			this.updatePlayListScrollers(pl);
		}
		show.prevShow.nextShow = show.nextShow;
		show.nextShow.prevShow = show.prevShow;
		show = null;
	},
	updatePlayListScrollers: function(pl) {
		if (pl.topItem > 0 && pl.maxItem > 0) {
			$("#" + pl.divId + " .playlist-scroller-up").removeClass("x-item-disabled");
		}
		if (pl.topItem < pl.maxItem) {
			$("#" + pl.divId + " .playlist-scroller-down").removeClass("x-item-disabled");
		}
		if (pl.topItem === 0) {
			$("#" + pl.divId + " .playlist-scroller-up").
				removeClass("playlist-scroller-up-hover").
				addClass("x-item-disabled");
		}

		if (pl.topItem >= pl.maxItem) {
			$("#" + pl.divId + " .playlist-scroller-down").
				removeClass("playlist-scroller-down-hover").
				addClass("x-item-disabled");
		}
	},
	playMedia: function(show) {
		if (this.playerInstance) {
			this.selectItem(show);
			try{
				this.playerInstance.externalCastfirePlayVideo(show.url);
			}catch(e){}
		}
	},
	loadMedia: function(show, deep) {
		deep = deep?deep:0;
		if(deep>4) return;
		
		if (this.playerInstance) {
			this.selectItem(show);
			try{
				this.playerInstance.externalCastfireLoadVideo(show.url);
			}catch(e){
				setTimeout(
				(function(player, show, deep) { return function() {
					player.loadMedia(show,++deep); }; }) (this, show, deep)
				, 500);
			}
		}
	},
	onCompleteMedia: function(url){
		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;
			var	itemId = curPL + "-playlist-" + show.show_id;
			show.oDiv = $("#" + itemId);
			show.oDiv.addClass("playlist-item-selected");
			this.currentShow = show;
		}
	},
	generateEmbed: function() {
		var plId = "castfire_player-" + this.id;
		var url = "http://p.castfire.com/" + this.guid + "/video/unloaded";
		var tmpl = [
				'<object width="', this.playerWidth, '" height="100%" id="', plId ,'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">',
					'<param name="movie" value="http://p.castfire.com/' + this.guid + '/video/unloaded"></param>',
					'<param name="allowFullScreen" value="true"></param>',
					'<param name="allowScriptAccess" value="always"></param>',

					'<embed ',
						'width="', this.playerWidth, '" height="100%" ',
						'src="http://p.castfire.com/' + this.guid + '/video/unloaded" ',
						'id="', plId ,'" ',
						'type="application/x-shockwave-flash" ',
						'allowFullScreen="true" ',
						'allowScriptAccess="always">',
					'</embed>',
				'</object>'
		];
		return tmpl.join('');
	},
	generateInitialEmbed: function(guid, width, height, playerId, show) {
		/*
		<embed id="castfire_player_1812_flv" class="castfire_player"
			height="354" width="425" pluginspage="http://www.macromedia.com/go/getflashplayer"
			type="application/x-shockwave-flash" allowscriptaccess="always"
			name="castfire_player_1812_flv" wmode="transparent" quality="low"
			src="http://p.castfire.com/cHNHf/video/1812/webbalert_2007-08-02-024247.flv"/>
		 */
		var plId = this.id + "-" + show.show_id;
		var url = "http://p.castfire.com/" + show.show_id + "/unloaded/";
		/*
		var tmpl = [
			"<embed id=\"" + plId + "\" class=\"castfire_player\"",
			" height=\"" + height +  "\" width=\"" + width + "\" ",
			" pluginspage=\"http://www.macromedia.com/go/getflashplayer\"",
			" name=\"" + plId + "\" wmode=\"transparent\" quality=\"low\"",
			" src=\"" + url + "\"/>"
		];
		*/
		var tmpl = [
			'<object width="', width, '" height="', height,
			'" id="player', playerId, '" name="player', playerId,
			'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">',
			'<param name="movie" value="' + url + '"></param>',
			'<param name="allowFullScreen" value="true"></param>',
			'<param name="allowScriptAccess" value="always"></param>',
			'<embed width="', width , '" height="', height,
			'" src="' + url + '" id="player', playerId,
			'" name="player', playerId, '" type="application/x-shockwave-flash"',
			' allowFullScreen="true" allowScriptAccess="always"></embed>',
			'</object>'
		];
		return tmpl.join('');
	}
});

$.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;
	}
});