/**
 *	DetailDisplay [SINGLETON]
 *
 *	Overlay for detail box SWF to display image or video for an item
 */
var DrPepper = DrPepper || {};
DrPepper.About = DrPepper.About || {};

DrPepper.About.Timeline = DrPepper.About.Timeline || {};


//
// CONSTRUCTOR
//

DrPepper.About.Timeline.DetailDisplay = function()
{
	if (DrPepper.About.Timeline.DetailDisplay.instance) {
		throw("DrPepper.About.Timeline.DetailDisplay objects are singletons");
	}
	DrPepper.About.Timeline.DetailDisplay.instance = this;
	this.init();
}


//
// CLASS CONSTANTS
//

// Time [ms] to take to fade in an item
DrPepper.About.Timeline.DetailDisplay.FADE_TIME_MS = 400;

// Time [ms] to wait before fading in an item; used for items (such as images, MySpace video) that do not have a callback
// to inform us about whether they are ready to display/interact.
DrPepper.About.Timeline.DetailDisplay.DEFAULT_ITEM_STARTUP_DELAY_MS	= 1500;

// DOM ID of video player SWF
DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID = "timeline-video-player";

// Width and height of video player SWF
DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_WIDTH	= 640;
DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_HEIGHT	= 385;

// Video player SWF embed URLs
DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_URL_YOUTUBE	= "http://www.youtube.com/v/__VIDEO_ID__?fs=1&amp;rel=0&amp;enablejsapi=1";
DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_URL_MYSPACE	= "http://mediaservices.myspace.com/services/media/embed.aspx/m=__VIDEO_ID__,t=1,mt=video"; 
DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_URL_VIMEO	= "http://vimeo.com/moogaloop.swf?clip_id=__VIDEO_ID__&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=d31245&amp;fullscreen=1&amp;js_api=1&amp;js_onLoad=onVimeoPlayerReady";



//
// INSTANCE FUNCTIONS
//

