    /**
     * @class Ext.LoadMask
     * <p>A modal, floating Component which may be shown above a specified {@link Ext.core.Element Element}, or a specified
     * {@link Ext.Component Component} while loading data. When shown, the configured owning Element or Component will
     * be covered with a modality mask, and the LoadMask's {@link #msg} will be displayed centered, accompanied by a spinner image.</p>
     * <p>If the {@link #store} config option is specified, the masking will be automatically shown and then hidden synchronized with
     * the Store's loading process.</p>
     * <p>Because this is a floating Component, its z-index will be managed by the global {@link Ext.WindowManager ZIndexManager}
     * object, and upon show, it will place itsef at the top of the hierarchy.</p>
     * <p>Example usage:</p>
     * <pre><code>
    // Basic mask:
    var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
    myMask.show();
    </code></pre>

     */

    Ext.define('Ext.LoadMask', {

        extend: 'Ext.Component',

        alias: 'widget.loadmask',

        /* Begin Definitions */

        mixins: {
            floating: 'Ext.util.Floating'
        },

        uses: ['Ext.data.StoreManager'],

        /* End Definitions */

        /**
         * @cfg {Ext.data.Store} store
         * Optional Store to which the mask is bound. The mask is displayed when a load request is issued, and
         * hidden on either load success, or load fail.
         */

        /**
         * @cfg {String} msg
         * The text to display in a centered loading message box.
         */
        msg : 'Loading...',
        /**
         * @cfg {String} [msgCls="x-mask-loading"]
         * The CSS class to apply to the loading message element.
         */
        msgCls : Ext.baseCSSPrefix + 'mask-loading',

        /**
         * @cfg {Boolean} useMsg
         * Whether or not to use a loading message class or simply mask the bound element.
         */
        useMsg: true,

        /**
         * Read-only. True if the mask is currently disabled so that it will not be displayed
         * @type Boolean
         */
        disabled: false,

        baseCls: Ext.baseCSSPrefix + 'mask-msg',

        renderTpl: '<div style="position:relative" class="{msgCls}"></div>',

        // Private. The whole point is that there's a mask.
        modal: true,

        // Private. Obviously, it's floating.
        floating: {
            shadow: 'frame'
        },

        // Private. Masks are not focusable
        focusOnToFront: false,

        /**
         * Creates new LoadMask.
         * @param {String/HTMLElement/Ext.Element} el The element, element ID, or DOM node you wish to mask.
         * <p>Also, may be a {@link Ext.Component Component} who's element you wish to mask. If a Component is specified, then
         * the mask will be automatically sized upon Component resize, the message box will be kept centered,
         * and the mask only be visible when the Component is.</p>
         * @param {Object} [config] The config object
         */
        constructor : function(el, config) {
            var me = this;

            // If a Component passed, bind to it.
            if (el.isComponent) {
                me.ownerCt = el;
                me.bindComponent(el);
            }
            // Create a dumy Component encapsulating the specified Element
            else {
                me.ownerCt = new Ext.Component({
                    el: Ext.get(el),
                    rendered: true,
                    componentLayoutCounter: 1
                });
                me.container = el;
            }
            me.callParent([config]);

            if (me.store) {
                me.bindStore(me.store, true);
            }
            me.renderData = {
                msgCls: me.msgCls
            };
            me.renderSelectors = {
                msgEl: 'div'
            };
        },

        bindComponent: function(comp) {
            this.mon(comp, {
                resize: this.onComponentResize,
                scope: this
            });
        },

        afterRender: function() {
            this.callParent(arguments);
            this.container = this.floatParent.getContentTarget();
        },

        /**
         * @private
         * Called when this LoadMask's Component is resized. The toFront method rebases and resizes the modal mask.
         */
        onComponentResize: function() {
            var me = this;
            if (me.rendered && me.isVisible()) {
                me.toFront();
                me.center();
            }
        },

        /**
         * Changes the data store bound to this LoadMask.
         * @param {Ext.data.Store} store The store to bind to this LoadMask
         */
        bindStore : function(store, initial) {
            var me = this;

            if (!initial && me.store) {
                me.mun(me.store, {
                    scope: me,
                    beforeload: me.onBeforeLoad,
                    load: me.onLoad,
                    exception: me.onLoad
                });
                if (!store) {
                    me.store = null;
                }
            }
            if (store) {
                store = Ext.data.StoreManager.lookup(store);
                me.mon(store, {
                    scope: me,
                    beforeload: me.onBeforeLoad,
                    load: me.onLoad,
                    exception: me.onLoad
                });

            }
            me.store = store;
            if (store && store.isLoading()) {
                me.onBeforeLoad();
            }
        },

        onDisable : function() {
            this.callParent(arguments);
            if (this.loading) {
                this.onLoad();
            }
        },

        // private
        onBeforeLoad : function() {
            var me = this,
                owner = me.ownerCt || me.floatParent,
                origin;
            if (!this.disabled) {
                // If the owning Component has not been layed out, defer so that the ZIndexManager
                // gets to read its layed out size when sizing the modal mask
                if (owner.componentLayoutCounter) {
                    Ext.Component.prototype.show.call(me);
                } else {
                    // The code below is a 'run-once' interceptor.
                    origin = owner.afterComponentLayout;
                    owner.afterComponentLayout = function() {
                        owner.afterComponentLayout = origin;
                        origin.apply(owner, arguments);
                        if(me.loading) {
                            Ext.Component.prototype.show.call(me);
                        }
                    };
                }
            }
        },

        onHide: function(){
            var me = this;
            me.callParent(arguments);
            me.showOnParentShow = true;
        },

        onShow: function() {
            var me = this,
                msgEl = me.msgEl;

            me.callParent(arguments);
            me.loading = true;
            if (me.useMsg) {
                msgEl.show().update(me.msg);
            } else {
                msgEl.parent().hide();
            }
        },

        afterShow: function() {
            this.callParent(arguments);
            this.center();
        },

        // private
        onLoad : function() {
            this.loading = false;
            Ext.Component.prototype.hide.call(this);
        }
    });