/**
 * @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.
        *
        * 
        * old: hdVideoFields : ["playurl", "gotoMovie", "guid", "movieCategory", "movieTitle", "movieID"],		 
        **/
        hdVideoFields: ["gotoMovie", "guid", "movieCategory", "movieTitle", "movieID"],

        initialize: function() {
            //_isPlayerLoaded = false;
            _isMediaComplete = true;
            _clipData = null;
            Count = 0;
            videoTimer = null;
            countTimerInterval = 0;

            trace("tracing is on");
            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.
            //this.wssPageView(obj);
        },
        
        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_MDC", "VIDHD_Player_MDC_Volume");
                    break;
                case "OnSetReleaseUrl":
                    trace("jsEventHandler() handling event.type = " + evt.type);
                    break;
                case "OnSetVolume":
                    // WSS Reporting:
                    _hbLink("VIDHD_Player_MDC", "VIDHD_Player_MDC_Volume");
                    break;
                case "OnShowFullScreen":
                    // WSS Reporting: (Expand)
                    _hbLink("VIDHD_Player_MDC", "VIDHD_Player_MDC_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("lid=VIDHD_Player_MDC", "");
                    break;
                case "OnMediaPause":
                    // WSS Reporting:
                    _hbLink("VIDHD_Player_MDC", "VIDHD_Player_MDC_Pause");
                    break;
                case "OnMediaUnpause":
                    // WSS Reporting:
                    _hbLink("VIDHD_Player_MDC", "VIDHD_Player_MDC_Play");
                    break;
                case "OnMediaSeek":
                    // WSS Reporting:
                    _hbLink("VIDHD_Player_MDC", "VIDHD_Player_MDC_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 += "/mdcwebsite";
            }

            var playerUrl = protocol + host + "/" + pagename + "?src=" + obj["guid"];

            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

    })();

