/**
 * A simple Component for displaying an Adobe Flash SWF movie. The movie will be sized and can
 * participate in layout like any other Component.
 *
 * This component requires the third-party SWFObject library version 2.2 or above. It is not
 * included within the ExtJS distribution, so you will have to include it into your page manually
 * in order to use this component.
 * The SWFObject library can be downloaded from the [SWFObject project page](http://code.google.com/p/swfobject)
 * and then simply import it into the head of your HTML document:
 *
 *     <script type="text/javascript" src="path/to/local/swfobject.js"></script>
 *
 * ## Configuration
 *
 * This component allows several options for configuring how the target Flash movie is embedded.
 * The most important is the required {@link #url} which points to the location of the Flash movie
 * to load. Other configurations include:
 *
 * - {@link #backgroundColor}
 * - {@link #wmode}
 * - {@link #flashVars}
 * - {@link #flashParams}
 * - {@link #flashAttributes}
 *
 * ## Example usage:
 *
 *     var win = Ext.widget('window', {
 *         title: "It's a tiger!",
 *         layout: 'fit',
 *         width: 300,
 *         height: 300,
 *         x: 20,
 *         y: 20,
 *         resizable: true,
 *         items: {
 *             xtype: 'flash',
 *             url: 'tiger.swf'
 *         }
 *     });
 *     win.show();
 *
 * ## Express Install
 *
 * Adobe provides a tool called [Express Install](http://www.adobe.com/devnet/flashplayer/articles/express_install.html)
 * that offers users an easy way to upgrade their Flash player. If you wish to make use of this,
 * you should set the static EXPRESS_INSTALL_URL property to the location of your Express Install
 * SWF file:
 *
 *     Ext.flash.Component.EXPRESS_INSTALL_URL = 'path/to/local/expressInstall.swf';
 */
Ext.define('Ext.flash.Component', {
    extend: 'Ext.Component',
    alternateClassName: 'Ext.FlashComponent',
    alias: 'widget.flash',
 
    /**
     * @cfg {String} [flashVersion="9.0.115"]
     * Indicates the version the flash content was published for.
     */
    flashVersion: '9.0.115',
 
    /**
     * @cfg {String} [backgroundColor="#ffffff"]
     * The background color of the SWF movie.
     */
    backgroundColor: '#ffffff',
 
    /**
     * @cfg {String} [wmode="opaque"]
     * The wmode of the flash object. This can be used to control layering.
     * Set to 'transparent' to ignore the {@link #backgroundColor} and make the background
     * of the Flash movie transparent.
     */
    wmode: 'opaque',
 
    /**
     * @cfg {Object} flashVars
     * A set of key value pairs to be passed to the flash object as flash variables.
     */
 
    /**
     * @cfg {Object} flashParams
     * A set of key value pairs to be passed to the flash object as parameters. Possible parameters
     * can be found here: http://kb2.adobe.com/cps/127/tn_12701.html
     */
 
    /**
     * @cfg {Object} flashAttributes
     * A set of key value pairs to be passed to the flash object as attributes.
     */
 
    /**
     * @cfg {String} url (required)
     * The URL of the SWF file to include.
     */
 
    /**
     * @cfg {String/Number} [swfWidth="100%"]
     * The width of the embedded SWF movie inside the component.
     *
     * Defaults to "100%" so that the movie matches the width of the component.
     */
    swfWidth: '100%',
 
    /**
     * @cfg {String/Number} [swfHeight="100%"]
     * The height of the embedded SWF movie inside the component.
     *
     * Defaults to "100%" so that the movie matches the height of the component.
     */
    swfHeight: '100%',
 
    /**
     * @cfg {Boolean} [expressInstall=false]
     * True to prompt the user to install flash if not installed. Note that this uses
     * Ext.FlashComponent.EXPRESS_INSTALL_URL, which should be set to the local resource.
     */
    expressInstall: false,
 
    /**
     * @property {Ext.dom.Element} swf
     * A reference to the object or embed element into which the SWF file is loaded. Only
     * populated after the component is rendered and the SWF has been successfully embedded.
     */
 
    // Have to create a placeholder div with the swfId, which SWFObject will replace with the
    // object/embed element.
    renderTpl: ['<div id="{swfId}" role="application"></div>'],
 
    /**
     * @event success
     * Fired when the Flash movie has been successfully embedded
     * @param {Ext.flash.Component} this 
     */
 
    /**
     * @event failure
     * Fired when the Flash movie embedding fails
     * @param {Ext.flash.Component} this 
     */
 
    initComponent: function() {
        /* global swfobject */
        // <debug>
        if (!('swfobject' in window)) {
            Ext.raise('The SWFObject library is not loaded. Ext.flash.Component requires ' +
                      'SWFObject version 2.2 or later: http://code.google.com/p/swfobject/');
        }
 
        if (!this.url) {
            Ext.raise('The "url" config is required for Ext.flash.Component');
        }
        // </debug>
 
        this.callParent();
    },
    
    beforeRender: function() {
        this.callParent();
        
        Ext.applyIf(this.renderData, {
            swfId: this.getSwfId()
        });
    },
 
    afterRender: function() {
        var me = this,
            flashParams = Ext.apply({}, me.flashParams),
            flashVars = Ext.apply({}, me.flashVars);
 
        me.callParent();
 
        flashParams = Ext.apply({
            allowScriptAccess: 'always',
            bgcolor: me.backgroundColor,
            wmode: me.wmode
        }, flashParams);
 
        flashVars = Ext.apply({
            allowedDomain: document.location.hostname
        }, flashVars);
 
        new swfobject.embedSWF(
            me.url,
            me.getSwfId(),
            me.swfWidth,
            me.swfHeight,
            me.flashVersion,
            me.expressInstall ? me.statics.EXPRESS_INSTALL_URL : undefined,
            flashVars,
            flashParams,
            me.flashAttributes,
            me.swfCallback.bind(me)
        );
    },
 
    /**
     * @private
     * The callback method for handling an embedding success or failure by SWFObject
     * @param {Object} e The event object passed by SWFObject - see http://code.google.com/p/swfobject/wiki/api
     */
    swfCallback: function(e) {
        var me = this;
 
        if (e.success) {
            me.swf = Ext.get(e.ref);
            me.onSuccess();
            me.fireEvent('success', me);
        }
        else {
            me.onFailure();
            me.fireEvent('failure', me);
        }
    },
 
    /**
     * Retrieves the id of the SWF object/embed element.
     */
    getSwfId: function() {
        return this.swfId || (this.swfId = "extswf" + this.getAutoId());
    },
 
    onSuccess: function() {
        // swfobject forces visiblity:visible on the swf element, which prevents it 
        // from getting hidden when an ancestor is given visibility:hidden.
        this.swf.setStyle('visibility', 'inherit');
    },
 
    onFailure: Ext.emptyFn,
 
    doDestroy: function() {
        var me = this,
            swf = me.swf;
        
        if (swf) {
            swfobject.removeSWF(me.getSwfId());
            me.swf = Ext.destroy(swf);
        }
        
        me.callParent();
    },
 
    statics: {
        /**
         * @property {String} 
         * The url for installing flash if it doesn't exist. This should be set to a local resource.
         * See [http://get.adobe.com/flashplayer/](http://get.adobe.com/flashplayer/) for details.
         * @static
         */
        EXPRESS_INSTALL_URL: 'http://swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf'
    }
});