var FO = function(src, xtras) {
    this.__xtras = xtras || {};
    this.__attrs = {};
    this.__params = {};
    this.__flashvars = [];

    this.__loaded = false;
    this.__alt = '';
    this.__version = this.__get('version', '6,0,40,0');

    this.__attrs['width'] = this.__get('width', '500');
    this.__attrs['height'] = this.__get('height', '400');
    this.__attrs['id'] = this.__get('id', this.__extractId(src));
    this.__attrs['align'] = this.__get('align', 'middle');

    this.__params['movie'] = src;
    for (var name in this.__xtras) {
        if (name == 'flashvars') {
            this.__getFlashVars();
        } else {
            this.__params[name] = this.__get(name);
        }
    }

    var self = this;
    if (document.addEventListener) {
        document.addEventListener('load', function() { self.__loaded = true; }, false);
        window.addEventListener('load', function() { self.__loaded = true; }, false);
    } else if (document.attachEvent) {
        document.attachEvent('onload', function() { self.__loaded = true; });
    }
};
FO.prototype = {
    write: function(target) {
        var obj = this.__getObj(target);

        if (!obj && !this.__loaded) {
            var self = this;
            this.__timerId = setInterval(function() {
                self.__poll.apply(self, [target]);
            }, 10);
        } else if (obj) {
            this.__doWrite(obj);
        }
    },

    addVar: function(name, value) {
        this.__flashvars[this.__flashvars.length] = {name: name, value: escape(value)};
    },

    __build: function() {
        var content = '';
        if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
            content  = '<object data="' + this.__params['movie'] + '" type="application/x-shockwave-flash"';
            for (var attr in this.__attrs) {
                content += ' ' + attr + '="' + this.__attrs[attr] + '"';
            }
            content += '> <param name="pluginurl" value="http://www.macromedia.com/go/getflashplayer" />';

            delete this.__params['movie'];
            for (var param in this.__params) {
                content += '  <param name="' + param + '" value="' + this.__params[param] + '" />';
            }
        } else {
            content += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + this.__version + '"';
            for (var attr in this.__attrs) {
                content += ' ' + attr + '="' + this.__attrs[attr] + '"';
            }
            content += '>';
            for (var param in this.__params) {
                content += '  <param name="' + param + '" value="' + this.__params[param] + '" />';
            }
        }
        content += this.__buildFlashVars();
        if (typeof this.__alt == 'string') {
            content += this.__alt;
        }
        content += '</object>';
        return content;
    },

    __poll: function(target) {
        var obj = this.__getObj(target);
        if (obj || this.__loaded) {
            if (obj) {
                this.__doWrite(obj);
            } else {
                alert(target + ' does not exist');
            }
            clearInterval(this.__timerId);
        }
    },

    __doWrite: function(obj) {
        this.__setAlt(obj);
        if (!this.__innerXHTML(this.__build(), obj)) {
            alert('XHTML ERROR');
            return;
        }

        if (typeof this.__alt != 'string') {
            this.__import(this.__alt, obj.firstChild);
        }
    },

    __innerXHTML: function(src, obj) {
        if (!window.DOMParser) {
            obj.innerHTML = src;
            return true;
        }

        try {
            var dom = new DOMParser().parseFromString('<div xmlns="http://www.w3.org/1999/xhtml">' + src + '</div>', 'application/xhtml+xml');
            if (dom.firstChild.nodeName == 'parsererror') {
                return false;
            }
        } catch(e) {
            return false;
        }

        this.__clear(obj);
        this.__import(dom.firstChild, obj);
        return true;
    },

    __buildFlashVars: function() {
        var n = this.__flashvars.length;
        if (n == 0) return '';
        var str = '<param name="flashvars" value="&amp;';
        for (var i = 0; i < n; ++i) {
            str += this.__flashvars[i].name + '=' + this.__flashvars[i].value + '&amp;';
        }
        str += '" />';
        return str;
    },
    
    __getFlashVars: function() {
        var bits = this.__xtras.flashvars.split(/&|&amp;/);
        var n = bits.length;
        for (var i = 0; i < n; ++i) {
            if (bits[i].indexOf('=') == -1) continue;
            var nameAndValue = bits[i].split('=');
            this.addVar(nameAndValue[0], nameAndValue[1]);
        }
        delete this.__xtras.flashvars;
    },

    __setAlt: function(obj) {
        this.__alt = (window.DOMParser) ? obj.cloneNode(true) : obj.innerHTML;
    },

    __getObj: function(target) {
        if (target) return document.getElementById(target);
        if (document.getElementsByTagName('body')) return document.getElementsByTagName('body')[0];
        return false;
    },

    __get: function(name, def) {
        var val = this.__xtras[name] || def;
        delete this.__xtras[name];
        return val;
    },

    __extractId: function(str) {
        var s = str.lastIndexOf('/') + 1;
        return str.substring(s, str.indexOf('.', s));
    },

    __import: function(src, target) {
        var n = src.childNodes.length;
        for (var i = 0; i < n; ++i) {
            target.appendChild(document.importNode(src.childNodes[i], true));
        }
    },

    __clear: function(obj) {
        while (obj.hasChildNodes()) {
           obj.removeChild(obj.firstChild);
        }
    }
};