DrPepper.About.Timeline.DetailDisplay.prototype =
{
	/**
	 *	Initialize this DetailDisplay object.
	 */
	init : function()
	{
		var l_xThis = this;

		this._xDomElement = $("#timeline-detail-display");
	},

	/**
	 *	Load the specified item into the detail display box.
	 *
	 *	@param	p_xItem	{Object}	Item information { type, hash (for images), reference (for videos) }
	 */	
	loadItem : function(p_xItem)
	{
		// Get a reference to the detail SWF
		this._xDetailSwf = $("#" + DrPepper.About.Timeline.Grid.DETAIL_SWF_ID).get(0);
		
		var l_xThis = this;

		p_xItem.type = parseInt(p_xItem.type);
		
		this._sCurrentItemTitle = p_xItem.title;
		this._bIsVideoOpen = false; // see trackEvent(); used to determine whether a PLAY event for a video item is the first one or not

		if (p_xItem.type == DrPepper.About.Timeline.Grid.ITEMTYPE_IMAGE) {
			//
			// IMAGE
			//
			this._xImage = new Image();
			$(this._xImage)
				.load(function() {
					$(this).unbind();
					l_xThis._xDomElement.css("background", "url(" + this.src + ") 50% 50% no-repeat #000");
					setTimeout(function() { l_xThis.showItemContainer(true); }, DrPepper.About.Timeline.DetailDisplay.DEFAULT_ITEM_STARTUP_DELAY_MS * .5);
				})
				.error(function() {
					// TODO: Call detail SWF to inform it of missing image
				})
				.attr("src", DrPepper.About.Timeline.Grid.URL_IMAGES + DrPepper.About.Timeline.Grid.FILENAME_PATTERN_IMAGE.replace(/__HASH__/, p_xItem.hash));
		}
		else {
			//
			// VIDEO
			//
			var l_sSWFURL;
			
			switch (p_xItem.type)
			{
				case DrPepper.About.Timeline.Grid.ITEMTYPE_VIDEO_YOUTUBE:
					l_sSWFURL = DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_URL_YOUTUBE.replace(/__VIDEO_ID__/, p_xItem.reference);

					DrPepper.About.Timeline.DetailDisplay.getVideoCurrentTime = DrPepper.About.Timeline.DetailDisplay.getVideoCurrentTimeYouTube;
					DrPepper.About.Timeline.DetailDisplay.getVideoDuration = DrPepper.About.Timeline.DetailDisplay.getVideoDurationYouTube;

					break;

				case DrPepper.About.Timeline.Grid.ITEMTYPE_VIDEO_MYSPACE:
					l_sSWFURL = DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_URL_MYSPACE.replace(/__VIDEO_ID__/, p_xItem.reference);

					DrPepper.About.Timeline.DetailDisplay.getVideoCurrentTime = null;
					DrPepper.About.Timeline.DetailDisplay.getVideoDuration = null;
					
					// MySpace video player has no public API, so guess a good time to fade in the video
					// (other players have an explicit callback for this purpose)
					setTimeout(function() { l_xThis.showItemContainer(true); }, DrPepper.About.Timeline.DetailDisplay.DEFAULT_ITEM_STARTUP_DELAY_MS);

					break;

				case DrPepper.About.Timeline.Grid.ITEMTYPE_VIDEO_VIMEO:
					l_sSWFURL = DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_URL_VIMEO.replace(/__VIDEO_ID__/, p_xItem.reference)

					DrPepper.About.Timeline.DetailDisplay.getVideoCurrentTime = DrPepper.About.Timeline.DetailDisplay.getVideoCurrentTimeVimeo;
					DrPepper.About.Timeline.DetailDisplay.getVideoDuration = DrPepper.About.Timeline.DetailDisplay.getVideoDurationVimeo;

					break;
			}

			if (l_sSWFURL)
			{
				// If we have a SWF URL to load, insert new video player here
				
				this._xDomElement.html($("<div />").attr("id", DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID + "-container"));
	
				swfobject.embedSWF(
					l_sSWFURL,
					DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID + "-container",
					DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_WIDTH,
					DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_HEIGHT,
					"9.0.124",
					null,
					null,
					{ wmode: "opaque", allowScriptAccess: "always", allowFullscreen: "true", bgcolor: "#000000" },
					{ id: DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID }
				);
			}
		}
	},


	/**
	 *	Clear detail display box immediately
	 */
	clear : function()
	{
		if (this._xImage) {
			$(this._xImage).unbind();
			this._xImage = null;
		}
		
		var l_xVideoPlayer = $("#" + DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID);
		if (!$.browser.msie) {
			if ($(l_xVideoPlayer).length > 0) {
				swfobject.removeSWF(DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID);
			}
		}

		$(document).unbind("mousedown", this.onVimeoMouseDown);
		$(document).unbind("mouseup", this.onVimeoMouseUp);
		if ($(l_xVideoPlayer).length > 0) {
			$(l_xVideoPlayer).unbind("mouseup", onVimeoMouseUp);
		}
		$(this._xDetailSwf).unbind("mouseup", onVimeoMouseUp);
		
		this._xDomElement.empty()
		this._xDomElement.css({ "opacity": 0, "background": "none" });
	},


	/**
	 *	Clear current item from display box and (optionally) invoke callback after fadeout.
	 *
	 *	@param	p_fCallback		Callback to invoke after item has faded out
	 */	
	clearItem : function(p_fCallback)
	{
		if (this._xImage) {
			$(this._xImage).unbind();
			this._xImage = null;
		}
		
		var l_xThis = this;
		this.showItemContainer(false, function() {
			l_xThis.clear();
			if (p_fCallback) {
				p_fCallback();
			}
		});
	},
	
	
	/**
	 *	Show or hide item container.
	 *
	 *	@param	p_bShow		Flag: show (true) or hide (false) container. Defaults to true.
	 */
	showItemContainer : function(p_bShow /* = true */, p_fCallback)
	{
		if ($.browser.msie) {
			$(this._xDomElement).stop().css("opacity", "");
		}
		if (p_bShow || (p_bShow == undefined)) {
			if ($.browser.msie) {
				$(this._xDomElement).css("opacity", "");
				if (p_fCallback) {
					p_fCallback();
				}
			}
			else {
				$(this._xDomElement).stop().animate({ "opacity": 1 }, DrPepper.About.Timeline.DetailDisplay.FADE_TIME_MS, null, p_fCallback);
			}
		}
		else {
			$(this._xDomElement).css("opacity", "0");
			if (p_fCallback) {
				p_fCallback();
			}
		}
	},


	/**
	 *	Track the specified event, with the given parameters
	 *
	 *	@param	p_nEventType	{int}		Event type
	 *	@param	p_xParameters	{Object}	Parameters to send along with the event
	 */
	trackEvent : function(p_nEventType, p_xParameters)
	{
		// Always pass title and duration
		p_xParameters.title = this._sCurrentItemTitle;
		p_xParameters.duration = this.getVideoDuration();

		// The very first PLAY event for this item will be sent as an OPEN event
		//
		if (p_nEventType == DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_PLAY && !this._bIsVideoOpen) {
			p_nEventType = DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_OPEN;
			this._bIsVideoOpen = true;
		}

		if (this._xDetailSwf && this._xDetailSwf.trackEvent) {
			this._xDetailSwf.trackEvent(p_nEventType, [p_xParameters]);
		}
		else {
			// no tracking interface available
		}
	}
};



