/**
 * bam.zPlayer : A singleton representing a lightbox-style, draggable Flv Player
 *
 * To use: call bam.zPlayer.play(), and pass one of:
 *  - String representing a content_id
 *  - Number representing a content_id
 *  - Object containing all required information for clip playback (headline, url, etc.)
 *
 * Z Player now supports a related content state for MLB homepages
 *
 */

bam.zPlayer = (function(){

	$.easing.def = "easeInOutExpo";
												
	var _initialized   = false,
			_isPlaying     = false,
			_playInitiated = false, // used to prevent double clicks on play button			
			_isOpen        = false,
			
			_previousOverlayCSS,
			_bgImage,
			_playerContext = "Z Player",
			_psKeys = ["MLB_FLASH_800K_STREAM_VPP", "MLB_FLASH_800K_STREAM", "MLB_FLASH_1000K_PROGDNLD", "MLB_FLASH_800K_PROGDNLD"],

			// variables used for the related content leave-behind
			_playedVideos = [], // local cache - loadClipData saves it here
			_relatedIsDisplayed = false,
			_relatedCssLoaded = false,
			_replayHandlerAssigned = false,
			_topicId = "";
	
	
	/**
	* Private method for detecting if the browser is Firefox 2 on Mac.
	* This browser doesn't like the opacity/flash/etc. combo, so we redirect to VPP
	* @return boolean
	*/
	function _isMacXFF2(){
		var userAgent = navigator.userAgent.toLowerCase();
		if (/firefox[\/\s](\d+\.\d+)/.test(userAgent)) {
			var ffversion = new Number(RegExp.$1);
			if (ffversion < 3 && userAgent.indexOf("mac") != -1){ return true; }
		}
		return false;
	}
	
	
	/**
	* Private method for checking if the related content leave-behind should be displayed.
	* @return boolean	
	*/
	function _showRelatedContentLeaveBehind(){
		return (
			(typeof(club)!=="undefined" && typeof(section)!=="undefined" && typeof(page_id)!=="undefined") &&
			(section==="homepage" || (section==="world_series" && page_id==="ps_2009_ws_landing"))
		);
	}
	
	
	/* private jQuery object for controlling custom events */
	var _$event = $({supportedEvents:["beforePlay","afterPlay","beforeClose","afterClose"]});

	var _self = {
		
		debugMode     : false,
		curClipData   : null,
		flashPlayer   : null,
		playerProps   : {w:640, h:400},
		zoomStartDims : {w:"33px",  h:"22px"},
		zoomEndDims   : {w:"660px", h:"450px"},
		content_id    : null,		// @TODO Why does this exist in addition to value in curClipData?
		
		// flag used to force incompatible browsers (currently only MacXFF2) to the VPP for playback
		redirectBadBrowsers : true, 
		

		log: function(msg){
			if (typeof console!="undefined" && _self.debugMode){ console.log("bam.zPlayer: " + msg); }
		},
		
		bind: function(eventName, dataOrFn, fnOrUndefined){
			_$event.bind(eventName, dataOrFn, fnOrUndefined);
		},
		
		unbind: function(eventName, fn){
			_$event.unbind(eventName, fn);
		},
		
		
		/** prePlay() and postClose() are DEPRECATED - USE bind("beforePlay") and bind("afterClose") instead */
		prePlay: function(){},
		postClose: function(){},
		
		
		/**
		* initializes zPlayer by loading required JavaScript files (if not already loaded)
		* and appending required elements to the DOM.
		*/
		init: function(){
			_self.log("initializing.  importing scripts");
			// __getScriptSync() is a local shortcut method.  avoids setting global props via ajaxSetup
			var __getScriptSync = function(url){ $.ajax({type:"GET", async:false, cache:true, url:url, dataType:"script"}); }; 
			if (typeof bam.FlvPlayer == "undefined") __getScriptSync("/shared/scripts/bam.FlvPlayer.js");
			if (typeof bam.media     == "undefined") __getScriptSync("/shared/scripts/bam.media.js");
			__getScriptSync("/shared/scripts/external/jquery.easing.js");
			__getScriptSync("/shared/scripts/external/jquery-ui-draggable-1.7.1.min.js");
			bam.loadSync("/shared/scripts/bam/bam.overlay.js");
			_bgImage = new Image();  _bgImage.src = "/shared/images/bam/zPlayer/bg.png";
			var zPlayerHtml = '\
				<div id="zPlayerOuter" style="display:none; position:absolute; background:no-repeat; top:0; left:0; width:680px; height:460px; overflow:hidden; z-index:999999;">\
					<div id="zPlayerInner" style="margin:0 auto; width:'+_self.zoomStartDims.w+'; background:#222; height:'+_self.zoomStartDims.h+'; overflow:hidden;">\
						<div id="zPlayerClipInfo" style="width:auto; overflow:hidden; margin-top:20px;">\
							<div id="zPlayerHeadline" style="float:left; font:bold 12px arial,helvetica; color:#fff; margin-top:2px; margin-left:9px;"></div>\
							<a href="javascript:bam.zPlayer.close()" style="float:right; margin-right:8px;"><img src="/shared/images/bam/zPlayer/buttonClose.png" alt="Close" title="Close" style="border:0;"/></a><br/>\
						</div>\
						<div id="zPlayer_flvContainer" style="margin:4px 8px 8px 9px;"></div>\
						<div id="zPlayer_leaveBehind" style="display:none;"></div>\
					</div>\
				</div>';
			$(zPlayerHtml).appendTo("body");
			$("#zPlayerInner").css({opacity:0});
			$("#zPlayerClipInfo").hover(function(){ $(this).css({cursor:"move"}); }, function(){ $(this).css({cursor:"default"}); })
			bam.overlay.init();
			_initialized = true;
		},		


		/**
		* Updates the private psKeys (playback scenario keys) array. This allows 
		* instances of Z Player to set their own playback scenario(s) and not use
		* the default ones.
		* @param newKeys Array
		*/
		setPlaybackScenarioKeys: function(newKeys){
			if (newKeys instanceof Array){
				_psKeys = newKeys;
			}
		},
		

		/**
		* Public method for initiating playback.
		* Accepts a single parameter which can be either a string (content_id) or 
		* an object containing all of the data required to display and play a clip.
		* @param clipData Object, String (content_id) OR Number (content_id)
		*/
		play: function(clipData /*, topicId */){
			if (_playInitiated) return; // if user clicked on the play button already, do nothing.  this prevents weird behavior on double-click.
			_playInitiated = true;
			switch (typeof clipData){
				case "string" : _self.content_id = clipData; break;
				case "number" : _self.content_id = clipData+""; break; // convert to string
				case "object" : _self.content_id = clipData.content_id; _self.curClipData = clipData; break;
				default : throw new Error("Invalid data passed to bam.zPlayer.play()"); return false;
			}
			if (arguments[1]){
				_topicId = arguments[1];
			}
			if (_isMacXFF2() && _self.redirectBadBrowsers){
				location.href = "/media/video.jsp?content_id="+_self.content_id+"&topic_id="+_topicId; // redirect Mac users with Firefox 2.x browsers to VPP due to flash/overlay/flash issue
				return;
			}
			_$event.trigger("beforePlay");
			if (!_initialized){
				_self.init();
			}
			if (bam.tracking){
				bam.tracking.track({
					async:{
						isDynamic    : false,
						compName     : "Z Player Interaction",
						compActivity : "Z Player Launch",
						actionGen    : true
					}
				});
			}
			function startPlayback(){
				_self.log("starting playback");
				var fullWidth = parseInt($("body").innerWidth());
				var elemWidth = parseInt($("#zPlayerOuter").css("width"));
				var posLeft   = ((fullWidth/2) - (elemWidth/2)) - 65; // offset so that its directly over media wall
				var posTop    = $(document).scrollTop() + 95;
				var bgUrl     = "/shared/images/bam/zPlayer/bg.png";
				if ((/MSIE (6)/.test(navigator.userAgent) && navigator.platform == "Win32")){ bgUrl = "/shared/images/bam/zPlayer/bg.gif"; } // don't use png for IE6 (alpha+drag+flash+link problems)
				$("#zPlayerOuter").css({top:posTop+"px",left:posLeft+"px"}).show().draggable({containment:"document", cancel:"#zPlayer_flvContainer, #zPlayer_leaveBehind"});
				$("#zPlayerInner").animate({width:_self.zoomEndDims.w, height:_self.zoomEndDims.h, opacity:1}, "normal", function(){
					$("#zPlayerOuter").css({"background-image":"url("+bgUrl+")"});
					setTimeout(function(){ $("#zPlayerInner").css({"background":"none"}) }, 100);
				});
				_isOpen = true;
				_self.killFlvPlayer(); // will check if exists first
				_self.createFlvPlayer();
				_$event.trigger("afterPlay");				
			};
			if (!_isMacXFF2()){			
				if ($("#overlay").length){
					_previousOverlayCSS = {"background-color":$("#overlay").css("background-color"), "opacity":$("#overlay").css("opacity")};
					$("#overlay").click(function(){ _self.close({compActivity:"Z Player Outside Close Click"}); });
				}
				bam.overlay.setCSS({"background-color":"#ffffff"});			
				bam.overlay.show({fadeSpeed:"fast", opacity:"0.3", callback:startPlayback});
			}
			else{
				$("embed,iframe").css("visibility","hidden");
				startPlayback();				
			}
		},
		

		/**
		* Creates instance of FLV Player as a public property (bam.zPlayer.flashPlayer)
		*/
		createFlvPlayer: function(){
			_self.log("createFlvPlayer()");
			$("#zPlayer_flvContainer").show(); // related content hides this div which prevents future loading of flvplayer. this ensures proper loading
			_self.flashPlayer = new bam.FlvPlayer({
				hideControls       : false,
				skin               : "/flash/video/y2009/skins/mlb_media_landing_full.swf",
				self               : "bam.zPlayer.flashPlayer",
				endPosterPath      : _showRelatedContentLeaveBehind() ? "/images/000000.gif" : "/shared/images/bam/zPlayer/buttonReplay.png",
				width              : _self.playerProps.w,
				height             : _self.playerProps.h,
				elemId             : "flashPlayer",
				containerId        : "zPlayer_flvContainer",
				wmode              : $.browser.msie ? "window" : "transparent",
				defaultVolume      : 60,
				debugMode          : _self.debugMode,
				onPlayerLoaded     : _self.onFlvPlayerLoaded,
				onPlaylistComplete : _self.onPlaylistComplete,
				onCollapse         : _self.onCollapse,
				pageComponent      : "z_player" // used when assembling siteSection value for FW preroll
			});
		},


		/**
		* Handler triggered by flv player (SWF) after it has loaded
		*/
		onFlvPlayerLoaded: function(){
			_self.log("flvPlayer.onFlvPlayerLoaded()");
			_self.playClip(_self.content_id);		
		},


		/**
		* Handler triggered by flv player (SWF) after it has completed playback of the playlist
		*/
		onPlaylistComplete: function(){
			if (bam.tracking) bam.tracking.track({videoComplete:{playerContext:_playerContext}});
			_self.flashPlayer.execute("exitFullScreen");
			_isPlaying = false;
			// show leave-behind for mlb and club homepages
			if (_showRelatedContentLeaveBehind()){
				_self.showRelatedContent();
			}
			_self.log("done with onPlaylistComplete");			
		},
		
		
		/**
		* Appends CSS for related content to the head of the DOM.  Only once.
		*/
		loadRelatedCss: function(){
			if (!_relatedCssLoaded){
				_self.log("loadRelatedCSS(): loading since its hasn't been loaded already");
				var styleHtml = "\
					<style>\
					#zPlayer_leaveBehind  {width:635px; height:404px; overflow:hidden; margin-left:12px; margin-top:5px; background:url(/shared/images/bam/zPlayer/bgRelatedContent.gif) no-repeat;}\
					#zPlayer_replayInfo   {width:635px; height:98px; margin-bottom:7px; overflow:hidden;}\
					#zPlayer_replayButton {float:left; display:block; width:113px; height:98px; text-indent:-999px;}\
					#zPlayer_clipThumb    {float:left; width:124px; border:1px solid #298EDB; margin-top:13px;}\
					#zPlayer_clipTitle    {float:left; width:350px; padding:12px 0 0 12px; font:bold 14px arial,helvetica; color:#298EDB;}\
					#zPlayer_clipBlurb    {float:left; width:335px; height:60px; padding:12px 0 0 12px; font:normal 11px arial,helvetica; color:#fff;}\
					#zPlayer_relatedVideos              {width:635px; height:285px;}\
					#zPlayer_relatedVideos ul           {margin:35px 0 0 0; padding:0; list-style:none; width:635px; height:260px; overflow:hidden;}\
					#zPlayer_relatedVideos ul li        {margin:15px 15px 0 15px; padding:0; float:left; width:126px; height:114px; overflow:hidden;}\
					#zPlayer_relatedVideos ul li a      {text-decoration:none;}\
					#zPlayer_relatedVideos ul li img    {border:1px solid #298EDB; display:block; width:124px; height:70px;}\
					#zPlayer_relatedVideos ul li div    {border:0; margin:4px 4px 0 4px; font:10px arial,helvetica; line-height:12px; color:#fff; height:35px;}\
					* html #zPlayer_relatedVideos ul li {margin-left:10px;}\
					</style>";
				$("head").append(styleHtml);
				_self.log("loadRelatedCSS(): done loading css");
				_relatedCssLoaded = true;
			}
		},

		
		/**
		* Displays leave-behind screen with replay option and related videos which
		* link to the Video Playback Page.
		*/
		showRelatedContent: function(){
			_self.log("showRelatedContent");			
			_self.loadRelatedCss();
			_self.killFlvPlayer(function(){ 
				$("#zPlayer_flvContainer").hide();
				$("#zPlayerHeadline").text("");
				_self.log("cleared headline");
				$("#zPlayer_leaveBehind").append('\
					<div id="zPlayer_replayInfo">\
						<a id="zPlayer_replayButton" href="#">Click to Replay</a>\
						<div id="zPlayer_clipThumb"><img src="'+_self.curClipData.thumb+'"></div>\
						<div id="zPlayer_clipTitle">'+_self.curClipData.headline+'</div>\
						<div id="zPlayer_clipBlurb">'+_self.curClipData.blurb+'</div>\
					</div>\
					<div id="zPlayer_relatedVideos"></div>').show();
				if (!_replayHandlerAssigned){
					$("#zPlayer_replayButton").live("click", function(){
						_self.log("--------------- REPLAY ---------------");
						$("#zPlayer_leaveBehind").empty().hide();
						$("#zPlayer_flvContainer").show();
						_relatedIsDisplayed = false;
						_self.createFlvPlayer();
					});
					_replayHandlerAssigned = true;
				}
				_self.loadRelatedContent();
			});													
		},
		
		
		/**
		* Loads related content from an XML file via ajax, and calls renderRelatedContent.
		*/
		loadRelatedContent: function(){
			_self.log("loadRelatedContent");
			var xmlFilePath = (_topicId) ? "/gen/multimedia/topic/"+_topicId+".xml" : "/gen/"+club+"/components/multimedia/topvideos.xml";  // correct these values
			if (typeof(section)!=="undefined" && section==="world_series"){ 
				xmlFilePath = "/gen/ps/2009/ws/series/ws/media_full.xml"; // override data url for worldseries.com
			}
			$.ajax({
				type     : "GET",
				async    : false,
				url      : xmlFilePath,
				dataType : "xml",
				error    : function(){ _self.log("loadRelatedContent(): Error loading " + xmlFilePath); },
				success  : function(xmlData){
					if (_topicId){ // get index from topic config, then render that
						_self.log("Looking for topic index in the topic config....");
						$.ajax({
							type     : "GET",
							async    : false,
							url      : $("topic video_index", xmlData).attr("src"),
							dataType : "xml",
							error    : function(){ 
								_self.log("loadRelatedContent(): Error loading " + xmlFilePath);
								$("#zPlayer_relatedVideos").html("<div style='margin:80px 0 0 20px; color:#fff; font:11px arial;'>Related content is temporarily unavailable.</div>");
							},
							success  : _self.renderRelatedContent
						});
					}
					else { // just render index data (no topic to worry about)
						_self.renderRelatedContent(xmlData);
					}
				}
			});
		},
		

		/**
		* Parses XML DOM object and renders related videos from it by injecting new
		* html into the leave-behind related videos container.
		* @param xml XML DOM object returned by $.ajax()
		*/
		renderRelatedContent: function(xml){
			_self.log("renderRelatedContent");
			var count = 0,
					max   = 8,
					html  = "<ul>",
					items = [],
					$curItem;
			function getVppUrl(contentId){
				return "/media/video.jsp?content_id=" + contentId + ((typeof club!=="undefined" && club!=="mlb")?"&c_id="+club:"") + ((_topicId)?"&topic_id="+_topicId:"");
			}
			$("data item", xml).each(function(i, curItem){
				$curItem = $(curItem);
				items.push({
					content_id : $curItem.attr("content_id"),
					headline   : $curItem.find(">title").text() || $curItem.find(">headline").text(),  // either Newsroom or Homebase format, also below
					thumb      : $curItem.find(">pictures picture[type='small-text-graphic'] url").text() || $curItem.find(">images image[type='7']").text()
				});
				if (items.length > 9){ return; }
			});
			if (items.length < max){
				max = items.length;
			}
			while ( (count < max) && ($.inArray(items[count].content_id, _playedVideos)===-1) ){
				html += "<li><a href='" + getVppUrl(items[count].content_id) + "'><img src='"+items[count].thumb+"'/><div>"+items[count].headline+"</div></a></li>";
				count++;
			}
			html += "</ul>";
			$("#zPlayer_relatedVideos").html(html);
			_relatedIsDisplayed = true;
			_self.log("rendered related content");
		},

		
		/**
		* Handles the onCollapse event from the FlvPlayer(swf). That event is generally 
		* triggered by end-of-stream marker in video content itself.
		*/
		onCollapse: function(){
			setTimeout( function(){
				_self.collapsePlayer();
				if (bam.tracking){
					bam.tracking.track({
						async:{
							isDynamic    : false,
							compName     : "Z Player Interaction",
							compActivity : "Z Player Auto Close",
							actionGen    : true
						}
					});
				}
			}, 500);
		},

		
		/**
		* If the instance of flvPlayer exists, it empties the container and deletes the object.
		*/
		killFlvPlayer: function(callback){
			if (_self.flashPlayer){
				_self.log("killFlvPlayer(): stopping, then killing flv player");
				_self.flashPlayer.execute("stopPlaylist");
				_self.flashPlayer.clearPlaylist();
				delete(_self.flashPlayer);
				setTimeout(function(){ 
					$("#zPlayer_flvContainer").empty();
					if (typeof(callback)==="function"){
						callback();
					}
				}, 10);
			}
			else {
				_self.log("killFlvPlayer(): player did not exist.  doing nothing.");
			}
		},
		
		
		/**
		* Loads data for content_id (unless its already loaded), and plays clip
		* @param content_id String (integer doesn't work here)
		*/
		playClip: function(content_id){
			_isPlaying = true;
			_self.log("playClip("+content_id+")");
			if (_self.loadClipData(content_id)){
				$("#zPlayer_flvContainer").show();
				_self.log("startingPlaylist: " + _self.curClipData.curVideoFlashUrl);
				var adDomain  = (typeof c_domain  != "undefined") ? c_domain[club] : "mlb",
						adSection = (typeof section   != "undefined") ? section        : "",
						adKeyVal  = (typeof dc_keyVal != "undefined") ? dc_keyVal      : "",
						adUrl     = "http://ad.doubleclick.net/pfadx/"+adDomain+".mlb/"+adSection+";"+adKeyVal+";pos=1;sz=640x360;tile=1;ord=" + (new Date).getTime(),
						playlist  = [];
				$("#zPlayerHeadline").text(_self.curClipData.headline);
				if (bam.FlvPlayer.prerollPlatform==="fw"){
					_self.log("preroll platform is FW.");
					playlist.push({type:'freewheelAd', content_id:_self.curClipData.content_id, duration:bam.media.getDurationInSeconds(_self.curClipData.duration)});					
				}
				else {
					_self.log("preroll platform is DC. url: " + adUrl);
					playlist.push({type:'dartPreroll', path:adUrl});
				}
				playlist.push({type:'video', path:_self.curClipData.curVideoFlashUrl});
				_self.flashPlayer.startPlaylist(playlist);
				if ($.inArray(_self.curClipData.content_id, _playedVideos)!==-1){
					_self.log("adding " + _self.curClipData.content_id + " to _playedVideos");
					_playedVideos.push(_self.curClipData.content_id); // add to played videos
				}
				if (bam.tracking){
					if (typeof club=="string" && typeof section=="string"){
						_playerContext = club.toUpperCase() + " " + section.substring(0,1).toUpperCase() + section.substring(1) + " Z Player";
					}
					_self.log("_playerContext: " + _playerContext);
					bam.tracking.track({
						async_media:{
							mediaID        : _self.content_id + "|" + _self.curClipData.playbackScenario,
							playerType     : "Flash",
							playerContext  : _playerContext,
							contextVersion : "3.0",
							streamType     : "Progressive Download",
							bitRate        : _self.curClipData.bitRate,
							sequenceID     : _self.curClipData.sequenceId,
							cdn            : _self.curClipData.cdn,
							actionGen      : (typeof(_self.actionGen)=="boolean" ? _self.actionGen : true) // actionGen is set externally, or defaulted to User Generated
						}
					});
				}
			}
			else {
				_self.log("error loading data");
				$("#zPlayerHeadline").text("This video is temporarily unavailable");
			}
		},
		
		
		/**
		* Checks if data for the passed content_id is currently loaded (in .curClipData)
		* @param content_id string
		* @return boolean
		*/
		dataIsLoaded: function(content_id){
			var isClipDataLoaded = !!(_self.curClipData && _self.curClipData.curVideoFlashUrl);
			if (isClipDataLoaded && content_id!=_self.curClipData.content_id){
				isClipDataLoaded = false;
			}
			_self.log("dataIsLoaded(): " + isClipDataLoaded);
			return isClipDataLoaded;
		},
		
		
		/**
		* Loads data for clip with passed content_id by calling bam.media.getMetaData(), 
		* into .curClipData property, unless its already loaded.
		* @param content_id String
		* @return boolean
		*/
		loadClipData: function(content_id){
			if (!_self.dataIsLoaded(content_id)){
				_self.curClipData = bam.media.getMetaData(content_id);
				if (_self.curClipData && typeof _self.curClipData.urls != "undefined"){
					var urlNode = {};
					var psMap   = {};
					$.each(_self.curClipData.urls, function(i, url){ // load available playback scenarios into a hash for easy reference
						if (url.getAttribute("playback_scenario")){
							psMap[url.getAttribute("playback_scenario")] = url;
						}
						else if (url.getAttribute("speed")=="800" && url.getAttribute("type")=="flash-video"){
							psMap["v2_url"] = url;
						}
					});
					_self.log("looking for playback scenario match...");
					$.each(_psKeys, function(i, psKey){
						if (psMap[psKey]){
							_self.log("found it: " + psKey);
							urlNode = psMap[psKey]; // get the first match and exit
							return false;
						}
					});
					if (urlNode.firstChild && urlNode.firstChild.nodeValue){
						_self.curClipData.curVideoFlashUrl = urlNode.firstChild.nodeValue;
						_self.curClipData.curVideoFlashId  = urlNode.getAttribute("id");
						_self.curClipData.playbackScenario = urlNode.getAttribute("playback_scenario");
						_self.curClipData.sequenceId       = urlNode.getAttribute("sequence") || "Not Available";
						_self.curClipData.cdn              = urlNode.getAttribute("cdn")      || "Not Available";
						var bitRateArr = _self.curClipData.playbackScenario.match(/(\d+K)/);
						_self.curClipData.bitRate = (bitRateArr) ? bitRateArr[1] : "";				
					}
					else { 
						return false;
					}
				}
				else { 
					return false;
				}
			}
			return true;
		},
		
		
		/**
		* Handler for zPlayer's close button. Stops playback and calls collapsePlayer()
		*/
		close: function(){
			_self.log("close");
			_$event.trigger("beforeClose");
			var trackCompActivity = "Z Player Close Button Click";
			if (typeof arguments[0]=="object" && arguments[0].compActivity){
				trackCompActivity = arguments[0].compActivity;
			}
			if (_self.flashPlayer) {
				_self.flashPlayer.execute("stopPlaylist");
			}
//			else if (!_relatedIsDisplayed){
//				// If _self.flashPlayer doesn't exist AND related content is NOT displayed, 
//				// then user already clicked the Close button before and we're ignoring this call
//				// to prevent calling collapsePlayer on a non-existent player
//				return;
//			}
			_self.collapsePlayer();
			if (bam.tracking){
				bam.tracking.track({
					async:{
						isDynamic    : false,
						compName     : "Z Player Interaction",
						compActivity : trackCompActivity,
						actionGen    : true
					}
				});
			}
		},
		
		
		/**
		* Collapses the player by destroying flvPlayer instance and data, and hiding DOM elements.
		*/
		collapsePlayer: function(){
			_self.log("collapsing player");
			_self.killFlvPlayer();
			delete(_self.curClipData);
			$("#zPlayer_leaveBehind").empty().hide();
			_relatedIsDisplayed = false;
			$("#zPlayerOuter").hide().css({"background":"none"});
			$("#zPlayerHeadline").text("");
			$("#zPlayerInner").css({width:_self.zoomStartDims.w, height:_self.zoomStartDims.h, background:"#222222", opacity:0});// });
			bam.overlay.hide({callback:function(){
				if (_previousOverlayCSS){
					bam.overlay.setCSS(_previousOverlayCSS);
					_previousOverlayCSS = null;
				}
			}});
			if (_isMacXFF2()){
				$("embed,iframe").css("visibility","visible");
			}
			_isOpen = false;
			_isPlaying = false; // this is here since onPlaylistComplete is now always called (player often keeps playing with an end poster)			
			_playInitiated = false;
			_$event.trigger("afterClose");
		},
		
		
		/**
		* Public read access to private isPlaying variable.
		*/
		isPlaying: function(){
			return _isPlaying;
		},
		
		
		/**
		* Public read access to private isOpen variable.
		*/		
		isOpen: function(){
			return _isOpen;
		},
		
		
		/**
		* Sets clip data to the passed object.
		*/
		setClipData: function(newClipData){
			if (!_self.curClipData){
				_self.curClipData = {
					content_id       : "",
					headline         : "",
					curVideoFlashUrl : "",
					playbackScenario : "",
					bitRate          : "Not Available",
					sequenceId       : "Not Available",
					cdn              : "Not Available"
				};	
			}
			$.extend(_self.curClipData, newClipData);
		},
		
		
		/**
		* Handles case where the player is already playing but needs to be updated
		* with new content.
		*/
		updateClip: function(newClipData){
			_self.setClipData(newClipData);
			$("#zPlayerHeadline").text(_self.curClipData.headline);
			// another tracking call here (to pass updated sequence id)?
		}
		
	};
	
	// These calls add support for (now deprecated) prePlay() and postClose() methods. For backwards support only.
	_$event.bind("beforePlay", function(){ _self.prePlay(); });
	_$event.bind("afterClose", function(){ _self.postClose(); });
	

	return _self;
})();