    /*!
     * Ext JS Library 3.0.3
     * Copyright(c) 2006-2009 Ext JS, LLC
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    /**
     * @class Ext.layout.BoxLayout
     * @extends Ext.layout.ContainerLayout
     * Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.
     */
    Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
        /**
         * @cfg {Object} defaultMargins
         * If the individual contained items do not have a margins
         * property specified, the default margins from this property will be
         * applied to each item.
         *
    This property may be specified as an object containing margins
         * to apply in the format:
    {
        top: (top margin),
        right: (right margin),
        bottom: (bottom margin),
        left: (left margin)
    }
         * This property may also be specified as a string containing
         * space-separated, numeric margin values. The order of the sides associated
         * with each value matches the way CSS processes margin values:
         *
         * If there is only one value, it applies to all sides.
         * If there are two values, the top and bottom borders are set to the
         * first value and the right and left are set to the second.
         * If there are three values, the top is set to the first value, the left
         * and right are set to the second, and the bottom is set to the third.
         * If there are four values, they apply to the top, right, bottom, and
         * left, respectively.
         *
         * Defaults to:
         * {top:0, right:0, bottom:0, left:0}
         *
         */
        defaultMargins : {left:0,top:0,right:0,bottom:0},
        /**
         * @cfg {String} padding
         * Sets the padding to be applied to all child items managed by this layout.
         * This property must be specified as a string containing
         * space-separated, numeric padding values. The order of the sides associated
         * with each value matches the way CSS processes padding values:
         *
         * If there is only one value, it applies to all sides.
         * If there are two values, the top and bottom borders are set to the
         * first value and the right and left are set to the second.
         * If there are three values, the top is set to the first value, the left
         * and right are set to the second, and the bottom is set to the third.
         * If there are four values, they apply to the top, right, bottom, and
         * left, respectively.
         *
         * Defaults to: "0"
         */
        padding : '0',
        // documented in subclasses
        pack : 'start',

        // private
        monitorResize : true,
        scrollOffset : 0,
        extraCls : 'x-box-item',
        ctCls : 'x-box-layout-ct',
        innerCls : 'x-box-inner',

        constructor : function(config){
            Ext.layout.BoxLayout.superclass.constructor.call(this, config);
            if(Ext.isString(this.defaultMargins)){
                this.defaultMargins = this.parseMargins(this.defaultMargins);
            }
        },

        // private
        isValidParent : function(c, target){
            return c.getEl().dom.parentNode == this.innerCt.dom;
        },

        // private
        onLayout : function(ct, target){
            var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;

            if(!this.innerCt){
                target.addClass(this.ctCls);

                // the innerCt prevents wrapping and shuffling while
                // the container is resizing
                this.innerCt = target.createChild({cls:this.innerCls});
                this.padding = this.parseMargins(this.padding);
            }
            this.renderAll(ct, this.innerCt);
        },

        // private
        renderItem : function(c){
            if(Ext.isString(c.margins)){
                c.margins = this.parseMargins(c.margins);
            }else if(!c.margins){
                c.margins = this.defaultMargins;
            }
            Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
        },

        getTargetSize : function(target){
            return (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize();
        },

        getItems: function(ct){
            var items = [];
            ct.items.each(function(c){
                if(c.isVisible()){
                    items.push(c);
                }
            });
            return items;
        }

        /**
         * @property activeItem
         * @hide
         */
    });

    /**
     * @class Ext.layout.VBoxLayout
     * @extends Ext.layout.BoxLayout
     * A layout that arranges items vertically down a Container. This layout optionally divides available vertical
     * space between child items containing a numeric flex configuration.
     * This layout may also be used to set the widths of child items by configuring it with the {@link #align} option.
     */
    Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
        /**
         * @cfg {String} align
         * Controls how the child items of the container are aligned. Acceptable configuration values for this
         * property are:
         *
         * left : Defaultchild items are aligned horizontally
         * at the left side of the container
         * center : child items are aligned horizontally at the
         * mid-width of the container
         * stretch : child items are stretched horizontally to fill
         * the width of the container
         * stretchmax : child items are stretched horizontally to
         * the size of the largest item.
         *
         */
        align : 'left', // left, center, stretch, strechmax
        /**
         * @cfg {String} pack
         * Controls how the child items of the container are packed together. Acceptable configuration values
         * for this property are:
         *
         * start : Defaultchild items are packed together at
         * top side of container
         * center : child items are packed together at
         * mid-height of container
         * end : child items are packed together at bottom
         * side of container
         *
         */
        /**
         * @cfg {Number} flex
         * This configuation option is to be applied to child items of the container managed
         * by this layout. Each child item with a flex property will be flexed vertically
         * according to each item's relative flex value compared to the sum of all items with
         * a flex value specified.  Any child items that have either a flex = 0 or
         * flex = undefined will not be 'flexed' (the initial size will not be changed).
         */

        // private
        onLayout : function(ct, target){
            Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);

            var cs = this.getItems(ct), cm, ch, margin,
                size = this.getTargetSize(target),
                w = size.width - target.getPadding('lr'),
                h = size.height - target.getPadding('tb') - this.scrollOffset,
                l = this.padding.left, t = this.padding.top,
                isStart = this.pack == 'start',
                isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
                stretchWidth = w - (this.padding.left + this.padding.right),
                extraHeight = 0,
                maxWidth = 0,
                totalFlex = 0,
                flexHeight = 0,
                usedHeight = 0;

            Ext.each(cs, function(c){
                cm = c.margins;
                totalFlex += c.flex || 0;
                ch = c.getHeight();
                margin = cm.top + cm.bottom;
                extraHeight += ch + margin;
                flexHeight += margin + (c.flex ? 0 : ch);
                maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
            });
            extraHeight = h - extraHeight - this.padding.top - this.padding.bottom;

            var innerCtWidth = maxWidth + this.padding.left + this.padding.right;
            switch(this.align){
                case 'stretch':
                    this.innerCt.setSize(w, h);
                    break;
                case 'stretchmax':
                case 'left':
                    this.innerCt.setSize(innerCtWidth, h);
                    break;
                case 'center':
                    this.innerCt.setSize(w = Math.max(w, innerCtWidth), h);
                    break;
            }

            var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight),
                leftOver = availHeight,
                heights = [],
                restore = [],
                idx = 0,
                availableWidth = Math.max(0, w - this.padding.left - this.padding.right);

            Ext.each(cs, function(c){
                if(isStart && c.flex){
                    ch = Math.floor(availHeight * (c.flex / totalFlex));
                    leftOver -= ch;
                    heights.push(ch);
                }
            });

            if(this.pack == 'center'){
                t += extraHeight ? extraHeight / 2 : 0;
            }else if(this.pack == 'end'){
                t += extraHeight;
            }
            Ext.each(cs, function(c){
                cm = c.margins;
                t += cm.top;
                c.setPosition(l + cm.left, t);
                if(isStart && c.flex){
                    ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0));
                    if(isRestore){
                        restore.push(c.getWidth());
                    }
                    c.setSize(availableWidth, ch);
                }else{
                    ch = c.getHeight();
                }
                t += ch + cm.bottom;
            });

            idx = 0;
            Ext.each(cs, function(c){
                cm = c.margins;
                if(this.align == 'stretch'){
                    c.setWidth((stretchWidth - (cm.left + cm.right)).constrain(
                        c.minWidth || 0, c.maxWidth || 1000000));
                }else if(this.align == 'stretchmax'){
                    c.setWidth((maxWidth - (cm.left + cm.right)).constrain(
                        c.minWidth || 0, c.maxWidth || 1000000));
                }else{
                    if(this.align == 'center'){
                        var diff = availableWidth - (c.getWidth() + cm.left + cm.right);
                        if(diff > 0){
                            c.setPosition(l + cm.left + (diff/2), c.y);
                        }
                    }
                    if(isStart && c.flex){
                        c.setWidth(restore[idx++]);
                    }
                }
            }, this);
        }
        /**
         * @property activeItem
         * @hide
         */
    });

    Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;

    /**
     * @class Ext.layout.HBoxLayout
     * @extends Ext.layout.BoxLayout
     * A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal
     * space between child items containing a numeric flex configuration.
     * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option.
     */
    Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
        /**
         * @cfg {String} align
         * Controls how the child items of the container are aligned. Acceptable configuration values for this
         * property are:
         *
         * top : Defaultchild items are aligned vertically
         * at the left side of the container
         * middle : child items are aligned vertically at the
         * mid-height of the container
         * stretch : child items are stretched vertically to fill
         * the height of the container
         * stretchmax : child items are stretched vertically to
         * the size of the largest item.
         */
        align : 'top', // top, middle, stretch, strechmax
        /**
         * @cfg {String} pack
         * Controls how the child items of the container are packed together. Acceptable configuration values
         * for this property are:
         *
         * start : Defaultchild items are packed together at
         * left side of container
         * center : child items are packed together at
         * mid-width of container
         * end : child items are packed together at right
         * side of container
         *
         */
        /**
         * @cfg {Number} flex
         * This configuation option is to be applied to child items of the container managed
         * by this layout. Each child item with a flex property will be flexed horizontally
         * according to each item's relative flex value compared to the sum of all items with
         * a flex value specified.  Any child items that have either a flex = 0 or
         * flex = undefined will not be 'flexed' (the initial size will not be changed).
         */

        // private
        onLayout : function(ct, target){
            Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);

            var cs = this.getItems(ct), cm, cw, margin,
                size = this.getTargetSize(target),
                w = size.width - target.getPadding('lr') - this.scrollOffset,
                h = size.height - target.getPadding('tb'),
                l = this.padding.left, t = this.padding.top,
                isStart = this.pack == 'start',
                isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
                stretchHeight = h - (this.padding.top + this.padding.bottom),
                extraWidth = 0,
                maxHeight = 0,
                totalFlex = 0,
                flexWidth = 0,
                usedWidth = 0;

            Ext.each(cs, function(c){
                cm = c.margins;
                totalFlex += c.flex || 0;
                cw = c.getWidth();
                margin = cm.left + cm.right;
                extraWidth += cw + margin;
                flexWidth += margin + (c.flex ? 0 : cw);
                maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
            });
            extraWidth = w - extraWidth - this.padding.left - this.padding.right;

            var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
            switch(this.align){
                case 'stretch':
                    this.innerCt.setSize(w, h);
                    break;
                case 'stretchmax':
                case 'top':
                    this.innerCt.setSize(w, innerCtHeight);
                    break;
                case 'middle':
                    this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
                    break;
            }

            var availWidth = Math.max(0, w - this.padding.left - this.padding.right - flexWidth),
                leftOver = availWidth,
                widths = [],
                restore = [],
                idx = 0,
                availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom);

            Ext.each(cs, function(c){
                if(isStart && c.flex){
                    cw = Math.floor(availWidth * (c.flex / totalFlex));
                    leftOver -= cw;
                    widths.push(cw);
                }
            });

            if(this.pack == 'center'){
                l += extraWidth ? extraWidth / 2 : 0;
            }else if(this.pack == 'end'){
                l += extraWidth;
            }
            Ext.each(cs, function(c){
                cm = c.margins;
                l += cm.left;
                c.setPosition(l, t + cm.top);
                if(isStart && c.flex){
                    cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0));
                    if(isRestore){
                        restore.push(c.getHeight());
                    }
                    c.setSize(cw, availableHeight);
                }else{
                    cw = c.getWidth();
                }
                l += cw + cm.right;
            });

            idx = 0;
            Ext.each(cs, function(c){
                var cm = c.margins;
                if(this.align == 'stretch'){
                    c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain(
                        c.minHeight || 0, c.maxHeight || 1000000));
                }else if(this.align == 'stretchmax'){
                    c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
                        c.minHeight || 0, c.maxHeight || 1000000));
                }else{
                    if(this.align == 'middle'){
                        var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom);
                        if(diff > 0){
                            c.setPosition(c.x, t + cm.top + (diff/2));
                        }
                    }
                    if(isStart && c.flex){
                        c.setHeight(restore[idx++]);
                    }
                }
            }, this);
        }

        /**
         * @property activeItem
         * @hide
         */
    });

    Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;