//
//	ANALYTICS
//

// Possible video player events
DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_OPEN = 0;
DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_PLAY = 1;
DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_STOP = 2;
DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_CLOSE = 3;

 
//
//	VIDEO-PLAYER-SPECIFIC TRACKING FUNCTIONALITY
//
//	NOTE: These are global functions.
//
/**
 *	Invoked by YouTube video player SWF when its API is ready for interaction.
 */
function onYouTubePlayerReady()
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;

	var l_xVideoPlayer = $("#" + DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID).get(0);

	// Override getVideoCurrentTime() and getVideoDuration() with player-specific API calls
	l_xDetailDisplayInstance.getVideoCurrentTime	= function() { return l_xVideoPlayer.getCurrentTime(); };
	l_xDetailDisplayInstance.getVideoDuration		= function() { return l_xVideoPlayer.getDuration(); };

	// Set up API event listeners		
	l_xVideoPlayer.addEventListener("onStateChange", "onYouYubePlayerStateChange");

	// Fade in item container, as the video player is now ready to run			
	l_xDetailDisplayInstance.showItemContainer(true);
}

/**
 *	Invoked by Vimeo video player SWF when its API is ready for interaction.
 */
function onVimeoPlayerReady()
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;

	var l_xVideoPlayer = $("#" + DrPepper.About.Timeline.DetailDisplay.VIDEO_PLAYER_ID).get(0);

	// Override getVideoCurrentTime() and getVideoDuration() with player-specific API calls
	l_xDetailDisplayInstance.getVideoCurrentTime	= function() { return l_xVideoPlayer.api_getCurrentTime(); };
	l_xDetailDisplayInstance.getVideoDuration		= function() { return l_xVideoPlayer.api_getDuration(); };
			
	// Set up API event listeners		
	l_xVideoPlayer.api_addEventListener("onPlay", "onVimeoPlayerPlay");
	l_xVideoPlayer.api_addEventListener("onPause", "onVimeoPlayerPause");
	l_xVideoPlayer.api_addEventListener("onFinish", "onVimeoPlayerFinish");
	l_xVideoPlayer.api_addEventListener("onSeek", "onVimeoPlayerSeek");
	
	// Fade in item container, as the video player is now ready to run			
	l_xDetailDisplayInstance.showItemContainer(true);
	
	// Seek tracking for vimeo
	l_xDetailDisplayInstance._bIsVideoPlaying = false;
	l_xDetailDisplayInstance._nCurrentSeekTime = null;
	l_xDetailDisplayInstance._bIsMouseDown = false;
	$(document).mousedown(onVimeoMouseDown);
	$(document).mouseup(onVimeoMouseUp);
	
	// Additional mouseup-checks for FF
	$(l_xVideoPlayer).mouseup(onVimeoMouseUp);
	$(l_xDetailDisplayInstance._xDetailSwf).mouseup(onVimeoMouseUp);
}

