if (!window.Msn) {
    window.Msn = {};
}

if (!window.Msn.Video) {
    window.Msn.Video = new function() { }
}

Msn.Video._loaded = null; //This value is polled from channels.js

Msn.Video.OnVideoTitle = function(text, id) {
    id = id + "_t"; if (checkString(text) && checkString(id))
    { var el = document.getElementById(id); if (el) { el.innerHTML = text; } }
}
Msn.Video.OnMediaCompleted = function(id)
{ id = id + "_t"; var el = document.getElementById(id); if (el) { el.innerHTML = ""; } }

Msn.Video.OnLinkback = function(text, url, id) {
    id = id + "_m"; var c; var el = document.getElementById(id); var css; if (el) {
        el.innerHTML = ""; for (c = 0; c <= text.length - 1; c++) {
            if (checkString(text[c]) && checkString(url[c]))
            { css = (c == text.length - 1) ? "linkback last" : "linkback"; el.innerHTML = el.innerHTML + '<a class="' + css + '" href="' + url[c] + '" target="_blank">' + text[c] + '</a>'; }
        }
    }
}
Msn.Video.OnAdLoaded = function(adData, id) {
    id = id + "_a"; if (checkObject(adData) && adData.imageUrl && checkArray(adData.clickUrls, 2) && checkString(id)) {
        var el = document.getElementById(id); if (el)
        { el.innerHTML = '<a class="ad" href="' + adData.clickUrls[1] + '" target="_blank"><img src="' + adData.imageUrl + '" width="300" height="60"></a>'; }
    }
}
Msn.Video.OnAdSurveyAvailable = function(obj, id) {
    if (checkObject(obj)) {
        id = id + "_r"; var el = document.getElementById(id) || document.body; if (el) try
{ var script = document.createElement("SCRIPT"); script.type = "text/javascript"; el.appendChild(script); script.src = obj.url; } catch (e) { }
    }
}

Msn.Video.EVENT_FLASH_DETECT = "flash_detect";

// util functions

function isIE() { return (navigator.userAgent.toLowerCase().indexOf("msie") != -1) }

function checkDefined(o) { return ((typeof (o) != "undefined") && (null != o)); }
function checkString(s) { return ((typeof (s) == "string") && (s.length > 0)); }
function checkObject(o) { return (typeof (o) == "object" && (null != o)); }
function checkArray(array, minLength) { var arrayCheck = (array instanceof Array); if (minLength != '') { arrayCheck = arrayCheck && (array.length >= minLength); } returnarrayCheck; }
function checkFunction(o) { return (typeof (o) == "function"); }
function parseBool(s) { return (typeof (s) != "undefined") && null != s && s.toLowerCase() == "true"; }
function checkInt(f, min, max) {
    if ((null != f) && ((typeof (f) != "string") || ("" != f)) && !isNaN(f))
    { if (checkDefined(min) && (f < min)) return false; if (checkDefined(max) && (f > max)) return false; return true; } return false;
}

function openStandardWindow(url, target)
{ return openWindow(url, target, 1024, 768, "resizable=yes,toolbar=yes,menubar=yes,scrollbars=yes,status=yes,location=yes"); }


// FlashObject

Msn.Video.FlashObject = function(id, s, w, h, params) {
    var that = this;
    var attrKeys = new Array();
    var attrValues = new Array();

    var _objectNode = null;
    var _installCtrl = null;
    var _minVersionFailed = false;
    var _id = id;
    var _src = s;
    var _params = params;
    var _versionDetectionFailed = false;
    var _majorVersion = 0;
    var _minorVersion = 0;
    var _revisionVersion = 0;
    var _parent;

    _params = _params || {};

    if (_params["wmode"] == undefined) _params["wmode"] = "transparent";
    if (_params["bgColor"] == undefined) _params["bgColor"] = "#000000";
    if (_params["base"] == undefined) _params["base"] = ".";
    if (_params["menu"] == undefined) _params["menu"] = "false";

    Msn.Video.FlashVersionDetectInstance.addListener(this);

    this.onEvent = function(source, type, param, param2) {
        switch (type) {
            case Msn.Video.EVENT_FLASH_DETECT:
                if (!Msn.Video.FlashVersionDetectInstance.checkVersion(_majorVersion, _minorVersion, _revisionVersion)) {
                    this.onVersionDetectionFailure();
                }
            default:
                break;
        }
    }

    this.getObjectNode = function() {
        return _objectNode;
    }

    this.setInstallCtrl = function(ctrl, major, minor, revision) {
        if (ctrl != undefined) {
            _installCtrl = ctrl;
        }

        _majorVersion = major != undefined ? major : 0;
        _minorVersion = minor != undefined ? minor : 0;
        _revisionVersion = revision != undefined ? revision : 0;
    }

    this.onDispose = function() {
        if (isIE()) {
            // Clearing up Flash External interface to avoid leaks
            // Note : this is not required for FF, and actually would cause subsequent flash object not to render..
            try {
                for (var f in _objectNode) {
                    if (checkFunction(_objectNode[f])) {
                        _objectNode[f] = empty;
                    }
                }
            }
            catch (e) { }
        }

        // Clean up the flash object to avoid memory leaks
        _objectNode = null;
    }

    this.onVersionDetectionFailure = function() {
        _versionDetectionFailed = true;
        this.render(_parent);
    }

    this.verifyIEInstall = function() {
        var n = document.getElementById(_id + "Install");

        if (n) {
            // Flash installation failed..
            that.onVersionDetectionFailure();
        }
    }

    this.render = function(p) {
        _parent = p;
        _parent.innerHTML = "";

        if ((null != p) && checkString(_src)) {
            // need to check for a version failure here, since the event may have already been sent before this
            // object was created
            if (Msn.Video.FlashVersionDetectInstance && !Msn.Video.FlashVersionDetectInstance.checkVersion(_majorVersion, _minorVersion, _revisionVersion)) {
                _versionDetectionFailed = true;
            }

            if (_versionDetectionFailed && _installCtrl) {
                _installCtrl.render(p);
            }
            else {
                if (isIE()) {
                    // set object tag for IE through innerHTML               
                    p.innerHTML = "<object id=\"" + _id + "\" " +
                                    "name=\"" + _id + "\" " +
                                    "classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" " +
                                    "height=\"" + h + "\" " +
                                    "width=\"" + w + "\"> " +
                                    "<param name=\"movie\" value=\"" + _src + "\">" +
                                    "<param name=\"flashvars\" value=\"" + _params["flashvars"] + "\"/> " +
                                    "<param name=\"menu\" value=\"" + _params["menu"] + "\">" +
                                    "<param name=\"wmode\" value=\"" + _params["wmode"] + "\">" +
                                    "<param name=\"play\" value=\"0\">" +
                                    "<param name=\"quality\" value=\"High\">" +
                                    "<param name=\"allowScriptAccess\" value=\"always\">" +
                                    "<param name=\"allowFullScreen\" value=\"true\">" +
                                    "<param name=\"bgcolor\" value=\"" + _params["bgcolor"] + "\">" +
                                    "<param name=\"base\" value=\"" + _params["base"] + "\">" +
                                    "<div id=\"" + _id + "Install\"></div>" +
                                    "</object>";

                    _objectNode = p.childNodes[0];

                    if (_installCtrl) {
                        setTimeout(this.verifyIEInstall, 1000);
                    }
                }
                else {
                    _objectNode = document.createElement("EMBED");
                    _objectNode.id = _id;
                    _objectNode.setAttribute("name", _id);
                    _objectNode.setAttribute("bgcolor", _params["bgcolor"]);
                    _objectNode.setAttribute("allowScriptAccess", "always");
                    _objectNode.setAttribute("menu", _params["menu"]);
                    _objectNode.setAttribute("quality", "high");
                    _objectNode.setAttribute("type", "application/x-shockwave-flash");
                    _objectNode.setAttribute("src", _src);
                    _objectNode.setAttribute("width", w);
                    _objectNode.setAttribute("height", h);
                    _objectNode.setAttribute("flashVars", _params["flashvars"]);
                    _objectNode.setAttribute("wmode", _params["wmode"]);
                    _objectNode.setAttribute("base", _params["base"]);
                    _objectNode.setAttribute("allowFullScreen", "true");
                    p.appendChild(_objectNode);

                    if (_installCtrl && !(navigator.plugins != null && navigator.plugins.length > 0 && (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]))) {
                        this.onVersionDetectionFailure();
                    }
                }
            }
        }
        else {
            // Cleanup reference to flash object node
            _objectNode = null;
        }
    }
}

