/**
 * {@link Ext.TitleBar}'s are most commonly used as a docked item within an {@link Ext.Container}.
 *
 * The main difference between a {@link Ext.TitleBar} and an {@link Ext.Toolbar} is that
 * the {@link #title} configuration is **always** centered horiztonally in a {@link Ext.TitleBar},
 * no matter what other items you have in it.
 *
 * You can also give items of a {@link Ext.TitleBar} an `align` configuration of `left` or `right`
 * which will dock them to the `left` or `right` of the bar.
 *
 * # Example:
 *
 *     var myNavBar = new Ext.TitleBar({
 *         docked: 'top',
 *         title: 'Navigation',
 *         items: [
 *             {
 *                 text: 'My Button',
 *             },
 *             {
 *                 text: 'My Button',
 *                 align: 'right'
 *             }
 *         ]
 *     });
 *
 *     Ext.create('Ext.Container', {
 *         dockedItems: [myNavBar],
 *         fullscreen : true,
 *         html       : 'Test Panel'
 *     });
 *
 * The {@link #defaultType} of Toolbar's is {@link Ext.Button button}.
 */
Ext.define('Ext.TitleBar', {
    extend: 'Ext.Container',
    xtype: 'titlebar',

    requires: [
        'Ext.Button',
        'Ext.Title',
        'Ext.Spacer',
        'Ext.util.SizeMonitor'
    ],

    // private
    isToolbar: true,

    config: {
        // @inherit
        baseCls: Ext.baseCSSPrefix + 'toolbar',

        // @inherit
        cls: Ext.baseCSSPrefix + 'navigation-bar',

        /**
         * @cfg {String} ui
         * Style options for Toolbar. Either 'light' or 'dark'.
         * @accessor
         */
        ui: 'dark',

        /**
         * @cfg {String} title
         * The title of the toolbar.
         * @accessor
         */
        title: null,

        /**
         * @cfg {String} defaultType
         * The default xtype to create.
         * @accessor
         */
        defaultType: 'button',

        /**
         * @hide
         */
        layout: {
            type: 'hbox'
        },

        /**
         * @cfg {Array/Object} items The child items to add to this TitleBar. The {@link #defaultType} of
         * a TitleBar is {@link Ext.Button}, so you do not need to specify an `xtype` if you are adding
         * buttons.
         *
         * You can also give items a `align` configuration which will align the item to the `left` or `right` of
         * the TitleBar.
         * @accessor
         */
        items: []
    },

    /**
     * The max button width in this toolbar
     * @private
     */
    maxButtonWidth: '40%',

    constructor: function() {
        this.refreshTitlePosition = Ext.Function.createThrottled(this.refreshTitlePosition, 50, this);

        this.callParent(arguments);
    },

    beforeInitialize: function() {
        this.applyItems = this.applyInitialItems;
    },

    initialize: function() {
        delete this.applyItems;
        
        this.doAdd = this.doBoxAdd;
        this.remove = this.doBoxRemove;
        this.doInsert = this.doBoxInsert;

        this.add(this.initialItems);
        delete this.initialItems;

        this.on({
            painted: 'onPainted',
            erased: 'onErased'
        });
    },

    applyInitialItems: function(items) {
        var SizeMonitor = Ext.util.SizeMonitor,
            defaults = this.getDefaults() || {},
            leftBox, rightBox, spacer;

        this.initialItems = items;

        this.leftBox = leftBox = this.add({
            xtype: 'container',
            style: 'position: relative',
            layout: {
                type: 'hbox',
                align: 'center'
            }
        });

        this.spacer = spacer = this.add({
            xtype: 'component',
            style: 'position: relative',
            flex: 1
        });

        this.rightBox = rightBox = this.add({
            xtype: 'container',
            style: 'position: relative',
            layout: {
                type: 'hbox',
                align: 'center'
            }
        });

        this.titleComponent = this.add({
            xtype: 'title',
            hidden: defaults.hidden,
            centered: true
        });

        this.sizeMonitors = {
            leftBox: new SizeMonitor({
                element: leftBox.renderElement,
                callback: this.refreshTitlePosition,
                scope: this
            }),
            spacer: new SizeMonitor({
                element: spacer.renderElement,
                callback: this.refreshTitlePosition,
                scope: this
            }),
            rightBox: new SizeMonitor({
                element: rightBox.renderElement,
                callback: this.refreshTitlePosition,
                scope: this
            })
        };
    },

    doBoxAdd: function(item) {
        if (item.config.align == 'right') {
            this.rightBox.add(item);
        }
        else {
            this.leftBox.add(item);
        }

        if (this.painted) {
            this.refreshTitlePosition();
        }
    },

    doBoxRemove: function(item) {
        if (item.config.align == 'right') {
            this.rightBox.remove(item);
        }
        else {
            this.leftBox.remove(item);
        }

        if (this.painted) {
            this.refreshTitlePosition();
        }
    },

    doBoxInsert: function(index, item) {
        if (item.config.align == 'right') {
            this.rightBox.add(item);
        }
        else {
            this.leftBox.add(item);
        }
    },

    onPainted: function() {
        var sizeMonitors = this.sizeMonitors;

        this.painted = true;
        this.refreshTitlePosition();

        sizeMonitors.leftBox.refresh();
        sizeMonitors.spacer.refresh();
        sizeMonitors.rightBox.refresh();
    },

    onErased: function() {
        this.painted = false;
    },

    getMaxButtonWidth: function() {
        var value = this.maxButtonWidth;

        //check if it is a percentage
        if (Ext.isString(this.maxButtonWidth)) {
            value = parseInt(value.replace('%', ''), 10);
            value = Math.round((this.element.getWidth() / 100) * value);
        }

        return value;
    },

    refreshTitlePosition: function() {
        var titleElement = this.titleComponent.renderElement;

        titleElement.setWidth(null);
        titleElement.setLeft(null);

        //set the min/max width of the left button
        var leftBox = this.leftBox,
            leftButton = leftBox.down('button'),
            leftBoxWidth, maxButtonWidth;

        if (leftButton) {
            leftButton.renderElement.setWidth('auto');

            leftBoxWidth = leftBox.renderElement.getWidth();
            maxButtonWidth = this.getMaxButtonWidth();

            if (leftBoxWidth > maxButtonWidth) {
                leftButton.renderElement.setWidth(maxButtonWidth);
            }
        }

        var spacerBox = this.spacer.renderElement.getPageBox(),
            titleBox = titleElement.getPageBox(),
            widthDiff = titleBox.width - spacerBox.width,
            titleLeft = titleBox.left,
            titleRight = titleBox.right,
            halfWidthDiff, leftDiff, rightDiff;

        if (widthDiff > 0) {
            titleElement.setWidth(spacerBox.width);
            halfWidthDiff = widthDiff / 2;
            titleLeft += halfWidthDiff;
            titleRight -= halfWidthDiff;
        }

        leftDiff = spacerBox.left - titleLeft;
        rightDiff = titleRight - spacerBox.right;

        if (leftDiff > 0) {
            titleElement.setLeft(leftDiff);
        }
        else if (rightDiff > 0) {
            titleElement.setLeft(-rightDiff);
        }

        titleElement.repaint();
    },

    // @private
    updateTitle: function(newTitle) {
        this.titleComponent.setTitle(newTitle);

        this.titleBox = null;

        if (this.painted) {
            this.refreshTitlePosition();
        }
    },

    destroy: function() {
        this.callParent();

        var sizeMonitors = this.sizeMonitors;

        sizeMonitors.leftBox.destroy();
        sizeMonitors.spacer.destroy();
        sizeMonitors.rightBox.destroy();
    }
});