var FlashInject = {
	objCounter: 0,
	/* go thru the document and REWRITE it:
	 *
	 * 1. wrap each object with an ID'ed span,
	 * 2. parse & remove cntents of span,
	 * 3. inject new/dynamically generated object tags
	 */
	runCalled: false,
	run: function() {
        if (FlashInject.runCalled) {
            return;
        } else {
            FlashInject.runCalled = true;
        }

	    parsedObjs = [];

	    // determine that we have the necessary functionality
	    if ((typeof UFO == 'undefined') || !UFO.is_w3cdom) return;

	    // find all the dom elements with tagName 'OBJECT'
        objs = document.getElementsByTagName('OBJECT');
        if (!objs || !objs.length) {
            return;
        }

        for (var i = 0; i < objs.length; i++) {
            // determine whether this is a flash object
            // codebase: 'swflash.cab'
            codeBase = objs[i].getAttribute('codebase'); if (!codeBase) { codeBase = objs[i]['codebase']; }
            if (!codeBase || (codeBase.indexOf('swflash.cab') === false)) {
                continue;
            }

            // try to parse out the ness. info from the dom <OBJECT> element\
            // and add it to our stack if we succeed.
            if (o = FlashInject.parseObj( objs[i] )) {
                parsedObjs[parsedObjs.length] = {'newobj':o, 'oldobj':objs[i]};
            }
        }

        // go through our parsed data, inject a usable (with id attribute) wrapper element,
        // remove the original element and call the creation routine with the required info
        for (var i = 0; i < parsedObjs.length; i++) {
            // inject the span
            span    = document.createElement('SPAN');
            span.id = parsedObjs[i]['newobj']['id'];

            parsedObjs[i]['oldobj'].parentNode.insertBefore(span, parsedObjs[i]['oldobj']);

            // hide the original element
            if (styleObj = FlashInject.getStyleObj( parsedObjs[i]['oldobj'] )) {
                styleObj.visibility = 'hidden';
                styleObj.display    = 'none';
            }

            // create a new OBJECT element
            if (UFO.create(parsedObjs[i]['newobj']['obj'], parsedObjs[i]['newobj']['id']) ) {
                // remove the old element from the DOM.
                parsedObjs[i]['oldobj'].parentNode.removeChild( parsedObjs[i]['oldobj'] );
            } else if (styleObj) {
                // show the orginal element again if the insert of the new element failed
                styleObj.visibility = 'visible';
                styleObj.display    = '';
            }
        }
	},

	parseObj: function(domEl)  {

        // try to determine the required major and minor [SW Flash] version of the flash movie
	    codeBase = domEl.getAttribute('codebase'); if (!codeBase) { codeBase = domEl['codebase']; }
	    if (!codeBase) {
            return;
	    } else {
	        vArr   = codeBase.replace(/^.*=/, '').split(",");
            if (!vArr.length) {
                return;
            }
	    }

	    majorV = parseInt(vArr[0]);
	    minorV = parseInt(vArr[2]);

        // to to parse out a number of OBJECT tag PARAM children - some required, some optional
        if (!domEl.childNodes.length) {
            return;
	    } else {
            for (var i = 0; i < domEl.childNodes.length; i++) {
                if (domEl.childNodes[i].tagName != 'PARAM') {
                    continue;
                }

                name = domEl.childNodes[i].getAttribute('name');  if (!name) { name = domEl.childNodes[i]['name'].toLowerCase();  }
                val  = domEl.childNodes[i].getAttribute('value'); if (!val)  { val  = domEl.childNodes[i]['value'];               }

                if (name) {
                    switch (name) {
                        case 'movie':
                            url     = val;
                            break;
                        case 'quality':
                            quality = val;
                            break;
                        case 'wmode':
                            wmode   = val;
                            break;
                        case 'allowScriptAccess':
                            asa     = val;
                            break;
                        case 'menu':
                            smenu   = val;
                            break;
                        case 'scale':
                            scale   = val;
                            break;
                        case 'bgcolor':
                            bgcol   = val;
                            break;

                    }
                }
            }
	    }

	    // try to determine the required width and height info.
	    width  = domEl.getAttribute('width');  if (!width)  { width  = domEl['width'];  }
	    height = domEl.getAttribute('height'); if (!height) { height = domEl['height']; }

	    // check we have the required information
	    if (((typeof url == 'undefined') || !url) || !width || !height || (typeof majorV != 'number') || (typeof minorV != 'number')) {
	        return false;
	    }

	    // create the object with the required info.
        thenewobj = {'movie': url, 'width': width, 'height': height, 'majorversion': majorV, 'build': minorV};

        // add some optional information/params - if they exist.
        if (((typeof wmode   != 'undefined') && wmode))   thenewobj['wmode']                = wmode;
        if (((typeof quality != 'undefined') && quality)) thenewobj['quality']              = quality;
        if (((typeof sas     != 'undefined') && asa))     thenewobj['allowScriptAccess']    = asa;
        if (((typeof smenu   != 'undefined') && smenu))   thenewobj['menu']                 = smenu;
        if (((typeof scale   != 'undefined') && scale))   thenewobj['scale']                = scale;
        if (((typeof bgcol   != 'undefined') && bgcol))   thenewobj['bgcolor']              = bgcol;

        // crank up the count of the objects we have successfully parsed - this allows us to generate an id attribute
        // in the caller function.
        FlashInject.objCounter++;

        // return the data required to inject a flash object.
	    return {
	               'id':  'flashWrapper'+FlashInject.objCounter,
	               'obj': thenewobj
	           };
	},

	// cross-browser function to get an object's style object given its id
    getStyleObj: function(object) {
        if(document.getElementById) {
            // W3C DOM
            return object.style;
        } else if (document.all) {
            // MSIE 4 DOM
            return object.style;
        } else if (document.layers) {
        	// NN 4 DOM.. note: this won't find nested layers
        	return object;
        } else {
    	   return false;
        }
    }
}

// add an onload event to automatically replace any flash element in the page
// with javascript generated ones - thanks to Eidos and M$ for the need to do this.
addEvent( window, 'load', function(){FlashInject.run();} );