// VersionDetect

Msn.Video.FlashVersionDetect = function() {
    var that = this;
    var _major;
    var _minor;
    var _revision;
    var _listeners = new Array();

    // register FlashVersionDetect singleton    
    if (!checkDefined(Msn.Video.FlashVersionDetectInstance)) {
        Msn.Video.FlashVersionDetectInstance = this;
    }

    this.addListener = function(listener) {
        _listeners.push(listener);
    }

    this.fireEvent = function(event, param1, param2) {
        for (var i = 0; i < _listeners.length; i++) {
            if (checkDefined(_listeners[i]) && checkFunction(_listeners[i].onEvent)) {
                _listeners[i].onEvent(this, event, param1, param2);
            }
        }
    }

    this.render = function(p) {
        if (null != p) {
            p.style.position = "absolute";

            var id = "versiondetect";
            var url = "http://images.video.msn.com/flash/versionDetect.swf";
            var obj = new Msn.Video.FlashObject(id, url, 1, 1);
            obj.render(p);

            var node = obj.getObjectNode();

            if (node) {
                if (node.attachEvent) node.attachEvent("fscommand", that.onVersion);
                window[id + "_DoFSCommand"] = that.onVersion;
            }
            else {
                _major = _minor = _revision = 0;
            }
        }
    }

    this.checkVersion = function(major, minor, revision) {
        if (_major > major || _major == undefined) {
            return true;
        }
        else if (_major == major) {
            if (_minor > minor || _minor == undefined) {
                return true;
            }
            else if (_minor == minor && (_revision >= revision || _revision == undefined)) {
                return true;
            }
        }

        return false;
    }

    this.onVersion = function(v) {
        try {
            var temp = v.split(" ")[1]; // WIN 9,0,0,0 -> 9,0,0,0
            temp = temp.split(","); // -> [9,0,0,0]
            _major = checkInt(temp[0]) ? temp[0] : 0;
            _minor = checkInt(temp[1]) ? temp[1] : 0;
            _revision = checkInt(temp[2]) ? temp[2] : 0;

            that.fireEvent(Msn.Video.EVENT_FLASH_DETECT, v);
        }
        catch (e) { }
    }
}

// FlashInstall

Msn.Video.FlashInstall = function(content) {
    var that = this;
    var _content = content;

    this.cfg = {
        REQUIRE_FLASH: "Please install the latest version of the free Adobe Flash Player. ",
        REQUIRE_FLASH_LINK: "Download now.",
        HELP_FLASH: "For help with Flash, see Adobe's ",
        HELP_FLASH_LINK: "Flash Player Support page.",
        FLASH_INSTALL_URL: "http://g.msn.com/0VD0/34/67?CM=not_auto_flash",
        FLASH_HELP_URL: "http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_15511"
    }

    this.onFlashInstall = function() {
        setTimeout(that.onFlashInstallComplete, 1000);
    }

    this.onFlashInstallComplete = function() {
        openStandardWindow(that.cfg.FLASH_INSTALL_URL, "_blank");
    }

    this.render = function(p) {
        if (null != p) {
            if (checkDefined(_content)) {
                p.appendChild(_content);
            }
            else {
                var d = document.createElement("DIV");
                d.className = "flashInstallParent";
                p.appendChild(d);

                var n = document.createElement("DIV");
                n.className = "flashInstall";
                n.style.backgroundColor = "#e0e0e0";
                n.style.color = "#666";
                n.style.fontFamily = "Tahoma";
                n.style.fontSize = "8pt";
                n.style.fontWeight = "bold";
                n.style.padding = "30px";
                d.appendChild(n);

                var span = document.createElement("span");
                span.innerHTML = that.cfg.REQUIRE_FLASH;
                n.appendChild(span);

                var link = document.createElement("a");
                link.setAttribute("href", that.cfg.FLASH_INSTALL_URL);
                link.setAttribute("target", "_blank");
                link.innerHTML = that.cfg.REQUIRE_FLASH_LINK;
                link.style.color = "#07519a";
                n.appendChild(link);

                n.appendChild(document.createElement("BR"));
                n.appendChild(document.createElement("BR"));

                span = document.createElement("span");
                span.innerHTML = that.cfg.HELP_FLASH;
                n.appendChild(span);

                link = document.createElement("a");
                link.setAttribute("href", that.cfg.FLASH_HELP_URL);
                link.setAttribute("target", "_blank");
                link.innerHTML = that.cfg.HELP_FLASH_LINK;
                link.style.color = "#07519a";
                n.appendChild(link);
            }
        }
    }
}
// silverlight
///////////////////////////////////////////////////////////////////////////////
//
//  Silverlight.js   			version 2.0.31030.0
//
//  This file is provided by Microsoft as a helper file for websites that
//  incorporate Silverlight Objects. This file is provided under the Microsoft
//  Public License available at 
//  http://code.msdn.microsoft.com/silverlightjs/Project/License.aspx.  
//  You may not use or distribute this file or the code in this file except as 
//  expressly permitted under that license.
// 
//  Copyright (c) Microsoft Corporation. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////

if (!window.Silverlight) {
    window.Silverlight = {};
}

//////////////////////////////////////////////////////////////////
//
// _silverlightCount:
//
// Counter of globalized event handlers
//
//////////////////////////////////////////////////////////////////
Silverlight._silverlightCount = 0;

//////////////////////////////////////////////////////////////////
//
// __onSilverlightInstalledCalled:
//
// Prevents onSilverlightInstalled from being called multiple 
// times
//
//////////////////////////////////////////////////////////////////
Silverlight.__onSilverlightInstalledCalled = false;

//////////////////////////////////////////////////////////////////
//
// fwlinkRoot:
//
// Prefix for fwlink URL's
//
//////////////////////////////////////////////////////////////////
Silverlight.fwlinkRoot = 'http://go2.microsoft.com/fwlink/?LinkID=';

//////////////////////////////////////////////////////////////////
//
// __installationEventFired:
//
// Ensures that only one Installation State event is fired.
//
//////////////////////////////////////////////////////////////////
Silverlight.__installationEventFired = false;

//////////////////////////////////////////////////////////////////
//  
// onGetSilverlight:
//
// Called by Silverlight.GetSilverlight to notify the page that a user
// has requested the Silverlight installer
//
//////////////////////////////////////////////////////////////////
Silverlight.onGetSilverlight = null;

//////////////////////////////////////////////////////////////////
//
// onSilverlightInstalled:
//
// Called by Silverlight.WaitForInstallCompletion when the page detects
// that Silverlight has been installed. The event handler is not called
// in upgrade scenarios.
//
//////////////////////////////////////////////////////////////////
Silverlight.onSilverlightInstalled = function() { window.location.reload(false); };

