// constants
const RPJAVASCRIPTHELPEROBJECT_CLASS_ID = Components.ID("{FF2FC136-90C2-4147-9CDC-C00D3281FE22}");
const RPJAVASCRIPTHELPEROBJECT_CLASS_NAME = "RealPlayer Javascript Helper Object";
const RPJAVASCRIPTHELPEROBJECT_CONTRACT_ID = "@real.com/RealPlayer/jshelper;1";

// RPJavascriptHelperObject class constructor
function RPJavascriptHelperObject()
{
};

// RPJavascriptHelperObject class definition
RPJavascriptHelperObject.prototype =
{
    QueryInterface: function(aIID)
    {
        if (!aIID.equals(Components.interfaces.nsISupports) &&
            !aIID.equals(Components.interfaces.nsIRPJavascriptHelperObject) &&
            !aIID.equals(Components.interfaces.nsISupportsWeakReference))
            throw Components.results.NS_ERROR_NO_INTERFACE;
        return this;
    },
    
    // nsIRPJavascriptHelperObject ----------------------------------------------------------------------------
    // void putEmbedFlashVars(in nsIDOMHTMLEmbedElement embed);
    putEmbedFlashVars: function(embed)
    {
        try
        {
            var flashVars = embed.wrappedJSObject.getAttribute("FlashVars");
            if (flashVars && flashVars.length > 0)
            {
                var splitList = flashVars.split('&');
                if (splitList && splitList.length > 0)
                {
                    for (var count = 0; count < splitList.length; count++)
                    {
                        try
                        {
                            var currentFlashVar = splitList[count];
                            if (currentFlashVar)
                            {
                                var index = currentFlashVar.indexOf('=');
                                if (index > 0)
                                {
                                    var flashVarName = currentFlashVar.substring(0,index);
                                    var flashVarValue = currentFlashVar.substring(index+1,currentFlashVar.length);
                                    embed.wrappedJSObject.SetVariable(flashVarName, unescape(flashVarValue));
                                }
                            }
                        }
                        catch(e2)
                        {
                            dump("putEmbedFlashVars error2:"+e2+"\n");
                        }
                    }
                }
            }
        }
        catch(e)
        {
            dump("putEmbedFlashVars error:"+e+"\n");
        }
    },
    
    doesRequestMatchFlashControlInDocument: function(httpChannel, theDocument)
    {
        // TODO: for any string compares, we need to make it lower case string compare!!!
        if (httpChannel && theDocument)
        {
            try
            {
                var bContinue = false;
                httpChannel = httpChannel.QueryInterface(Components.interfaces.nsIHttpChannel);
                theDocument = theDocument.QueryInterface(Components.interfaces.nsIDOMNSHTMLDocument);
                
                // Getting the document host name
                var standardUrl = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIStandardURL);
                standardUrl.init(Components.interfaces.nsIStandardURL.URLTYPE_STANDARD, 80, theDocument.URL, null, null);
                standardUrl = standardUrl.QueryInterface(Components.interfaces.nsIURI);
                var standardURLHost = standardUrl.host.toLowerCase();
                
                // Making sure that the httpChannel's URL's host name matches the document host name.
                // I need to do this because I should not replace any swfs that are in different domains from
                // the document, because I will not be able to call SetVariable on it.
                // TODO: What about ports?!?
                var channelURI = httpChannel.URI;
                bContinue = (standardURLHost == channelURI.host.toLowerCase());
                // If the URIs don't match, then check if the flashvars exists, if there are no flashvars
                // then we can replace without any problems.
                    
                // Getting the httpChannel's resolved URL
                var sChannelResolvedPath = channelURI.spec.toLowerCase();
                
                var thePlugins = theDocument.plugins;
                if (thePlugins && thePlugins.length && thePlugins.length > 0)
                {
                    var pluginListLength = thePlugins.length;
                    for (var count = 0; count < pluginListLength; count++)
                    {
                        var currentPlugin = thePlugins.item(count);
                        // TODO: Need to do one for objects
                        if (currentPlugin)
                        {
                            // TODO: Is application/x-shockwave-flash the only type?
                            // If the current plugin is a flash plugin and the inputs match, then return this plugin
                            var pluginType = "";
                            if (currentPlugin.type)
                                pluginType = currentPlugin.type.toLowerCase();
                            if (currentPlugin.src && pluginType == "application/x-shockwave-flash")
                            {
                                var sCurrentPluginPathResolved = standardUrl.resolve(currentPlugin.src);
                                if (sCurrentPluginPathResolved)
                                    sCurrentPluginPathResolved = sCurrentPluginPathResolved.toLowerCase();
                                if (sChannelResolvedPath == sCurrentPluginPathResolved)
                                {
                                    // If there are flashvars and this flash plugin is pointing to a swf on a diff
                                    // host, then we should not replace because I cannot add the flashvars!
                                    if (!bContinue)
                                        bContinue = !(currentPlugin.hasAttribute("FlashVars"));
                                    
                                    if (bContinue)
                                        return currentPlugin;
                                    else
                                        break;
                                }
                            }
                        }
                    }
                }
            }
            catch(e)
            {
                dump("doesRequestMatchFlashControlInDocument error:"+e+"\n");
            }
        }
        return null;
    }
};

// RPJavascriptHelperObject class factory
var RPJavascriptHelperObjectFactory =
{
    singleton: null,
    createInstance: function (aOuter, aIID)
    {
        if (aOuter != null)
            throw Components.results.NS_ERROR_NO_AGGREGATION;
        if (!this.singleton)
            this.singleton = new RPJavascriptHelperObject();
        return this.singleton.QueryInterface(aIID);
    }
};

//module definition (xpcom registration)
var RPJavascriptHelperObjectModule =
{
    _firstTime: true,
    _originalClassID: "",
    registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
    {
        if (this._firstTime)
        {
            this._firstTime = false;
            throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
        }
        
        aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
        aCompMgr.registerFactoryLocation(RPJAVASCRIPTHELPEROBJECT_CLASS_ID, RPJAVASCRIPTHELPEROBJECT_CLASS_NAME, RPJAVASCRIPTHELPEROBJECT_CONTRACT_ID, aFileSpec, aLocation, aType);
    },

    unregisterSelf: function(aCompMgr, aLocation, aType)
    {
        aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
        aCompMgr.unregisterFactoryLocation(RPJAVASCRIPTHELPEROBJECT_CLASS_ID, aLocation);
    },
      
    getClassObject: function(aCompMgr, aCID, aIID)
    {
        if (!aIID.equals(Components.interfaces.nsIFactory))
            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

        if (aCID.equals(RPJAVASCRIPTHELPEROBJECT_CLASS_ID))
            return RPJavascriptHelperObjectFactory;

        throw Components.results.NS_ERROR_NO_INTERFACE;
    },

    canUnload: function(aCompMgr)
    {
        return true;
    }
};

//module initialization
function NSGetModule(aCompMgr, aFileSpec)
{
    return RPJavascriptHelperObjectModule;
}