/**
 * This class is used to wrap content items in the `Dashboard`. It uses an
 * `anchor` layout by default and provides resizing on the bottom edge only.
 * @protected
 */
Ext.define('Ext.dashboard.Panel', {
    extend: 'Ext.panel.Panel',
 
    xtype: 'dashboard-panel',
 
    cls: Ext.baseCSSPrefix + 'dashboard-panel',
 
    anchor: '100%',
 
    layout: 'fit',
 
    frame: true,
    closable: true,
    collapsible: true,
    animCollapse: true,
    titleCollapse: true,
 
    stateful: true,
 
    draggable: {
        moveOnDrag: false
    },
 
    animateClose: true,
 
    loadMask: true,
    loadMessage: 'Loading...',
 
    minHeight: 90,
 
    resizable: true,
    resizeHandles: 's',
 
    // Override Panel's default doClose to provide a custom fade out effect
    // when a portlet is removed from the portal
    doClose: function() {
        var me = this;
 
        if (me.animateClose) {
            if (!me.closing) {
                me.closing = true;
                me.el.animate({
                    opacity: 0,
                    callback: me.finishClose,
                    scope: me
                });
            }
        }
        else {
            me.finishClose();
        }
    },
 
    finishClose: function() {
        var me = this,
            closeAction = me.closeAction;
 
        me.closing = false;
        me.fireEvent('close', me);
 
        // The close of the last portlet within a column results in removal of both the column
        // and its splitter.
        // So coalesce any layouts resulting from this operation.
        Ext.suspendLayouts();
        me[closeAction]();
        Ext.resumeLayouts(true);
 
        if (closeAction === 'hide') {
            // Restore the opacity from doClose
            me.el.setOpacity(1);
        }
    },
 
    afterRender: function() {
        this.callParent();
 
        if (this.loading) {
            this.onViewBeforeLoad();
        }
    },
 
    doCollapseExpand: function(flags) {
        // Ensure the layout caused by expand or collapse does not propagate
        // to the whole dashboard. The dashboard layout is automatically
        // updated after the operation.
        this._expandCollapseRoot = this._isLayoutRoot;
        this._isLayoutRoot = true;
        this.callParent(arguments);
    },
 
    afterExpand: function() {
        this._isLayoutRoot = this._expandCollapseRoot;
        this.callParent(arguments);
    },
 
    afterCollapse: function() {
        this._isLayoutRoot = this._expandCollapseRoot;
        this.callParent(arguments);
    },
 
    getLoadMask: function() {
        var me = this,
            loadMask = me.rendered && me.loadMask,
            config;
 
        if (loadMask && !loadMask.isComponent) {
            config = {
                target: me
            };
 
            if (loadMask === true) {
                loadMask = config;
            }
            else {
                Ext.apply(config, loadMask);
            }
 
            me.loadMask = loadMask = Ext.ComponentManager.create(config, 'loadmask');
        }
 
        return loadMask || null;
    },
 
    onAdd: function(view) {
        this.callParent(arguments);
 
        view.on({
            beforeload: 'onViewBeforeLoad',
            load: 'onViewLoaded',
            scope: this
        });
    },
 
    onViewBeforeLoad: function() {
        var loadMask;
        
        this.loading = true;
        loadMask = this.getLoadMask();
 
        if (loadMask) {
            loadMask.show();
        }
    },
 
    onViewLoaded: function() {
        var loadMask, view, title;
        
        this.loading = false;
        loadMask = this.getLoadMask();
 
        if (loadMask) {
            loadMask.hide();
        }
        
        view = this.items.getAt(0);
 
        if (view.getTitle) {
            title = view.getTitle();
 
            if (title) {
                this.setTitle(title);
            }
        }
    },
 
    /**
     * @private
     */
    setBox: function(box) {
        // The resizer calls setBox which would set our left/top coordinates but
        // that is a BAD thing in a column layout which relies on flow!
        this.setSize(box.width, box.height);
    },
 
    /**
     * @private
     */
    getState: function() {
        var me = this,
            state = me.callParent() || {};
 
        if (!state.collapsed) {
            me.addPropertyToState(
                state, 'height', me.rendered ? me.getHeight() : me.height || me.minHeight || 100
            );
        }
 
        return state;
 
    }
});