/**
 * CastFire Javascript player.
 * (c) CastFire.com 2009
 * @author Ivan Kirnev <ivan.kirnev@gmail.com>
 */

var CastfirePlayer = { version: "1.0" };
// Extending CastfirePlayer
$J.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
	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.embedId = this.id + '-cfp-embedId'; // div Id of player embeded object
	this.browseId = this.id + '-cfp-tabs-browse'; // div Id of player's browse button object
	this.totalWidth = conf.totalWidth;
	this.playerHeight = conf.playerHeight;
	this.playListHeight = 210;
	this.description = conf.description;
	this.selectedTabIdx = 0;
	this.mouseOver = false;
	this.scrollClicked = false;
	this.el = null;
	this.playlists = {};
	this.currentPlayList = null;
	this.currentShow = null;
	this.isInited = false;
};

// Extending castfire_player class with members and methods
$J.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)};
		
		this.el = $J('#' + this.id);
		if( this.el && this.el.length > 0 ){
			this.el[0].innerHTML = this.generateHtml();
		}

		// setting up sizes of elements
		$J("#" + this.mainContainerId).width(this.totalWidth);
		$J("#" + this.leftPanelId + " .castfire-player-container").width(this.totalWidth).height(this.playerHeight);
		$J('#' + this.rightPanelId + " .playlist-container").width(this.totalWidth);
		

		this.playerInstance = this.getPlayerInstance("castfire_player-" + this.id);
		
		// seting active tab
		//this.onTabClicked();
		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
		];
		arr.push(
			"<div id=\"" + this.embedId + "\"class=\"castfire-player-container\">",
			this.generateEmbed(),
			"</div></div>",
			"<div id=\"" + this.rightPanelId + "\" class=\"right-column\">"
		);
		
		arr.push(
			"<div class=\"playlist-container\">",
			"</div>",
			"</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() {
		var tabId = this.id + '-cfp-tabs-' + this.selectedTabIdx;
		if(this.currentPlayList == tabId) return;
		this.currentPlayList = tabId;
		var divId = tabId + "-playlist";
		//$J("#" + divId).remove();
		var htmlArr = [
			"<div id=\"" + divId + "\">",
			"<div class=\"scroller-up\"></div>",
			"<div class=\"playlist-loading\"> </div>",
			"<div class=\"scroller-down\"></div>", 
			"</div>"
		]
		$J('#' + this.rightPanelId + " .playlist-container").
			append(htmlArr.join(''));
		//return;//todo:

		var resp = $J.ajax({
			type: "GET", cache: false, async: false,
			url: this.initConf.tabs[0].feed,
			dataType: this.initConf.tabs[0].feed.indexOf(".json") != -1 ?  "json" : "jsonp",
			success: (function(player, tabId) { return function(data, status) {
						player.updatePlayList(tabId, data, "browse");}; }) (this, tabId)

		});
	},
	updatePlayList: function(tabId, data, mode) {
		var divId = tabId + "-playlist";
		$J("#" + divId).remove();
		var htmlArr = [
			"<div id=\"" + divId + "\">",
			"<div class=\"scroller-up\"></div>",
			"<ul class=\"rightnavigation\">"
		];

		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, i));
			}
		}
		htmlArr.push(
			"</ul>",
			"<div class=\"scroller-down\"></div>", 
			"</div>"
		);
		$J('#' + this.rightPanelId + " .playlist-container").
			append(htmlArr.join(''));
			
		var divScroll = $J('#' + divId).divScroll({
			scrollType: "horizontal",
			width: this.totalWidth,
			scrollSpeed:this.initConf.scrollSpeed,
			scrollWrapper:"ul.rightnavigation",
			callbackEndForward: (function(player, tabId) { return function() {
								player.loadNextPage(tabId);}; }) (this, tabId)
		});

		var pl = { divId: divId, data: data, divScroll: divScroll, topItem: 0,
			maxItem: (data.shows && data.shows.length > 0) ? data.shows.length - 1 : 0};
		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;
				$J("#" + itemId + " .image").click(
					(function(player, show) { return function() {
						player.playMedia(show); }; }) (this, show)
				);
				$J("#" + itemId + " h3").click(
					(function(player, show) { return function() {
						player.playMedia(show); }; }) (this, show)
				);
			}
		}
		
		/*if (!this.currentShow && data && data.shows && data.shows.length > 0 ){
			if(this.initConf.show) {
				this.playMedia(null, this.initConf.show);
			} else {
				this.loadMedia(data.shows[0]);
			}
		}*/
	
	},

	getItemHtml: function(divId, show, mode, i, hidden) {
		var itemId = divId + "-" + show.show_id;
		var date = new Date(show.pubdate);
		var htmlArr = [
			"<li id=\"" + itemId + "\" " + (hidden == "hidden"? " style=\"display: none;\" ":"") + " " + (i%2 == 1 ? " class=\"bg\" " : "") + " >",
				"<span>",
					"<h3>" + show.title + "</h3>",
					"<p>" + date.format('D, M j, Y') + "</p>",
					"<a class=\"image\">",
					(!show.images || !show.images.tmb) ? "" :
						"<img src=\"" + show.images.tmb + "\" alt=\"\">",
					"</a>",
					(this.description == "true") ? "<p class=\"description\">" + show.description + "</p>":"",
				"</span>",
			"</li>"
		];
		return htmlArr.join('');
	},
	loadNextPage: function(tabId){
		var pl = this.playlists[tabId];
		if (this.loading || !pl || !pl.data || !pl.data.pagination || "" == pl.data.pagination.next /*|| !pl.data.shows*/ ) { return; }

		pl.divScroll.append("<li class=\"playlist-loading\"> </li>");
		pl.divScroll.onScrollerForward(500, true, function(){});
		this.loading = true;
		
		var itemsPerPage = "10";
		var feed = pl.data.pagination.next.replace(/(^.*\/json\/\d+:)\d+(\/.*$)/i, "$1" + itemsPerPage + "$2");
		var resp = $J.ajax({
			type: "GET", cache: false, async: true,
			url: feed, //pl.data.pagination.next,
			dataType: feed.indexOf(".json") != -1 ?  "json" : "jsonp",
			success: (function(player, tabId) { return function(data, status) {
				player.loading = false;
				player.addNextPageToList(tabId,  data)}; }) (this, tabId)
		});
		
	},
	addNextPageToList: function(tabId,  data){
		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", j, "hidden"));
		}

		$J("#" + divId + " .rightnavigation").
			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;
			
			$J("#" + itemId + " .image").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
			$J("#" + itemId + " h3").click(
				(function(player, show) { return function() {
					player.playMedia(show); }; }) (this, show)
			);
		}	
		var itemId = divId + "-" + data.shows[data.shows.length-1].show_id;
		$J("#" + itemId + " .tumb").ready(
			(function(player, pl, divId) { return function() {
				setTimeout(
					(function(player, pl, divId) { return function() {
						pl.divScroll.remove(".playlist-loading");
						pl.divScroll.show("li");
					}; }) (player, pl, divId)
				, 500)
			}; }) (this, pl, divId)
		);
	},
	play: function(url) {
		this.playMedia(null, url);
	},
	run: function(url){
		this.onTabClicked();
		this.play(url);
		$J('#' + this.rightPanelId).show().css({ 'visibility' : 'visible' });
	},
	stop: function(url){
		this.loadMedia(null, url);
		$J('#' + this.rightPanelId).hide().css({ 'visibility' : 'hidden' });
	},
	playMedia: function(show, url, deep) {
		deep = deep?deep:0;
		if(deep>10) return;
		if (this.playerInstance) {
			if(show) this.selectItem(show);
			try{
				this.playerInstance.externalCastfirePlayVideo(url?url:show.url);
			}catch(e){
				setTimeout(
				(function(player, show, deep) { return function() {
					player.playMedia(show, url, ++deep); }; }) (this, show, deep)
				, 500);
			}
		}
	},
	loadMedia: function(show, url, deep) {
		deep = deep?deep:0;
		if(deep>10) return;
		
		if (this.playerInstance) {
			this.selectItem(show);
			try{
				this.playerInstance.externalCastfireLoadVideo(url?url:show.url);
			}catch(e){
				setTimeout(
				(function(player, show, deep) { return function() {
					player.loadMedia(show, url, ++deep); }; }) (this, show, deep)
				, 500);
			}
		}
	},
	onCompleteMedia: function(url){
		if(!this.currentShow) return;
		var tmpShow = this.currentShow;
		this.playMedia(tmpShow.nextShow);

	},
	selectItem: function(show) {
		if(this.currentShow && this.currentShow.oDiv){
			this.currentShow.oDiv.removeClass("playlist-item-selected");
		}
		if(show){
			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="100%" 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="100%" 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(''); //todo:
	},
	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('');
	}
});

$J.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;
	}
});