//////////////////////////////////////////////////////////////////
//
// isInstalled:
//
// Checks to see if the correct version is installed
//
//////////////////////////////////////////////////////////////////
Silverlight.isInstalled = function(version) {
    if (version == undefined)
        version = null;

    var isVersionSupported = false;
    var container = null;

    try {
        var control = null;
        var tryNS = false;

        if (window.ActiveXObject) {
            try {
                control = new ActiveXObject('AgControl.AgControl');
                if (version === null) {
                    isVersionSupported = true;
                }
                else if (control.IsVersionSupported(version)) {
                    isVersionSupported = true;
                }
                control = null;
            }
            catch (e) {
                tryNS = true;
            }
        }
        else {
            tryNS = true;
        }
        if (tryNS) {
            var plugin = navigator.plugins["Silverlight Plug-In"];
            if (plugin) {
                if (version === null) {
                    isVersionSupported = true;
                }
                else {
                    var actualVer = plugin.description;
                    if (actualVer === "1.0.30226.2")
                        actualVer = "2.0.30226.2";
                    var actualVerArray = actualVer.split(".");
                    while (actualVerArray.length > 3) {
                        actualVerArray.pop();
                    }
                    while (actualVerArray.length < 4) {
                        actualVerArray.push(0);
                    }
                    var reqVerArray = version.split(".");
                    while (reqVerArray.length > 4) {
                        reqVerArray.pop();
                    }

                    var requiredVersionPart;
                    var actualVersionPart;
                    var index = 0;


                    do {
                        requiredVersionPart = parseInt(reqVerArray[index]);
                        actualVersionPart = parseInt(actualVerArray[index]);
                        index++;
                    }
                    while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);

                    if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) {
                        isVersionSupported = true;
                    }
                }
            }
        }
    }
    catch (e) {
        isVersionSupported = false;
    }

    return isVersionSupported;
};
//////////////////////////////////////////////////////////////////
//
// WaitForInstallCompletion:
//
// Occasionally checks for Silverlight installation status. If it
// detects that Silverlight has been installed then it calls
// Silverlight.onSilverlightInstalled();. This is only supported
// if Silverlight was not previously installed on this computer.
//
//////////////////////////////////////////////////////////////////
Silverlight.WaitForInstallCompletion = function() {
    if (!Silverlight.isBrowserRestartRequired && Silverlight.onSilverlightInstalled) {
        try {
            navigator.plugins.refresh();
        }
        catch (e) {
        }
        if (Silverlight.isInstalled(null) && !Silverlight.__onSilverlightInstalledCalled) {
            Silverlight.onSilverlightInstalled();
            Silverlight.__onSilverlightInstalledCalled = true;
        }
        else {
            setTimeout(Silverlight.WaitForInstallCompletion, 3000);
        }
    }
};
//////////////////////////////////////////////////////////////////
//
// __startup:
//
// Performs startup tasks. 
//////////////////////////////////////////////////////////////////
Silverlight.__startup = function() {
    navigator.plugins.refresh();
    Silverlight.isBrowserRestartRequired = Silverlight.isInstalled(null);
    if (!Silverlight.isBrowserRestartRequired) {
        Silverlight.WaitForInstallCompletion();
        if (!Silverlight.__installationEventFired) {
            Silverlight.onInstallRequired();
            Silverlight.__installationEventFired = true;
        }
    }
    else if (window.navigator.mimeTypes) {
        var mimeSL2 = navigator.mimeTypes["application/x-silverlight-2"];
        var mimeSL2b2 = navigator.mimeTypes["application/x-silverlight-2-b2"];
        var mimeSL2b1 = navigator.mimeTypes["application/x-silverlight-2-b1"];
        var mimeHighestBeta = mimeSL2b1;
        if (mimeSL2b2)
            mimeHighestBeta = mimeSL2b2;

        if (!mimeSL2 && (mimeSL2b1 || mimeSL2b2)) {
            if (!Silverlight.__installationEventFired) {
                Silverlight.onUpgradeRequired();
                Silverlight.__installationEventFired = true;
            }
        }
        else if (mimeSL2 && mimeHighestBeta) {
            if (mimeSL2.enabledPlugin &&
                mimeHighestBeta.enabledPlugin) {
                if (mimeSL2.enabledPlugin.description !=
                    mimeHighestBeta.enabledPlugin.description) {
                    if (!Silverlight.__installationEventFired) {
                        Silverlight.onRestartRequired();
                        Silverlight.__installationEventFired = true;
                    }
                }
            }
        }
    }
    if (!Silverlight.disableAutoStartup) {
        if (window.removeEventListener) {
            window.removeEventListener('load', Silverlight.__startup, false);
        }
        else {
            window.detachEvent('onload', Silverlight.__startup);
        }
    }
};

///////////////////////////////////////////////////////////////////////////////
//
// This block wires up Silverlight.__startup to be executed once the page
// loads. This is the desired behavior for most sites. If, however, a site
// prefers to control the timing of the Silverlight.__startup call then it should
// put the following block of javascript into the webpage before this file is
// included:
//
//    <script type="text/javascript">
//        if (!window.Silverlight)
//        {
//            window.Silverlight = {};
//        }
//        Silverlight.disableAutoStartup = true;
//    </script> 
//
/////////////////////////////////////////////////////////////////////////////////

if (!Silverlight.disableAutoStartup) {
    if (window.addEventListener) {
        window.addEventListener('load', Silverlight.__startup, false);
    }
    else {
        window.attachEvent('onload', Silverlight.__startup);
    }
}

///////////////////////////////////////////////////////////////////////////////
// createObject:
//
// Inserts a Silverlight <object> tag or installation experience into the HTML
// DOM based on the current installed state of Silverlight. 
//
/////////////////////////////////////////////////////////////////////////////////

Silverlight.createObject = function(source, parentElement, id, properties, events, initParams, userContext) {
    var slPluginHelper = new Object();
    var slProperties = properties;
    var slEvents = events;

    slPluginHelper.version = slProperties.version;
    slProperties.source = source;
    slPluginHelper.alt = slProperties.alt;

    //rename properties to their tag property names. For bacwards compatibility
    //with Silverlight.js version 1.0
    if (initParams)
        slProperties.initParams = initParams;
    if (slProperties.isWindowless && !slProperties.windowless)
        slProperties.windowless = slProperties.isWindowless;
    if (slProperties.framerate && !slProperties.maxFramerate)
        slProperties.maxFramerate = slProperties.framerate;
    if (id && !slProperties.id)
        slProperties.id = id;

    // remove elements which are not to be added to the instantiation tag
    delete slProperties.ignoreBrowserVer;
    delete slProperties.inplaceInstallPrompt;
    delete slProperties.version;
    delete slProperties.isWindowless;
    delete slProperties.framerate;
    delete slProperties.data;
    delete slProperties.src;
    delete slProperties.alt;


    // detect that the correct version of Silverlight is installed, else display install

    if (Silverlight.isInstalled(slPluginHelper.version)) {
        //move unknown events to the slProperties array
        for (var name in slEvents) {
            if (slEvents[name]) {
                if (name == "onLoad" && typeof slEvents[name] == "function" && slEvents[name].length != 1) {
                    var onLoadHandler = slEvents[name];
                    slEvents[name] = function(sender) { return onLoadHandler(document.getElementById(id), userContext, sender) };
                }
                var handlerName = Silverlight.__getHandlerName(slEvents[name]);
                if (handlerName != null) {
                    slProperties[name] = handlerName;
                    slEvents[name] = null;
                }
                else {
                    throw "typeof events." + name + " must be 'function' or 'string'";
                }
            }
        }
        slPluginHTML = Silverlight.buildHTML(slProperties);
    }
    //The control could not be instantiated. Show the installation prompt
    else {
        slPluginHTML = Silverlight.buildPromptHTML(slPluginHelper);
    }

    // insert or return the HTML
    if (parentElement) {
        parentElement.innerHTML = slPluginHTML;
    }
    else {
        return slPluginHTML;
    }

};

