/*
    Here's the getter for Params.
    
    1. When parsing an html element, if there are 2 or more attributes with the same name, 
       the first one is picked and duplicates are ignored.
    
    2. A param element's name and value attributes make up a parameter. Attributes 
       make up parameters too. Since attributes come before the child nodes of the element, 
       attributes get picked first and if a param element makes a duplicate parameter, the 
       attribute gets priority and the parameter the param element makes is ignored or in a 
       sense, overridden.  That means if you have data="test" and <param name="data" value="no">, 
       the value of the data param passed will be "test" and NOT "no". This also means that if you 
       have 2 params with the same name attribute value, the first one gets picked.

    3. Normalize the case of param names to lowercase.

    To do all that, get the param elements first where an existing param cannot be overwritten.
    Then, get the attributes and let them overwrite an existing param.
*/

HTMLObjectElement.prototype.getParams = function() {
    var p = this.getElementsByTagName("param");
    var params = new Object();
    for ( var i = 0; i < p.length; ++i ) {
        if ( p[i].hasAttribute("name") && p[i].hasAttribute("value") && !params[ p[i].getAttribute("name").toLowerCase() ] ) {
            params[ p[i].getAttribute("name").toLowerCase() ] = p[i].getAttribute("value");
        }
    }
    var attr = this.attributes;
    for ( var i = 0;  i < attr.length; ++i) {
        if ( attr[i].name.toLowerCase() == "classid" && attr[i].value.toLowerCase().indexOf("java:") == 0 && attr[i].value.length > 5 ) {
            params[ "code" ] = attr[i].value.substring(5);
        } else if ( attr[i].name.toLowerCase() != "classid" ) {
            params[ attr[i].name.toLowerCase() ] = attr[i].value;
        }
    }
    return params;
};

/*
    Here's where fixes are applied - Depending on the type attribute value.

    1. The codebase is only used when there's not a plugin download URI present.
    
    2. The data attribute is mapped to other param(s) when necessary, which may 
       override. Before mapping, the codebase might be used to generate an absolute URI.

    3. If a plugin has its own param for codebase use, the codebase might be mapped to 
       that instead of using the codebase to generate an absolute URI for mapping to some 
       param.

    4. Codebase might be used to resolve a param that is known to be used as a src param.

    5. Classid is ignored except for Java.

    6. Params can be invented when necessary.

    7. Codebase is only used to directly resolve a data param for plugins that recognize 
       the data attribute, but don't recognize the codebase param.

*/

HTMLObjectElement.prototype.applyFixes = function(p) {
    if ( p["type"] ) {
        var type = p["type"].toLowerCase();
        switch ( type ) {
            case "application/asx" : case "video/x-ms-asf-plugin" : case "application/x-mplayer2":
            case "video/x-ms-wm"   : case "audio/x-ms-wma"        : case "audio/x-ms-wax":
            case "video/x-ms-wvx"  : case "video/x-ms-wmv"        : case "video/x-ms-asf":
                if ( p["data"] ) {
                    p["src"] = p["data"];
                    p["filename"] = p["data"];
                } 
                if ( p["codebase"] && p["codebase"].toLowerCase().indexOf("http://activex.microsoft.com/activex/controls/mplayer/") == -1 ) {
                    p["baseurl"] = p["codebase"];
                }
                break;
            case "audio/x-pn-realaudio-plugin":
                if ( p["data"] ) {
                    if ( p["codebase"] ) {
                        p["src"] = p["codebase"] + p["data"] ;
                    } else {
                        p["src"] = p["data"];
                    }
                } else if ( p["src"] && p["codebase"]) {
                    p["src"] =  p["codebase"] + p["src"] ;
                }
                break;
            case "application/futuresplash": case "application/x-shockwave-flash": case "application/x-director":
            break;
        }
    }
    if ( p["classid"] && p["classid"].length >= 5 && p["classid"].toLowerCase().indexOf("java:") == 0 ) {
        p["code"] = p["classid"].substring(5);
        if ( p["codebase"] && p["codebase"].toLowerCase().indexOf("http://java.sun.com/products/plugin/autodl/") != -1 ) {
            delete p["codebase"];
        }
    }
    return p;
};


/* Just some silly function to generate a table */

HTMLObjectElement.prototype.createParamTable = function(title,params) {
    var argc = 0;
    var argn = new Array();
    var argv = new Array();
    for ( i in params ) {
        argn[argc] = i;
        argv[argc] = params[i];
        ++argc;
    }
    var table = this.document.createElement("table");
    table.setAttribute("border", "1");
    table.setAttribute("cellpadding", "5");
    table.style.textAlign = "center";
    table.style.marginBottom = "10px";
    var head = this.document.createElement("caption");
    head.style.fontWeight = "bold";
    head.style.fontSize = "18px";
    head.appendChild ( this.document.createTextNode( title ) );
    table.appendChild( head );
    function createTD(text) {
        var temp = this.document.createElement("td");
        temp.appendChild( this.document.createTextNode( text ) );
        return temp;
    }
    var ftr = this.document.createElement("tr");
    ftr.style.fontWeight = "bold";
    ftr.appendChild( createTD( "argc(" + argc + ")" ) );
    ftr.appendChild( createTD( "argn" ) );
    ftr.appendChild( createTD( "argv" ) );
    table.appendChild( ftr );
    var count = 0;
    for ( i in params ) {
        var tr = this.document.createElement("tr");
        tr.appendChild( createTD( count ) );
        tr.appendChild( createTD( i ) );
        if ( params[i] == "" ) {
            tr.appendChild( createTD( '""' ) );
        } else {
            tr.appendChild( createTD( params[i] ) );
        }
        table.appendChild( tr );
        ++count;
    }
    return table;
};