//
// PLAYER STATE CHANGE
//
/**
 *	Invoked by YouTube video player SWF on each state change.
 *
 *	@param	p_nState	{int}	Current video player state
 */
function onYouYubePlayerStateChange(p_nState)
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;

	switch (p_nState)
	{
		case -1:
			// unstarted
			break;

		case 0:
			// ended
			l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_CLOSE, { time: l_xDetailDisplayInstance.getVideoCurrentTime() });
			break;
			
		case 1:
			// playing
			l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_PLAY, { time: l_xDetailDisplayInstance.getVideoCurrentTime() });
			break;
			
		case 2:
			// paused
			l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_STOP, { time: l_xDetailDisplayInstance.getVideoCurrentTime() });
			break;
			
		case 3:
			// buffering
			break;
			
		case 5:
			// cued (ready to play)
			break;
	}
}

/**
 *	Invoked by Vimeo video player SWF when "play" button is clicked.
 */
function onVimeoPlayerPlay()
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;
	l_xDetailDisplayInstance._bIsVideoPlaying = true;
	l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_PLAY, { time: l_xDetailDisplayInstance.getVideoCurrentTime() });
}

/**
 *	Invoked by Vimeo video player SWF when "pause" button is clicked.
 */
function onVimeoPlayerPause()
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;
	l_xDetailDisplayInstance._bIsVideoPlaying = false;
	l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_STOP, { time: l_xDetailDisplayInstance.getVideoCurrentTime() });
}

/**
 *	Invoked by Vimeo video player SWF when video ends (reaches 100%).
 */
function onVimeoPlayerFinish()
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;
	l_xDetailDisplayInstance._bIsVideoPlaying = false;
	l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_CLOSE, { time: l_xDetailDisplayInstance.getVideoCurrentTime() });
}

/**
 *	Invoked by Vimeo video player SWF when video ends (reaches 100%).
 */
function onVimeoPlayerSeek(p_nSeekPercentage)
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;

	if (!l_xDetailDisplayInstance._bIsVideoPlaying) {
		return;
	}
	
	var l_nCurrentSeekTime = l_xDetailDisplayInstance.getVideoCurrentTime();
	
	if (l_xDetailDisplayInstance._nCurrentSeekTime === null) {
		l_xDetailDisplayInstance._nCurrentSeekTime = l_nCurrentSeekTime;
		l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_STOP, { time: l_nCurrentSeekTime });
	}
	else {
		l_xDetailDisplayInstance._nCurrentSeekTime = l_nCurrentSeekTime;
	}
}

function onVimeoMouseDown()
{
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;
	l_xDetailDisplayInstance._bIsMouseDown = true;
}

function onVimeoMouseUp(p_xEvent)
{
	// handle this event only once (we added multiple mouseup handlers specifically for FF)
	p_xEvent.stopPropagation();
	
	var l_xDetailDisplayInstance = DrPepper.About.Timeline.DetailDisplay.instance;

	l_xDetailDisplayInstance._bIsMouseDown = false;
	
	// Vimeo seek handling
	//
	if (l_xDetailDisplayInstance._bIsVideoPlaying && l_xDetailDisplayInstance._nCurrentSeekTime !== null) {
		l_xDetailDisplayInstance.trackEvent(DrPepper.About.Timeline.DetailDisplay.EVENT_VIDEO_PLAY, { time: l_xDetailDisplayInstance._nCurrentSeekTime });
		l_xDetailDisplayInstance._nCurrentSeekTime = null;
	}
}