///////////////////////////////////////////////////////////////////////////////
//
//  buildHTML:
//
//  create HTML that instantiates the control
//
///////////////////////////////////////////////////////////////////////////////
Silverlight.buildHTML = function(slProperties) {
    var htmlBuilder = [];

    htmlBuilder.push('<object type=\"application/x-silverlight\" data="data:application/x-silverlight,"');
    if (slProperties.id != null) {
        htmlBuilder.push(' id="' + Silverlight.HtmlAttributeEncode(slProperties.id) + '"');
    }
    if (slProperties.width != null) {
        htmlBuilder.push(' width="' + slProperties.width + '"');
    }
    if (slProperties.height != null) {
        htmlBuilder.push(' height="' + slProperties.height + '"');
    }
    htmlBuilder.push(' >');

    delete slProperties.id;
    delete slProperties.width;
    delete slProperties.height;

    for (var name in slProperties) {
        if (slProperties[name]) {
            htmlBuilder.push('<param name="' + Silverlight.HtmlAttributeEncode(name) + '" value="' + Silverlight.HtmlAttributeEncode(slProperties[name]) + '" />');
        }
    }
    htmlBuilder.push('<\/object>');
    return htmlBuilder.join('');
};



//////////////////////////////////////////////////////////////////
//
// createObjectEx:
//
// takes a single parameter of all createObject 
// parameters enclosed in {}
//
//////////////////////////////////////////////////////////////////

