    /**
     * Panel is a container that has specific functionality and structural components that make it the perfect building
     * block for application-oriented user interfaces.
     *
     * Panels are, by virtue of their inheritance from {@link Ext.Container}, capable of being configured with a {@link
     * Ext.Container#layout layout}, and containing child Components.
     *
     * When either specifying child {@link Ext.Container#cfg-items items} of a Panel, or dynamically {@link Ext.Container#method-add
     * adding} Components to a Panel, remember to consider how you wish the Panel to arrange those child elements, and
     * whether those child elements need to be sized using one of Ext's built-in `**{@link Ext.Container#layout layout}**`
     * schemes.
     *
     * ## Example:
     *
     *     @example preview
     *     var panel = Ext.create('Ext.Panel', {
     *         fullscreen: true,
     *
     *         items: [
     *             {
     *                 docked: 'top',
     *                 xtype: 'toolbar',
     *                 title: 'Standard Titlebar'
     *             },
     *             {
     *                 docked: 'top',
     *                 xtype: 'toolbar',
     *                 ui   : 'light',
     *                 items: [
     *                     {
     *                         text: 'Test Button'
     *                     }
     *                 ]
     *             }
     *         ],
     *
     *         html: 'Testing'
     *     });
     *
     */
    Ext.define('Ext.Panel', {
        extend: 'Ext.Container',
        requires: ['Ext.util.LineSegment'],

        alternateClassName: 'Ext.lib.Panel',

        xtype: 'panel',

        isPanel: true,

        config: {
            baseCls: Ext.baseCSSPrefix + 'panel',

            /**
             * @cfg {Number/Boolean/String} bodyPadding
             * A shortcut for setting a padding style on the body element. The value can either be
             * a number to be applied to all sides, or a normal css string describing padding.
             * @deprecated 2.0 bodyPadding is deprecated and will be removed in a future version of Sencha Touch.
             */
            bodyPadding: null,

            /**
             * @cfg {Number/Boolean/String} bodyMargin
             * A shortcut for setting a margin style on the body element. The value can either be
             * a number to be applied to all sides, or a normal css string describing margins.
             * @deprecated 2.0 bodyMargin is deprecated and will be removed in a future version of Sencha Touch.
             */
            bodyMargin: null,

            /**
             * @cfg {Number/Boolean/String} bodyBorder
             * A shortcut for setting a border style on the body element. The value can either be
             * a number to be applied to all sides, or a normal css string describing borders.
             * @deprecated 2.0 bodyBorder is deprecated and will be removed in a future version of Sencha Touch.
             */
            bodyBorder: null
        },

        getElementConfig: function() {
            var config = this.callParent();

            config.children.push({
                reference: 'tipElement',
                className: 'x-anchor',
                hidden: true
            });

            return config;
        },

        applyBodyPadding: function(bodyPadding) {
            if (bodyPadding === true) {
                bodyPadding = 5;
            }

            bodyPadding = Ext.dom.Element.unitizeBox(bodyPadding);

            return bodyPadding;
        },

        updateBodyPadding: function(newBodyPadding) {
            this.element.setStyle('padding', newBodyPadding);
        },

        applyBodyMargin: function(bodyMargin) {
            if (bodyMargin === true) {
                bodyMargin = 5;
            }

            bodyMargin = Ext.dom.Element.unitizeBox(bodyMargin);

            return bodyMargin;
        },

        updateBodyMargin: function(newBodyMargin) {
            this.element.setStyle('margin', newBodyMargin);
        },

        applyBodyBorder: function(bodyBorder) {
            if (bodyBorder === true) {
                bodyBorder = 1;
            }

            bodyBorder = Ext.dom.Element.unitizeBox(bodyBorder);

            return bodyBorder;
        },

        updateBodyBorder: function(newBodyBorder) {
            this.element.setStyle('border-width', newBodyBorder);
        },

        alignTo: function(component) {
            var tipElement = this.tipElement;

            tipElement.hide();

            if (this.currentTipPosition) {
                tipElement.removeCls('x-anchor-' + this.currentTipPosition);
            }

            this.callParent(arguments);

            var LineSegment = Ext.util.LineSegment,
                alignToElement = component.isComponent ? component.renderElement : component,
                element = this.renderElement,
                alignToBox = alignToElement.getPageBox(),
                box = element.getPageBox(),
                left = box.left,
                top = box.top,
                right = box.right,
                bottom = box.bottom,
                centerX = left + (box.width / 2),
                centerY = top + (box.height / 2),
                leftTopPoint = { x: left, y: top },
                rightTopPoint = { x: right, y: top },
                leftBottomPoint = { x: left, y: bottom },
                rightBottomPoint = { x: right, y: bottom },
                boxCenterPoint = { x: centerX, y: centerY },
                alignToCenterX = alignToBox.left + (alignToBox.width / 2),
                alignToCenterY = alignToBox.top + (alignToBox.height / 2),
                alignToBoxCenterPoint = { x: alignToCenterX, y: alignToCenterY },
                centerLineSegment = new LineSegment(boxCenterPoint, alignToBoxCenterPoint),
                offsetLeft = 0,
                offsetTop = 0,
                tipSize, tipWidth, tipHeight, tipPosition, tipX, tipY;

            tipElement.setVisibility(false);
            tipElement.show();
            tipSize = tipElement.getSize();
            tipWidth = tipSize.width;
            tipHeight = tipSize.height;

            if (centerLineSegment.intersects(new LineSegment(leftTopPoint, rightTopPoint))) {
                tipX = Math.min(Math.max(alignToCenterX, left), right - (tipWidth / 2));
                tipY = top;
                offsetTop = tipHeight;
                tipPosition = 'top';
            }
            else if (centerLineSegment.intersects(new LineSegment(leftTopPoint, leftBottomPoint))) {
                tipX = left;
                tipY = Math.min(Math.max(alignToCenterY + (tipWidth / 2), top), bottom);
                offsetLeft = tipHeight;
                tipPosition = 'left';
            }
            else if (centerLineSegment.intersects(new LineSegment(leftBottomPoint, rightBottomPoint))) {
                tipX = Math.min(Math.max(alignToCenterX, left), right - (tipWidth / 2));
                tipY = bottom;
                offsetTop = -tipHeight;
                tipPosition = 'bottom';
            }
            else if (centerLineSegment.intersects(new LineSegment(rightTopPoint, rightBottomPoint))) {
                tipX = right;
                tipY = Math.min(Math.max(alignToCenterY - (tipWidth / 2), top), bottom);
                offsetLeft = -tipHeight;
                tipPosition = 'right';
            }

            if (tipX || tipY) {
                this.currentTipPosition = tipPosition;
                tipElement.addCls('x-anchor-' + tipPosition);
                tipElement.setLeft(tipX - left);
                tipElement.setTop(tipY - top);
                tipElement.setVisibility(true);

                this.setLeft(this.getLeft() + offsetLeft);
                this.setTop(this.getTop() + offsetTop);
            }
        }
    });