/**
 * @author rrobinson
 */

/**
 * This function implements jsTrace ...
 * @param {string} msg
 */
function trace( msg ){
	if( typeof( jsTrace ) != 'undefined' ){
		jsTrace.send( msg );
	}
}

var jsHDVideo = (function(){
	// -------------------------------------------------------
	// --------------- PRIVATE PROPERTIES --------------------
	// -- while these properties are not available after the
	// -- the function returns they are still available to 
	// -- each of the methods in the object returned because
	// -- lexical scoping in javascript
	// -------------------------------------------------------
	
	// ------------------- CONSTANTS -----------------------------
	var CONST_PLAYERDIV = "playerDiv";
	var CONST_IFRAME_ID = "hdfndngoIframe";
	var CONST_HDPLAYER_PAGENAME = "HDFandangoPlayer.aspx";
	// -----------------------------------------------------------
	
	var _isPlayerLoaded = false;
	var _isMediaComplete = true;
	var _clipData = null;
	var Count = 0;
	var videoTimer = null;
	var countTimerInterval = 0;
	
	/**
	 * This function will invoke the function passed as the method parameter as a member of the
	 * object passed as the scope parameter and pass the parameter arg to the invoked function.
	 *
	 * @param {Object} scope
	 * @param {function} method
	 * @param {*} arg
	 */
	var delegate = function(scope, method, arg)
	{
		return function(){
			return method.call(scope, arg);
		};
	};
		
	/**
	 * This function simply dumps a javascript object as a string
	 *
	 * @param {string} header
	 * @param {Object} obj
	 * @param {number} level
	 */
	var dumpObj = function (obj, depth){
		var indent = '';
		var level = 0;
		if (depth)
		{
			level = depth;
			for(var i=0; i < level; i++)
			{
				indent += "\t";
			}
		}
		
		var text = "{";
		for(var prop in obj)
		{
			text += "\n" + indent + prop + ":";
			if ( typeof obj[prop] == 'object')
			{
				text += dumpObj(obj[prop], level + 1);
			}
			else
			{
				text += obj[prop] + ",";
			}
		}
		text += indent + "}\n";
		
		return text;
	};

	// -------------------------------------------------------
	// The following statement simply returns an object containing
	// the methods for jsHDVideo.
	// -------------------------------------------------------
	return {	
		/**
		 * several functions in hdtrailers.js use this field to extract & construct a response object from the
		 * 'rel' attribute of an anchor tag on the HD Galleries page.
		 *
		 * TT 8771 - 9/10/2009 - rrobinson - added two optional fields: optContentCategory and optPageName to pass the
		 * WSS content category and page name values to the HDFandangoPlayer.aspx when a play is triggered
		 * by the HDFandangoPuppetTrailers.aspx page.
		 *
		 * NOTE: since optContentCategory and optPageName are optional they should always be at the end of the
		 * array; only optional fields should be appended after them.
		 **/
		hdVideoFields : ["gotoMovie", "guid", "movieCategory", "movieTitle", "movieID", "optContentCategory", "optPageName"],
		
		initialize : function()
		{
			//_isPlayerLoaded = false;
			_isMediaComplete = true;
			_clipData = null;
			Count = 0;
			videoTimer = null;
			countTimerInterval = 0;
			
			tpController.register(delegate(this, this.playerLoaded));
		},
		
		/**
		 * This method returns the value of _isPlayerLoaded ...
		 */
		isPlayerLoaded: function ()
		{
			return _isPlayerLoaded;
		},
		
		/**
		 * This method stops the videoTimer
		 */
		stopVideoTimer : function()
		{
			if (videoTimer)
			{
				clearInterval(videoTimer);
				videoTimer = null;
			}
		},
	
		play : function(obj)
		{
			trace("called play(): dumping:");
			trace(dumpObj(obj));
			
			this.startPlayer(obj);
			
			// By the time this point is reached the 'obj' object has been augmented with a title from
			// thePlatform for trailer about to be played. The following call will cause an _hbPageView()
			// call to track the playing of this trailer.
			// *** TT #8291 - the following call is no longer needed
			// HDFandangoPlayer.aspx initializes the hbx.pn and hbx.mlc in the FanCon:AnalyticsControl
			//this.wssPageView(obj);
		},
		
		wssPageView: function(obj)
		{
			var temp = obj["movieCategory"].replace("MOVIE ", "");
			var result = temp + "_";
			var pattern = /\s/g;	
			
			if (obj["movieTitle"])
			{
				temp = obj["movieTitle"].replace(pattern, "+");
				result += temp + "_";
				
				if (obj["movieID"])
				{
					result += obj["movieID"];
				}
				else
				{
					result += obj["guid"];
				}
			}
			else
			{
				temp = obj["title"].replace(pattern, "+");
				result += temp + "_";
				
				if (obj["movieID"])
				{
					result += obj["movieID"];
				}
				else
				{
					result += obj["guid"];
				}
			}
			
			result = result.replace(pattern, "+");
			//trace("WSS Reporting: VI/HDPlayed ==>" + result);
			_hbPageView(result, "VI/HDPlayed");
		},
		
		endPlayback : function()
		{
			trace("endPlayback() called");
			
			if (!_isMediaComplete)
			{
				tpController.stop();
				tpController.dispatchEvent("OnMediaEnd", _clipData, tpController.ID, "javascript");
			}
			
			//_isPlayerLoaded = false;
			
			// remove the iframe
			var playerDiv = document.getElementById(CONST_PLAYERDIV); // get the iframe parent
			var iframe = document.getElementById(CONST_IFRAME_ID);
			if (playerDiv)
			{
				if (iframe)
				{
					// remove the current iframe
					playerDiv.removeChild(iframe);
					iframe = null;
				}
			}
			
		},
		
		/**
		 * Every quarter second this method is called to check if the _isPlayerLoaded variable is true.
		 * If it is true then it stops the video timer and calls tpController.setReleaseURL() to send
		 * the currently selected player url to the flvPlayer.
		 * 
		 * @param {Object} hdURL
		 */
		sendReleaseURL : function(hdURL)
		{
			trace("isPlayerLoaded = " + this.isPlayerLoaded());
			if (this.isPlayerLoaded())
			{
				this.stopVideoTimer();
				tpController.setReleaseURL(hdURL);
			}
			else if (countTimerInterval >= 30)
			{
				this.stopVideoTimer();
				trace("HD player not ready! Closing player window.");
				return;
			}
			countTimerInterval++;
		},
					
		/**
		 * This method is provided as a callback function to registered with tpController.registerFunction().
		 * If called it will set the variable _isPlayerLoaded to true;
		 */
		playerLoaded : function()
		{
			_isPlayerLoaded = true;
			this.configureListeners();
			trace("The player has been loaded!");
		},
		
		/**
		 * This method establishes event listeners for several events dispatched by thePlatform's controls
		 */
		configureListeners : function()
		{
			trace("Called jsHDVideo.configureListeners");
			tpController.addEventListener("OnPlayerLoaded", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnClipInfoLoaded", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnJavascriptLoaded", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMute", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnSetReleaseUrl", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnSetVolume", "DVIDEO.jsEventHandler");
			tpController.addEventListener("OnShowFullScreen", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnReleaseStart", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnReleaseEnd", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaLoadStart", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaLoading", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaStart", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaPlaying", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaEnd", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaComplete", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaBuffer", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaPlay", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaPause", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaUnpause", "jsHDVideo.jsEventHandler");
			tpController.addEventListener("OnMediaSeek", "jsHDVideo.jsEventHandler");
			// tpController.addEventListener("", "jsHDVideo.jsEventHandler");
			trace("tpController Event Listeners configured!");
		},
		
		removeListeners : function()
		{
			trace("Called jsHDVideo.removeListeners");
			tpController.removeEventListener("OnPlayerLoaded", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnClipInfoLoaded", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnJavascriptLoaded", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMute", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnSetReleaseUrl", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnSetVolume", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnShowFullScreen", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnReleaseStart", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnReleaseEnd", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaLoadStart", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaLoading", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaStart", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaPlaying", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaEnd", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaComplete", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaBuffer", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaPlay", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaPause", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaUnpause", "jsHDVideo.jsEventHandler");
			tpController.removeEventListener("OnMediaSeek", "jsHDVideo.jsEventHandler");
			// tpController.removeEventListener("", "jsHDVideo.jsEventHandler");
			trace("tpController Event Listeners removed!");
		},
		
		/**
		 * This method is the event listener for events dispatched from thePlatform's controls
		 * 
		 * @param {Object} evt	thePlatform's javascript Event object
		 */
		jsEventHandler : function(evt)
		{	// parameter is Event from utils.js (from thePlatform's PDK)
			//trace("jsEventHandler() handling event.type = " + e.type);
			switch(evt.type)
			{
				case "OnPlayerLoaded":
					trace("jsEventHandler() handling event.type = " + evt.type);
					if (!_isPlayerLoaded) _isPlayerLoaded = true;
					break;
				case "OnClipInfoLoaded":
					break;
				case "OnJavascriptLoaded":
					trace("jsEventHandler() handling event.type = " + evt.type);
					break;
				case "OnMute":
					// WSS Reporting:
					_hbLink("VIDHD_Player", "VIDHD_Player_Volume");
					break;
				case "OnSetReleaseUrl":
					trace("jsEventHandler() handling event.type = " + evt.type);
					break;
				case "OnSetVolume":
					// WSS Reporting:
					_hbLink("VIDHD_Player", "VIDHD_Player_Volume");
					break;
				case "OnShowFullScreen":
					// WSS Reporting: (Expand)
					_hbLink("VIDHD_Player", "VIDHD_Player_Expand");
					break;
				case "OnReleaseStart":
					trace("jsEventHandler() handling event.type = " + evt.type);
					_clipData = null;
					break;
				case "OnReleaseEnd":
					trace("jsEventHandler() handling event.type = " + evt.type);
					break;
				case "OnMediaLoadStart":
					trace("jsEventHandler() handling event.type = " + evt.type);
					break;
				case "OnMediaLoading":
					break;
				case "OnMediaStart":
					trace("jsEventHandler() handling event.type = " + evt.type);
					_isMediaComplete = false;
					_clipData = evt.data;
					//trace("_clipData : " + dumpObj(_clipData));
					break;
				case "OnMediaPlaying":
					//trace("jsEventHandler() handling event.type = " + evt.type);
					break;
				case "OnMediaEnd":
					trace("jsEventHandler() handling event.type = " + evt.type);
					break;
				case "OnMediaComplete":
					_isMediaComplete = true;
					break;
				case "OnMediaBuffer":
					break;
				case "OnMediaPlay":
					trace("jsEventHandler() handling event.type = " + evt.type);
					//_hbLink("VIDHD_Player", "");
					break;
				case "OnMediaPause":
					// WSS Reporting:
					_hbLink("VIDHD_Player", "VIDHD_Player_Pause");
					break;
				case "OnMediaUnpause":
					// WSS Reporting:
					_hbLink("VIDHD_Player", "VIDHD_Player_Play");
					break;
				case "OnMediaSeek":
					// WSS Reporting:
					_hbLink("VIDHD_Player", "VIDHD_Player_Scrub");
					break;
			}
		}, // closing jsEventHandler
		
		/**
		 * This method starts the player for the IE browsers. It first extracts the protocol and domain from the
		 * from the current page location and build a new url referencing the page to be installed in the iframe and
		 * provides a parameter indicating the releaseUrl of the movie requested. Finally, it builds the iframe.
		 **/
		startPlayer: function (obj) {
			var protocol = window.location.protocol + "//";
			var host = window.location.host;
			var pagename = CONST_HDPLAYER_PAGENAME;
			
			if ( (host.toLowerCase()).indexOf(".com") == -1 )
			{
				host += "/fandango";
			}
			
			var playerUrl = protocol + host + "/" + pagename + "?src=" + obj["guid"];
			
			if (obj["optContentCategory"] && obj["optContentCategory"] != '')
			{
				playerUrl += "&mlc=" + obj["optContentCategory"];
			}

			if (obj["optPageName"] && obj["optPageName"] != '')
			{
				playerUrl += "&pn=" + obj["optPageName"];
			}
			
			trace("startPlayer(): playerUrl = " + playerUrl);
			
			this.createIframe(CONST_PLAYERDIV, CONST_IFRAME_ID, playerUrl);
		},
		
		/**
		 * This method will contruct the iframe for IE browsers
		 **/
		createIframe: function (divId, frameId, src)
		{
			var playerDiv = document.getElementById(divId);
			
			var iframe = document.getElementById(frameId);
			
			if (iframe)
			{
				// remove the current iframe
				playerDiv.removeChild(iframe);
				iframe = null;
			}
			
			// create a new iframe
			iframe = document.createElement("iframe");
			iframe.setAttribute("id", frameId);
			iframe.setAttribute("frameBorder","0");
			iframe.style.border = "0px";
			iframe.setAttribute("marginheight","0");
			iframe.setAttribute("marginwidth","0");
			iframe.setAttribute("height","450");
			iframe.setAttribute("width","800");
			iframe.setAttribute("scrolling","no");
			iframe.setAttribute("src",src);
			iframe.style.visibility = "visible";
			
			playerDiv.appendChild(iframe);
		}
/* *********** */		
	} // end of object returned by this function
	
})();