Silverlight.createObjectEx = function(params) {
    var parameters = params;
    var html = Silverlight.createObject(parameters.source, parameters.parentElement, parameters.id, parameters.properties, parameters.events, parameters.initParams, parameters.context);
    if (parameters.parentElement == null) {
        return html;
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////
//
// buildPromptHTML
//
// Builds the HTML to prompt the user to download and install Silverlight
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.buildPromptHTML = function(slPluginHelper) {
    var slPluginHTML = "";
    var urlRoot = Silverlight.fwlinkRoot;
    var version = slPluginHelper.version;
    if (slPluginHelper.alt) {
        slPluginHTML = slPluginHelper.alt;
    }
    else {
        if (!version) {
            version = "";
        }
        slPluginHTML = "<a href='javascript:Silverlight.getSilverlight(\"{1}\");' style='text-decoration: none;'><img src='{2}' alt='Get Microsoft Silverlight' style='border-style: none'/></a>";
        slPluginHTML = slPluginHTML.replace('{1}', version);
        slPluginHTML = slPluginHTML.replace('{2}', urlRoot + '108181');
    }

    return slPluginHTML;
};

///////////////////////////////////////////////////////////////////////////////////////////////
//
// getSilverlight:
//
// Navigates the browser to the appropriate Silverlight installer
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.getSilverlight = function(version) {
    if (Silverlight.onGetSilverlight) {
        Silverlight.onGetSilverlight();
    }

    var shortVer = "";
    var reqVerArray = String(version).split(".");
    if (reqVerArray.length > 1) {
        var majorNum = parseInt(reqVerArray[0]);
        if (isNaN(majorNum) || majorNum < 2) {
            shortVer = "1.0";
        }
        else {
            shortVer = reqVerArray[0] + '.' + reqVerArray[1];
        }
    }

    var verArg = "";

    if (shortVer.match(/^\d+\056\d+$/)) {
        verArg = "&v=" + shortVer;
    }

    Silverlight.followFWLink("114576" + verArg);
};


///////////////////////////////////////////////////////////////////////////////////////////////
//
// followFWLink:
//
// Navigates to a url based on fwlinkid
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.followFWLink = function(linkid) {
    top.location = Silverlight.fwlinkRoot + String(linkid);
};

///////////////////////////////////////////////////////////////////////////////////////////////
//
// HtmlAttributeEncode:
//
// Encodes special characters in input strings as charcodes
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.HtmlAttributeEncode = function(strInput) {
    var c;
    var retVal = '';

    if (strInput == null) {
        return null;
    }

    for (var cnt = 0; cnt < strInput.length; cnt++) {
        c = strInput.charCodeAt(cnt);

        if (((c > 96) && (c < 123)) ||
                  ((c > 64) && (c < 91)) ||
                  ((c > 43) && (c < 58) && (c != 47)) ||
                  (c == 95)) {
            retVal = retVal + String.fromCharCode(c);
        }
        else {
            retVal = retVal + '&#' + c + ';';
        }
    }

    return retVal;
};
///////////////////////////////////////////////////////////////////////////////
//
//  default_error_handler:
//
//  Default error handling function 
//
///////////////////////////////////////////////////////////////////////////////

Silverlight.default_error_handler = function(sender, args) {
    var iErrorCode;
    var errorType = args.ErrorType;

    iErrorCode = args.ErrorCode;

    var errMsg = "\nSilverlight error message     \n";

    errMsg += "ErrorCode: " + iErrorCode + "\n";


    errMsg += "ErrorType: " + errorType + "       \n";
    errMsg += "Message: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError") {
        errMsg += "XamlFile: " + args.xamlFile + "     \n";
        errMsg += "Line: " + args.lineNumber + "     \n";
        errMsg += "Position: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError") {
        if (args.lineNumber != 0) {
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " + args.charPosition + "     \n";
        }
        errMsg += "MethodName: " + args.methodName + "     \n";
    }
    alert(errMsg);
};

///////////////////////////////////////////////////////////////////////////////////////////////
//
// __cleanup:
//
// Releases event handler resources when the page is unloaded
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.__cleanup = function() {
    for (var i = Silverlight._silverlightCount - 1; i >= 0; i--) {
        window['__slEvent' + i] = null;
    }
    Silverlight._silverlightCount = 0;
    if (window.removeEventListener) {
        window.removeEventListener('unload', Silverlight.__cleanup, false);
    }
    else {
        window.detachEvent('onunload', Silverlight.__cleanup);
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////
//
// __getHandlerName:
//
// Generates named event handlers for delegates.
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.__getHandlerName = function(handler) {
    var handlerName = "";
    if (typeof handler == "string") {
        handlerName = handler;
    }
    else if (typeof handler == "function") {
        if (Silverlight._silverlightCount == 0) {
            if (window.addEventListener) {
                window.addEventListener('onunload', Silverlight.__cleanup, false);
            }
            else {
                window.attachEvent('onunload', Silverlight.__cleanup);
            }
        }
        var count = Silverlight._silverlightCount++;
        handlerName = "__slEvent" + count;

        window[handlerName] = handler;
    }
    else {
        handlerName = null;
    }
    return handlerName;
};
//////////////////////////////////////////////////////////////////
//  
// onRequiredVersionAvailable:
//
// Called by version  verification control to notify the page that
// an appropriate build of Silverlight is available. The page 
// should respond by injecting the appropriate Silverlight control
//
//////////////////////////////////////////////////////////////////
Silverlight.onRequiredVersionAvailable = function() {

};
//////////////////////////////////////////////////////////////////
//  
// onRestartRequired:
//
// Called by version verification control to notify the page that
// an appropriate build of Silverlight is installed but not loaded. 
// The page should respond by injecting a clear and visible 
// "Thanks for installing. Please restart your browser and return
// to mysite.com" or equivalent into the browser DOM
//
//////////////////////////////////////////////////////////////////
Silverlight.onRestartRequired = function() {

};
//////////////////////////////////////////////////////////////////
//  
// onUpgradeRequired:
//
// Called by version verification control to notify the page that
// Silverlight must be upgraded. The page should respond by 
// injecting a clear, visible, and actionable upgrade message into
// the DOM. The message must inform the user that they need to 
// upgrade Silverlight to use the page. They are already somewhat
// familiar with the Silverlight product when they encounter this.
// Silverlight should be mentioned so the user expects to see that
// string in the installer UI. However, the Silverlight-powered
// application should be the focus of the solicitation. The user
// wants the app. Silverlight is a means to the app.
// 
// The upgrade solicitation will have a button that directs 
// the user to the Silverlight installer. Upon click the button
// should both kick off a download of the installer URL and replace
// the Upgrade text with "Thanks for downloading. When the upgarde
// is complete please restart your browser and return to 
// mysite.com" or equivalent.
//
// Note: For a more interesting upgrade UX we can use Silverlight
// 1.0-style XAML for this upgrade experience. Contact PiotrP for
// details.
//
//////////////////////////////////////////////////////////////////
Silverlight.onUpgradeRequired = function() {

};
//////////////////////////////////////////////////////////////////
//  
// onInstallRequired:
//
// Called by Silverlight.checkInstallStatus to notify the page
// that Silverlight has not been installed by this user.
// The page should respond by 
// injecting a clear, visible, and actionable upgrade message into
// the DOM. The message must inform the user that they need to 
// download and install components needed to use the page. 
// Silverlight should be mentioned so the user expects to see that
// string in the installer UI. However, the Silverlight-powered
// application should be the focus of the solicitation. The user
// wants the app. Silverlight is a means to the app.
// 
// The installation solicitation will have a button that directs 
// the user to the Silverlight installer. Upon click the button
// should both kick off a download of the installer URL and replace
// the Upgrade text with "Thanks for downloading. When installation
// is complete you may need to refresh the page to view this 
// content" or equivalent.
//
//////////////////////////////////////////////////////////////////
Silverlight.onInstallRequired = function() {

};

//////////////////////////////////////////////////////////////////
//  
// IsVersionAvailableOnError:
//
// This function should be called at the beginning of a web page's
// Silverlight error handler. It will determine if the required 
// version of Silverlight is installed and available in the 
// current process.
//
// During its execution the function will trigger one of the 
// Silverlight installation state events, if appropriate.
//
// Sender and Args should be passed through from  the calling
// onError handler's parameters. 
//
// The associated Sivlerlight <object> tag must have
// minRuntimeVersion set and should have autoUpgrade set to false.
//
//////////////////////////////////////////////////////////////////
Silverlight.IsVersionAvailableOnError = function(sender, args) {
    var retVal = false;
    try {
        if (args.ErrorCode == 8001 && !Silverlight.__installationEventFired) {
            Silverlight.onUpgradeRequired();
            Silverlight.__installationEventFired = true;
        }
        else if (args.ErrorCode == 8002 && !Silverlight.__installationEventFired) {
            Silverlight.onRestartRequired();
            Silverlight.__installationEventFired = true;
        }
        // this handles upgrades from 1.0. That control did not
        // understand the minRuntimeVerison parameter. It also
        // did not know how to parse XAP files, so would throw
        // Parse Error (5014). A Beta 2 control may throw 2106
        else if (args.ErrorCode == 5014 || args.ErrorCode == 2106) {
            if (Silverlight.__verifySilverlight2UpgradeSuccess(args.getHost())) {
                retVal = true;
            }
        }
        else {
            retVal = true;
        }
    }
    catch (e) {
    }
    return retVal;
};
//////////////////////////////////////////////////////////////////
//  
// IsVersionAvailableOnLoad:
//
// This function should be called at the beginning of a web page's
// Silverlight onLoad handler. It will determine if the required 
// version of Silverlight is installed and available in the 
// current process.
//
// During its execution the function will trigger one of the 
// Silverlight installation state events, if appropriate.
//
// Sender should be passed through from  the calling
// onError handler's parameters. 
//
// The associated Sivlerlight <object> tag must have
// minRuntimeVersion set and should have autoUpgrade set to false.
//
//////////////////////////////////////////////////////////////////
Silverlight.IsVersionAvailableOnLoad = function(sender) {
    var retVal = false;
    try {
        if (Silverlight.__verifySilverlight2UpgradeSuccess(sender.getHost())) {
            retVal = true;
        }
    }
    catch (e) {
    }
    return retVal;
};
//////////////////////////////////////////////////////////////////
//
// __verifySilverlight2UpgradeSuccess:
//
// This internal function helps identify installation state by
// taking advantage of behavioral differences between the
// 1.0 and 2.0 releases of Silverlight. 
//
//////////////////////////////////////////////////////////////////
Silverlight.__verifySilverlight2UpgradeSuccess = function(host) {
    var retVal = false;
    var version = "2.0.31005";
    var installationEvent = null;

    try {
        if (host.IsVersionSupported(version + ".99")) {
            installationEvent = Silverlight.onRequiredVersionAvailable;
            retVal = true;
        }
        else if (host.IsVersionSupported(version + ".0")) {
            installationEvent = Silverlight.onRestartRequired;
        }
        else {
            installationEvent = Silverlight.onUpgradeRequired;
        }

        if (installationEvent && !Silverlight.__installationEventFired) {
            installationEvent();
            Silverlight.__installationEventFired = true;
        }
    }
    catch (e) {
    }
    return retVal;
};


if (!window.Msn) { window.Msn = {}; }
if (!window.Msn.VideoSL) { window.Msn.VideoSL = {}; }
Msn.VideoSL.Inline = function(id)
{
    var that = this, t = id + "_t", p = id + "_p", m = id + "_m", a = id + "_a", pobj = id + "_pobj", events, timeout, loaded;
    this.Build = function(v, w, h, src, props, evts)
    {
        that.BuildPlayer(v, w, h, src, props, evts);
    }
    this.BuildPlayer = function(v, w, h, src, props, evts)
    {
        var vs = { ifs: "true", playlistmin: "2" }, i; for (i in v) vs[i] = v[i]; v = [];
        for (i in vs) if (vs[i]) v.push(i + "=" + vs[i].replace(/,/g, "%2C")); v = v.join(",");
        var properties = {
            width: w ? w : 300,
            height: h ? h : 269,
            background: "black",
            framerate: "30",
            version: "2.0.31005",
            enableHtmlAccess: "true",
            enableGPUAcceleration: "true"
        };
        for (var x in props) properties[x] = props[x];
        events = evts;
        var ex = {
            source: (src ? src : "http://images.video.msn.com/sl/inline.xap"),
            parentElement: document.getElementById(p),
            id: pobj,
            properties: properties,
            events: { onLoad: that.OnLoad, onError: that.OnError },
            initParams: v,
            context: null
        };
        Silverlight.createObjectEx(ex);
        timeout = setTimeout(that.OnLoad, 100);
    }
    this.OnLoad = function(s, c, src)
    {
        if (timeout != null)
        {
            clearTimeout(timeout);
            timeout = null;
        }
        var obj = document.getElementById(pobj);
        if (obj != null && obj.IsLoaded)
        {
            if (!loaded)
            {
                loaded = true;
                var il = obj.Content.Inline;
                il.addEventListener("PropertyChanged", onIPC);
                st(il.Title);
                //sb(il.Banner);
                sl(il.Links);
                if (events != null && typeof events.onLoad == "function")
                    events.onLoad(s, c, src);
            }
        }
        else
        {
            timeout = setTimeout(that.OnLoad, 100);
        }
    }
    this.OnError = function(s, args)
    {
        if (events != null && typeof events.onError == "function")
            events.onError(s, args);
    }
    function onIPC(s, d)
    {
        var n = d.PropertyName, v = d.PropertyValue;
        if (n == "Title") st(v);
        if (n == "Banner") sb(v);
        if (n == "Links") sl(v);
    }
    function st(v)
    {
        var el = document.getElementById(t);
        if (el) el.innerHTML = (v == null) ? "" : v;
    }
    function sb(v)
    {
        var el = document.getElementById(a);
        if (el) el.innerHTML = (v == null) ? "" : '<a class="ad" href="' + v.Target + '" target="_blank"><img src="' + v.Image + '" width="300" height="60"></a>';
    }
    function sl(v)
    {
        var el = document.getElementById(m), c, css, s = "";
        if (el)
        {
            for (c = 0; v != null && c <= v.length - 1; c++)
            {
                css = (c == v.length - 1) ? "linkback last" : "linkback";
                var url;
                var text;
                
                try
                {
                    url = v[c].url;
                    text = v[c].text;
                }
                catch(e)
                {   //backwards compat: deprecate after 6/16/2010
                    url = v[c].Uri;
                    text = v[c].Value;
                }
                
                s += '<a class="' + css + '" href="' + url + '" target="_blank">' + text + '</a>';
            }
            el.innerHTML = s;
        }
    }
};

// script interface

/*
urls for all the widget assets
current: current relative path for asset
silverlight: whether the widget is silverlight or flash
oldRoot: whether to use V4 or V5 url (mainly for custom player. we should deprecate this)
*/
Msn.Video.Widgets =
{
    playerarticle:
    {
        current: { path: "flash/inline.swf" }
    },
    player:
    {
        "2": { path: "flash/soapbox1_1.swf", oldRoot: true },
        current: { path: "flash/inline.swf" }
    },
    playerrtl:
    {
        current: { path: "flash/soapbox1_1RTL.swf", oldRoot: true }
    },
    playerad:
    {
        "2": { path: "flash/soapbox1_1.swf", oldRoot: true },
        current: { path: "flash/inline.swf" }
    },
    slplayer:
    {
        current: { path: "sl/inlinev2.xap" },
        silverlight: true
    },
    slplayerad:
    {
        current: { path: "sl/inlinev2.xap" },
        silverlight: true
    },
    gallery:
    {
        "2": { path: "flash/gallerywidget/1_0/gallerywidget.swf", oldRoot: true },
        current: { path: "flash/gallerywidget/1_0/gallerywidget.swf" }
    },
    galleryrtl:
    {
        current: { path: "flash/gallerywidget/1_0/gallerywidget.swf", oldRoot: true }
    },
    customplayer:
    {
        "2": { path: "flash/customplayer/1_0/customplayer.swf", oldRoot: true },
        current: { path: "flash/customplayer/1_0/customplayer.swf"}
    }
};

//This function is maintained for backwards compatiblitiy
Msn.Video.createWidget = function(divId, src, w, h, flashvars, widgetId, params, version, root, downlevel)
{
    Msn.Video.createWidget2(
    {
        divId: divId,
        src: src,
        w: w,
        h: h,
        flashvars: flashvars,
        widgetId: widgetId,
        params: params,
        version: version,
        root: root,
        downlevel: downlevel
    });
}

/*
divId: div to render the widget in
src: name of the widget (found in Msn.Video.Widgets)
w: width of the widget
h: height of the widget
flashvars: flashvars/initparms for the widget
widgetId: ????
params: ????
version: ????
root: http://images.video.msn.com/
wRoot: http://img.widgets.video.msn.com/
vcRoot: http://edge1.catalog.video.msn.com
downlevel: I think this has to do with the downlevel flash installer
cacheBuster: Sticks a random QS on the asset to break the cache
*/

Msn.Video.createWidget2 = function(param)
{
    var renderWidget = true;

    //Only do config server call if we're doing a player widget
    if ((param.src.toLowerCase() == "player" || param.src.toLowerCase() == "playerad")
        && Silverlight.isInstalled("3.0"))
    {
        var configCsid = param.flashvars["configCsid"];
        var configName = param.flashvars["configName"];

        //check if configCsid/Name is defined
        if (checkString(configCsid) && checkString(configName))
        {
            //setup vc config server call url
            var root = normalizeRootUrl(getCreateWidgetParamValue(param, "vcRoot", "edge1.catalog.video.msn.com"));
            var configUrl = root + "configByName.aspx?csid=" + configCsid + "&name=" + configName + "&responseEncoding=json"; 

            Msn.Video.JavascriptApi.makeRequest(configUrl, param, Msn.Video.playerConfigServerCb);
            renderWidget = false;
        }
    }
    else if (!Silverlight.isInstalled("3.0"))
    {
        switch (param.src.toLowerCase())
        {
            case "slplayer":
                param.src = "player";
                break;
            case "slplayerad":
                param.src = "playerad";
                break;
        }
    }

    if (renderWidget)
    {
        Msn.Video.renderWidget(param);
    }
}

Msn.Video.playerConfigServerCb = function(obj, ctx, error)
{
    var leadWithSl = false;

    if (obj)
    {
        var data = obj.config.data;
        var len = data.length;
        for (var n = 0; n < len; n++)
        {
            if (data[n].$key.toLowerCase() == "player.leadwithplugin")
            {
                if (data[n].$value.toLowerCase() == "silverlight")
                {
                    leadWithSl = true;
                }
                break;
            }
        }
    }

    if (leadWithSl)
    {
        switch (ctx.src.toLowerCase())
        {
            case "player":
                ctx.src = "slplayer";
                break;
            case "playerad":
                ctx.src = "slplayerad"
                break;
        }
    }

    Msn.Video.renderWidget(ctx);
}

Msn.Video.renderWidget = function(param)
{
    var container = document.getElementById(param.divId);

    if (checkDefined(container))
    {
        var isSL = false;
        param.src = param.src.toLowerCase();
        var origSrc = param.src;

        if (param.src == "playerarticle")
        {
            var ctrl = new Msn.Video.ArticlePlayer();
            ctrl.create(
                param,
                container);
        }
        else
        {

            if (Msn.Video.Widgets[param.src])
            {
                isSL = Msn.Video.Widgets[param.src].silverlight == true;

                //support version on flash vars
                var version = param.flashvars["version"];
                if (!version || !Msn.Video.Widgets[param.src][version])
                {
                    version = "current";
                }

                var verData = Msn.Video.Widgets[param.src][version];

                var root = verData.oldRoot
                        ? getCreateWidgetParamValue(param, "root", "images.video.msn.com")
                        : getCreateWidgetParamValue(param, "wRoot", "img.widgets.video.s-msn.com")
                root = normalizeRootUrl(root);

                param.src = root + verData.path;

                if (param.cacheBuster)
                {
                    param.src += "?r=" + Math.random();
                }
            }

            var detectDiv = document.createElement("div");
            detectDiv.setAttribute("id", param.divId + "_detect");
            container.appendChild(detectDiv);

            var detectObj = new Msn.Video.FlashVersionDetect();

            var contentDiv = document.createElement("div");
            contentDiv.setAttribute("id", param.divId + "_content");
            container.appendChild(contentDiv);

            var fvv = {};
            for (var i in param.flashvars)
            {
                if (null != param.flashvars[i])
                {
                    fvv[i] = param.flashvars[i].replace(/\&/g, "%26");
                }
            }

            if (origSrc == "playerad" || origSrc == "slplayerad")
            {
                contentDiv = Msn.Video.buildPlayerAdElements(contentDiv, param.divId);
                fvv["cbprefix"] = "Msn.Video.";
                fvv["cbdata"] = param.divId;
                fvv["adDivs"] = (checkString(fvv["adDivs"]) ? (fvv["adDivs"] + ";") : "") + param.divId + "_a,300,60";
            }

            if (origSrc.substring(0, 6) == "player" && !checkString(fvv["mode"]))
            {
                fvv["mode"] = checkString(fvv["mode"]) ? fvv["mode"] : "inline";
            }

            param.params = param.params || new Object();

            if (isSL)
            {
                var flashvars = {};
                for (var k in fvv)
                {
                    flashvars[k] = decodeURIComponent(fvv[k]);
                }


                var player = new Msn.VideoSL.Inline(param.divId);

                if (origSrc == "slplayerad")
                {
                    player.Build(flashvars, param.w, param.h, param.src, param.params);
                }
                else
                {
                    contentDiv.innerHTML = "<div id='" + param.divId + "_p'></div>";
                    player.BuildPlayer(flashvars, param.w, param.h, param.src, param.params);
                }
            }
            else
            {
                var fvs = "";
                for (var i in fvv)
                {
                    fvs += i + "=" + fvv[i] + "&";
                }

                param.params["flashvars"] = fvs;

                var flash = new Msn.Video.FlashObject(param.widgetId || param.divId + "_flash", param.src, param.w, param.h, param.params);
                flash.setInstallCtrl(new Msn.Video.FlashInstall(param.downlevel), 9);

                detectObj.render(detectDiv);
                flash.render(contentDiv);

                return flash.getObjectNode();
            }
        }
    }
}

Msn.Video.buildPlayerAdElements = function(div, id)
{
    var v = '<div class="video1"><h3 id="' + id + '_t"></h3><div id="' + id + '_p"></div><div id="' + id + '_m"></div><div id="' + id + '_a" class="playerAdDiv"></div><div id="' + id + '_r"></div></div>';
    div.innerHTML = v;

    var playerNode = document.getElementById(id + '_p');

    return playerNode;
}

function getCreateWidgetParamValue(param, key, defaultVal)
{
    var val = defaultVal;
    if (param.hasOwnProperty(key) && checkDefined(param[key]))
    {
        val = param[key];
    }
    return val;
}

function normalizeRootUrl(url)
{
    if (url)
    {
        if (url.indexOf("http://") != 0)
        {
            url = "http://" + url;
        }

        if (url.lastIndexOf("/") != url.length - 1)
        {
            url += "/";
        }
    }
    return url;
}

Msn.Video._loaded = new Date().getTime();
//Handles making asynch javascript calls to VC and Widgets
if (!Msn.Video.JavascriptApi)
{
    Msn.Video.JavascriptApi = new function()
    {
        var _that = this;
        var _currRequestId = 0;

        var _callbacks = new Object();

        this.makeRequest = function(url, context, funcCb)
        {
            var reqId = _currRequestId++;
            _callbacks[reqId] =
        {
            context: context,
            funcCb: funcCb
        };

            //insert script into head of doc
            var scriptObj = document.createElement("script");
            scriptObj.setAttribute("type", "text/javascript");
            scriptObj.setAttribute("src", url + "&callbackName=Msn.Video.JavascriptApi.onComplete&cd=" + reqId);
            scriptObj.setAttribute("id", reqId);

            var head = document.getElementsByTagName("head")[0];
            head.appendChild(scriptObj);
        }

        this.onComplete = function(obj, reqId, error)
        {
            //remove script tag
            var scriptObj = document.getElementById(reqId);
            if (checkDefined(scriptObj))
            {
                var head = document.getElementsByTagName("head")[0];
                head.removeChild(scriptObj);
            }

            //get the context of the json call
            var ctx = _callbacks[reqId].context;
            var funcCb = _callbacks[reqId].funcCb;

            funcCb(obj, ctx, error);
        }

    };
}//Handles fetching localized resources
Msn.Video.ResourceMgr = function(data)
{
    var _lookup = new Object();

    function construct(resources)
    {
        for (var a = 0; a < resources.length; a++)
        {
            var ns = resources[a].Key.toLowerCase();
            _lookup[ns] = new Object();
            var currDict = _lookup[ns];
            var dict = resources[a].Value;

            for (var b = 0; b < dict.length; b++)
            {
                var entry = dict[b];
                currDict[entry.Key.toLowerCase()] = entry.Value;
            }
        }
    }
    construct(data);

    this.getValue = function(ns, key, defaultVal)
    {
        var val = defaultVal;
        ns = ns.toLowerCase();
        key = key.toLowerCase();

        if (_lookup.hasOwnProperty(ns) && _lookup[ns].hasOwnProperty(key))
        {
            val = _lookup[ns][key];
        }

        return val;
    }

    this.setValue = function(ns, key, val)
    {
        ns = ns.toLowerCase();
        key = key.toLowerCase();

        if (!_lookup.hasOwnProperty(ns))
        {
            _lookup[ns] = new Object();
        }
        _lookup[ns][key] = val;
    }
}

//Handles fetching localized resources
Msn.Video.ConfigMgr = function(data, flashvars)
{
    var DEFAULT_KEY = "default";
    var _resMgr;

    function construct(data, flashvars)
    {
        _resMgr = new Msn.Video.ResourceMgr(data);

        for (var key in flashvars)
        {
            _resMgr.setValue(DEFAULT_KEY, key, flashvars[key]);
        }
    }
    construct(data, flashvars);

    this.getValue = function(ns, key, defaultVal)
    {
        if (arguments.length == 2)
        {
            defaultVal = key;
            key = ns;
            ns = DEFAULT_KEY;
        }

        val = _resMgr.getValue(ns, key, defaultVal);

        return val;
    }
}

Msn.Video.ArticlePlayer = function()
{
    var _that = this;

    var _oldWidgetFrameworkInitializedFunc = null;

    var _widgetId;
    var _internalWidgetGroup;
    var _internalPlayerId;

    var _param;
    var _cfgMgr;
    var _resMgr;

    var _container;

    var _playerWrapper;
    var _playerDiv;

    var _metadataHolder;

    function padLeft(num, length)
    {
        var str = '' + num;
        while (str.length < length)
        {
            str = '0' + str;
        }
        return str;
    }

    this.create = function(param, container)
    {
        _param = param;
        _container = container;

        var mkt = param.flashvars.mkt;
        if (!checkString(mkt))
        {
            mkt = "en-us";
        }

        var root = normalizeRootUrl(getCreateWidgetParamValue(param, "wRoot", "img.widgets.video.s-msn.com"));

        var configUrl = root + "resource.aspx?resources=player&mkt=" + mkt + "&responseEncoding=json";

        Msn.Video.JavascriptApi.makeRequest(configUrl, null, onResourcesLoaded)
    }

    function onResourcesLoaded(data, ctx, error)
    {
        _cfgMgr = new Msn.Video.ConfigMgr(data.configs, _param.flashvars);
        _resMgr = new Msn.Video.ResourceMgr(data.resources);


        _widgetId = _param.widgetId;
        _internalWidgetGroup = _widgetId + "InternalGroup";

        //Add Widget Framework Initialized Callback
        if ("undefined" != typeof (MsnVideo2) && null != MsnVideo2)
        {
            onWidgetFrameworkInitialized();
        }
        else
        {
            _oldWidgetFrameworkInitializedFunc = window["MsnVideoInitializeInternal"];
            window["MsnVideoInitializeInternal"] = onWidgetFrameworkInitialized;
        }

        //We're very particular here. Anything that isn't explicitly "false" gets set to true
        var compactMode = _cfgMgr.getValue("compactMode", "false");
        compactMode = null != compactMode && compactMode.toLowerCase() == "true";

        var showMetaData = _cfgMgr.getValue("showMetadata", "false");
        showMetaData = null == showMetaData || showMetaData.toLowerCase() != "false";

        //Build Dom
        var wrapper = document.createElement("DIV");
        wrapper.className = "msnVideoArticlePlayer";
        _container.appendChild(wrapper);

        _playerWrapper = document.createElement("DIV");
        _playerWrapper.className = compactMode ? "compact" : "normal";

        var backgroundColor = _cfgMgr.getValue("backgroundcolor1", null);
        if (null != backgroundColor)
        {
            try
            {
                _playerWrapper.style.backgroundColor = backgroundColor;
            }
            catch (e) { alert("backgroundcolor1 configured incorrectly"); }
        }
        wrapper.appendChild(_playerWrapper);

        _playerDiv = document.createElement("DIV");
        _playerDiv.className = "playerDiv";
        var playerDivId = _widgetId + "PlayerDiv";
        _playerDiv.id = playerDivId;
        _playerWrapper.appendChild(_playerDiv);

        //Upper Div
        if (showMetaData || compactMode)
        {
            var upperDiv = document.createElement("DIV");
            upperDiv.className = "upperDiv";

            //Metadata Div
            _metadataHolder = document.createElement("DIV");
            _metadataHolder.className = "metadataDiv";

            var fontColor = _cfgMgr.getValue("fontcolor1", null);
            if (null != fontColor)
            {
                try
                {
                    _metadataHolder.style.color = fontColor;
                }
                catch (e) { alert("fontcolor1 configured incorrectly"); }
            }

            upperDiv.appendChild(_metadataHolder);

            _playerWrapper.appendChild(upperDiv);
        }

        //Bottom Div
        if (!compactMode)
        {
            var showBottomDiv = _cfgMgr.getValue("showBottomArea", "true");
            var bottomDiv = null;
            //We're very particular here. Anything that isn't explicitly "false" gets set to true
            if (null == showBottomDiv || showBottomDiv.toLowerCase() != "false")
            {
                bottomDiv = document.createElement("DIV");
                bottomDiv.className = "bottomDiv";
                var backgroundColor = _cfgMgr.getValue("backgroundcolor2", null);
                if (null != backgroundColor)
                {
                    try
                    {
                        bottomDiv.style.backgroundColor = backgroundColor;
                    }
                    catch (e) { alert("backgroundcolor2 configured incorrectly"); }
                }
                _playerWrapper.appendChild(bottomDiv);

                var browseMoreDiv = document.createElement("DIV");
                browseMoreDiv.className = "browseMoreDiv";

                var img = document.createElement("IMG");
                var root = normalizeRootUrl(getCreateWidgetParamValue(_param, "wRoot", "img.widgets.video.s-msn.com"));
                img.src = root + "/i/articleplayer/arrow.png";
                img.className = "arrow";
                browseMoreDiv.appendChild(img);

                var link = document.createElement("A");
                var fallbackUrl = "http://video.msn.com?mkt=" + _cfgMgr.getValue("mkt", "en-us");
                link.href = _cfgMgr.getValue("linkback", fallbackUrl);
                if (_cfgMgr.getValue("pl", "true").toLowerCase() == "true")
                {
                    link.target = "_blank";
                }

                link.appendChild(document.createTextNode(_resMgr.getValue("player", "MoreVideosText", "Browse more videos")));

                var fontColor = _cfgMgr.getValue("fontColor3", null);
                if (null != fontColor)
                {
                    try
                    {
                        link.style.color = fontColor;
                    }
                    catch (e) { alert("fontColor3 configured incorrectly"); }
                }
                browseMoreDiv.appendChild(link);

                bottomDiv.appendChild(browseMoreDiv);
            }
        }

        //Add ad div
        var adDiv = document.createElement("DIV");
        var adDivId = _widgetId + "adDiv";
        adDiv.id = adDivId;
        adDiv.className = "adDiv";

        if (compactMode)
        {
            upperDiv.appendChild(adDiv);
            var clear = document.createElement("DIV");
            clear.className = "clear";
            upperDiv.appendChild(clear);
        }
        else if (null != bottomDiv)
        {
            bottomDiv.appendChild(adDiv);
        }

        //Create player
        var initParams = new Object();
        for (var key in _param.flashvars)
        {
            initParams[key] = _param.flashvars[key];
        }
        initParams["widgetId"] = _internalPlayerId;
        initParams["adDivs"] = adDivId + "|300|60";
        initParams["widgetGroup"] = _internalWidgetGroup;

        Msn.Video.createWidget2
        ({
            divId: playerDivId,
            src: 'slplayer',
            w: _param.w,
            h: _param.h,
            flashvars: initParams,
            widgetId: _internalPlayerId,
            root: _param.root,
            wRoot: _param.wRoot,
            vcRoot: _param.vcRoot,
            cacheBuster: _param.cacheBuster
        });
    }

    function setCurrentVideo(vid)
    {
        var fontColor = _cfgMgr.getValue("fontColor2", null);
        var styleStr = "";
        if (null != fontColor)
        {
            styleStr = " style=\"color: " + fontColor + "\"";
        }

        _metadataHolder.innerHTML = "";

        var titleDiv = document.createElement("DIV");
        titleDiv.className = "titleDiv";
        titleDiv.innerHTML = vid.title;
        _metadataHolder.appendChild(titleDiv);

        var detailDiv = document.createElement("DIV");
        detailDiv.className = "detailDiv";

        //add date metadata
        var date = new Date(vid.startDate);
        var dateStr = (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();

        var html = "<div><span class=\"dateDetail\"><span class=\"detailLabel\"" + styleStr + ">"
                    + _resMgr.getValue("player", "DateLbl", "Date")
                    + ":</span>" + dateStr + "</span>";

        //add duration metadata
        var factor = 60 * 60;
        var remainingSecs = vid.durationSecs;
        var hours = Math.floor(remainingSecs / factor);
        remainingSecs %= factor;
        factor /= 60;
        var minutes = Math.floor(remainingSecs / factor);
        remainingSecs %= factor;
        var seconds = Math.floor(remainingSecs);
        var durationStr = "";
        if (hours > 0)
        {
            durationStr += padLeft(hours, 2) + ":";
        }

        var minutesPadding = minutes > 0 ? 2 : 1;

        durationStr += padLeft(minutes, minutesPadding) + ":" + padLeft(seconds, 2);

        html += "<span class=\"durationDetail\"><span class=\"detailLabel\"" + styleStr + ">"
                + _resMgr.getValue("player", "DurationLbl", "Duration")
                + ":</span> " + durationStr + "</span>";

        var videoByName;
        if (vid.relatedLinks.length > 0
            && checkString(vid.relatedLinks[0].url))
        {
            videoByName = "<a class=\"videoByLink\" href=\"" + vid.relatedLinks[0].url + "\" target=\"_blank\">" + vid.sourceFriendly + "</a>";
        }
        else
        {
            videoByName = vid.sourceFriendly;

        }

        html += "<span class=\"sourceDetail\"><span class=\"detailLabel\"" + styleStr + ">"
                + _resMgr.getValue("player", "VideoByLbl", "Video By")
                + ":</span> " + videoByName + "</span>";

        detailDiv.innerHTML = html;
        _metadataHolder.appendChild(detailDiv);

        var descriptionDiv = document.createElement("DIV");
        descriptionDiv.className = "descriptionDiv";
        descriptionDiv.innerHTML = vid.description;
        _metadataHolder.appendChild(descriptionDiv);


    }

    function onCurrentVideoChange(msg)
    {
        var vid = msg.param.video;
        setCurrentVideo(vid);
    }

    function onWidgetFrameworkInitialized()
    {
        MsnVideo2.addMessageReceiver
        ({
            eventType: "currentVideoChanged",
            widgetId: _widgetId,
            widgetGroup: _internalWidgetGroup,
            funcCb: onCurrentVideoChange
        });

        var props = MsnVideo2.getProperties
        ({
            type: "currentVideo",
            widgetId: _widgetId,
            widgetGroup: _internalWidgetGroup
        });

        if (null != props && props.length > 0)
        {
            setCurrentVideo(props[0].param.video);
        }

        if ("function" == typeof (_oldWidgetFrameworkInitializedFunc))
        {
            _oldWidgetFrameworkInitializedFunc();
        }
    }
}

