////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.containers
{

import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextLineMetrics;
import flash.utils.getQualifiedClassName;
import mx.automation.IAutomationObject;
import mx.containers.utilityClasses.BoxLayout;
import mx.containers.utilityClasses.CanvasLayout;
import mx.containers.utilityClasses.ConstraintColumn;
import mx.containers.utilityClasses.ConstraintRow;
import mx.containers.utilityClasses.IConstraintLayout;
import mx.containers.utilityClasses.Layout;
import mx.controls.Button;
import mx.core.Container;
import mx.core.ContainerLayout;
import mx.core.EdgeMetrics;
import mx.core.EventPriority;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IFontContextComponent;
import mx.core.IUIComponent;
import mx.core.IUITextField;
import mx.core.UIComponent;
import mx.core.UIComponentCachePolicy;
import mx.core.UITextField;
import mx.core.UITextFormat;
import mx.core.mx_internal;
import mx.effects.EffectManager;
import mx.events.CloseEvent;
import mx.events.SandboxMouseEvent;
import mx.managers.ISystemManager;
import mx.styles.ISimpleStyleClient;
import mx.styles.IStyleClient;
import mx.styles.StyleProxy;

use namespace mx_internal;

//--------------------------------------
//  Styles
//--------------------------------------

include "../styles/metadata/AlignStyles.as";
include "../styles/metadata/GapStyles.as";
include "../styles/metadata/ModalTransparencyStyles.as";

/**
 *  Alpha of the title bar, control bar and sides of the Panel.
 *
 *  The default value for the Halo theme is <code>0.4</code>.
 *  The default value for the Spark theme is <code>0.5</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="borderAlpha", type="Number", inherit="no", theme="halo, spark")]

/**
 *  Thickness of the bottom border of the Panel control.
 *  If this style is not set and the Panel control contains a ControlBar
 *  control, the bottom border thickness equals the thickness of the top border
 *  of the panel; otherwise the bottom border thickness equals the thickness
 *  of the left border.
 *
 *  @default NaN
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="borderThicknessBottom", type="Number", format="Length", inherit="no", theme="halo")]

/**
 *  Thickness of the left border of the Panel.
 *
 *  @default 10
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="borderThicknessLeft", type="Number", format="Length", inherit="no", theme="halo")]

/**
 *  Thickness of the right border of the Panel.
 *
 *  @default 10
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="borderThicknessRight", type="Number", format="Length", inherit="no", theme="halo")]

/**
 *  Thickness of the top border of the Panel.
 *
 *  @default 2
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="borderThicknessTop", type="Number", format="Length", inherit="no", theme="halo")]

/**
 *  Name of the CSS style declaration that specifies styles to apply to 
 *  any control bar child subcontrol.
 * 
 *  @default null
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="controlBarStyleName", type="String", inherit="no")]

/**
 *  Radius of corners of the window frame.
 *
 *  The default value for the Halo theme is <code>4</code>.
 *  The default value for the Spark theme is <code>0</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="cornerRadius", type="Number", format="Length", inherit="no", theme="halo, spark")]

/**
 *  Boolean property that controls the visibility
 *  of the Panel container's drop shadow.
 *
 *  @default true
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dropShadowEnabled", type="Boolean", inherit="no", theme="halo")]

/**
 *  Array of two colors used to draw the footer
 *  (area for the ControlBar container) background. 
 *  The first color is the top color. 
 *  The second color is the bottom color.
 *  The default values are <code>null</code>, which
 *  makes the control bar background the same as
 *  the panel background.
 *
 *  @default null
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="footerColors", type="Array", arrayType="uint", format="Color", inherit="yes", theme="halo")]

/**
 *  Array of two colors used to draw the header.
 *  The first color is the top color.
 *  The second color is the bottom color.
 *  The default values are <code>null</code>, which
 *  makes the header background the same as the
 *  panel background.
 *
 *  @default null
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="headerColors", type="Array", arrayType="uint", format="Color", inherit="yes", theme="halo")]

/**
 *  Height of the header.
 *  The default value is based on the style of the title text.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="headerHeight", type="Number", format="Length", inherit="no")]

/**
 *  Alphas used for the highlight fill of the header.
 *
 *  @default [0.3,0]
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="highlightAlphas", type="Array", arrayType="Number", inherit="no", theme="halo")]

/**
 *  Number of pixels between the container's lower border
 *  and its content area.
 *
 *  @default 0
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the container's top border
 *  and its content area.
 *
 *  @default 0
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

/**
 *  Flag to enable rounding for the bottom two corners of the container.
 *  Does not affect the upper two corners, which are normally round. 
 *  To configure the upper corners to be square, 
 *  set <code>cornerRadius</code> to 0.
 *
 *  @default false
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="roundedBottomCorners", type="Boolean", inherit="no", theme="halo")]

/**
 *  Direction of drop shadow.
 *  Possible values are <code>"left"</code>, <code>"center"</code>,
 *  and <code>"right"</code>.
 *
 *  @default "center"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="shadowDirection", type="String", enumeration="left,center,right", inherit="no", theme="halo")]

/**
 *  Distance of drop shadow.
 *  Negative values move the shadow above the panel.
 *
 *  @default 2
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="shadowDistance", type="Number", format="Length", inherit="no", theme="halo")]

/**
 *  Style declaration name for the status in the title bar.
 *
 *  @default "windowStatus"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
 
[Style(name="statusStyleName", type="String", inherit="no")]

/**
 *  The title background skin.
 *
 *  The default value for the Halo theme is <code>mx.skins.halo.TitleBackground</code>.
 *  The default value for the Spark theme is <code>mx.core.UIComponent</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="titleBackgroundSkin", type="Class", inherit="no")]

/**
 *  Style declaration name for the text in the title bar.
 *  The default value is <code>"windowStyles"</code>,
 *  which causes the title to have boldface text.
 *
 *  @default "windowStyles"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="titleStyleName", type="String", inherit="no")]

//--------------------------------------
//  Effects
//--------------------------------------

/**
 *  Specifies the effect to play after a Resize effect finishes playing.
 *  To disable the default Dissolve effect, so that the children are hidden
 *  instantaneously, set the value of the
 *  <code>resizeEndEffect</code> property to <code>"none"</code>.  
 *
 *  @default "Dissolve"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Effect(name="resizeEndEffect", event="resizeEnd")]

/**
 *  Specifies the effect to play before a Resize effect begins playing.
 *  To disable the default Dissolve effect, so that the children are hidden
 *  instantaneously, set the value of the
 *  <code>resizeStartEffect</code> property to <code>"none"</code>.  
 *
 *  @default "Dissolve"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Effect(name="resizeStartEffect", event="resizeStart")]

//--------------------------------------
//  Excluded APIs
//--------------------------------------

[Exclude(name="focusIn", kind="event")]
[Exclude(name="focusOut", kind="event")]

[Exclude(name="focusBlendMode", kind="style")]
[Exclude(name="focusSkin", kind="style")]
[Exclude(name="focusThickness", kind="style")]

[Exclude(name="focusInEffect", kind="effect")]
[Exclude(name="focusOutEffect", kind="effect")]

//--------------------------------------
//  Other metadata
//--------------------------------------

[AccessibilityClass(implementation="mx.accessibility.PanelAccImpl")]

[IconFile("Panel.png")]

[Alternative(replacement="spark.components.Panel", since="4.0")]

/**
 *  A Halo Panel container consists of a title bar, a caption, a border,
 *  and a  content area for its children.
 *  Typically, you use Panel containers to wrap top-level application modules.
 *  For example, you could include a shopping cart in a Panel container.
 * 
 *  <p><b>Note:</b> Adobe recommends that, when possible, you use the 
 *  Spark Panel container instead of the Halo Panel container.</p>
 *
 *  <p>The Panel container has the following default sizing characteristics:</p>
 *     <table class="innertable">
 *        <tr>
 *           <th>Characteristic</th>
 *           <th>Description</th>
 *        </tr>
 *        <tr>
 *           <td>Default size</td>
 *           <td>Height is large enough to hold all of its children at the default height of the children, 
 *               plus any vertical gaps between the children, the top and bottom padding, the top and bottom borders, 
 *               and the title bar.<br/>
 *               Width is the larger of the default width of the widest child plus the left and right padding of the 
 *               container, or the width of the title text, plus the border.</td>
 *        </tr>
 *        <tr>
 *           <td>Padding</td>
 *           <td>4 pixels for the top, bottom, left, and right values.</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *  
 *  <p>The <code>&lt;mx:Panel&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *  
 *  <pre>
 *  &lt;mx:Panel
 *   <strong>Properties</strong>
 *   layout="vertical|horizontal|absolute"
 *   status=""
 *   title=""
 *   titleIcon="null"
 *  
 *   <strong>Styles</strong>
 *   borderAlpha="0.4"
 *   borderThicknessBottom="NaN"
 *   borderThicknessLeft="10"
 *   borderThicknessRight="10"
 *   borderThicknessTop="2"
 *   controlBarStyleName="null"
 *   cornerRadius="4"
 *   dropShadowEnabled="true|false"
 *   footerColors="null"
 *   headerColors="null"
 *   headerHeight="<i>Based on style of title</i>"
 *   highlightAlphas="[0.3,0]"
 *   horizontalAlign="left|center|right"
 *   horizontalGap="8"
 *   modalTransparency="0.5"
 *   modalTransparencyBlur="3"
 *   modalTransparencyColor="#DDDDDD"
 *   modalTransparencyDuration="100"
 *   paddingBottom="0"
 *   paddingTop="0"
 *   roundedBottomCorners="false|true"
 *   shadowDirection="center|left|right"
 *   shadowDistance="2"
 *   statusStyleName="windowStatus"
 *   titleBackgroundSkin="TitleBackground"
 *   titleStyleName="windowStyles"
 *   verticalAlign="top|middle|bottom"
 *   verticalGap="6"
 *  
 *   <strong>Effects</strong>
 *   resizeEndEffect="Dissolve"
 *   resizeStartEffect="Dissolve"
 *   &gt;
 *      ...
 *      <i>child tags</i>
 *      ...
 *  &lt;/mx:Panel&gt;
 *  </pre>
 *  
 *  @includeExample examples/SimplePanelExample.mxml
 *
 *  @see spark.components.Panel
 *  @see mx.containers.ControlBar
 *  @see mx.containers.VBox
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class Panel extends Container
    implements IConstraintLayout, IFontContextComponent
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     *  @private 
     */
    private static const HEADER_PADDING:Number = 14;

    //--------------------------------------------------------------------------
    //
    //  Class mixins
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Placeholder for mixin by PanelAccImpl.
     */
    mx_internal static var createAccessibilityImplementation:Function;

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function Panel()
    {
        super();

        // If the user hasn't explicitly set a resizeStartEffect
        // or resizeEndEffect for this Panel, then we want to use
        // the Dissolve effect (which is specified in the Panel's
        // style sheet). Unfortunately, there's no automated mechanism
        // to hook up the EffectManager, so I need to do that here.
        // Also see the comment in defaults.css.
        addEventListener("resizeStart", EffectManager.eventHandler,
                         false, EventPriority.EFFECT);
        addEventListener("resizeEnd", EffectManager.eventHandler,
                         false, EventPriority.EFFECT);

        layoutObject = new BoxLayout();
        layoutObject.target = this;
        
        showInAutomationHierarchy = true;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private var layoutObject:Layout;

    /**
     *  @private
     *  Is there a close button? Panel itself never has one,
     *  but its subclass TitleWindow can set this flag to true.
     */
    mx_internal var _showCloseButton:Boolean = false;

    /**
     *  @private
     *  A reference to this Panel container's title bar skin.
     *  This is a child of the titleBar.
     */
    mx_internal var titleBarBackground:IFlexDisplayObject;

    /**
     *  @private
     *  A reference to this Panel container's title icon.
     */
    mx_internal var titleIconObject:Object = null;

    /**
     *  @private
     *  A reference to this Panel container's close button, if any.
     *  This is a sibling of the titleBar, not its child.
     */
    mx_internal var closeButton:Button; 

    /**
     *  @private
     *  true until the component has finished initializing
     */
    private var initializing:Boolean = true;

    /**
     *  @private
     */
    private var panelViewMetrics:EdgeMetrics;

    /**
     *  @private
     *  Horizontal location where the user pressed the mouse button
     *  on the titlebar to start dragging, relative to the original
     *  horizontal location of the Panel.
     */
    private var regX:Number;
    
    /**
     *  @private
     *  Vertical location where the user pressed the mouse button
     *  on the titlebar to start dragging, relative to the original
     *  vertical location of the Panel.
     */
    private var regY:Number;

    /**
     *  @private
     */
    private var checkedForAutoSetRoundedCorners:Boolean;
    
    /** 
     *  @private
     */
    private var autoSetRoundedCorners:Boolean;

    /** 
     *  @private
     */
    private var inCreateComponentsFromDescriptors:Boolean;

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  baselinePosition
    //----------------------------------

    /**
     *  @private
     *  The baselinePosition of a Panel is calculated for its title.
     */
    override public function get baselinePosition():Number
    {
        if (!validateBaselinePosition())
            return NaN;

        return titleBar.y + titleTextField.y + titleTextField.baselinePosition;
    }

    //----------------------------------
    //  cacheAsBitmap
    //----------------------------------

    /**
     *  @private
     */
    override public function set cacheAsBitmap(value:Boolean):void
    {
        super.cacheAsBitmap = value;

        // If we got cached, create the content pane so the content area of
        // this panel gets cached with an opaque background.
        if (cacheAsBitmap && !contentPane
                && cachePolicy != UIComponentCachePolicy.OFF
                && getStyle("backgroundColor"))
        {
            createContentPane();
            invalidateDisplayList();
        }
    }

    //----------------------------------
    //  enabled
    //----------------------------------

    [Inspectable(category="General", enumeration="true,false", defaultValue="true")]

    /**
     *  @private
     */
    override public function set enabled(value:Boolean):void
    {
        super.enabled = value;

        if (titleTextField)
            titleTextField.enabled = value;

        if (statusTextField)
            statusTextField.enabled = value;
        
        if (controlBar)
            controlBar.enabled = value;
        
        if (closeButton)
            closeButton.enabled = value;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  _closeButtonStyleFilters
    //----------------------------------

   
    private static var _closeButtonStyleFilters:Object = 
    {
        "closeButtonUpSkin" : "closeButtonUpSkin", 
        "closeButtonOverSkin" : "closeButtonOverSkin",
        "closeButtonDownSkin" : "closeButtonDownSkin",
        "closeButtonDisabledSkin" : "closeButtonDisabledSkin",
        "closeButtonSkin" : "closeButtonSkin",
        "repeatDelay" : "repeatDelay",
        "repeatInterval" : "repeatInterval"
    };
    
    /**
     *  The set of styles to pass from the Panel to the close button.
     *  @see mx.styles.StyleProxy
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function get closeButtonStyleFilters():Object
    {
        return _closeButtonStyleFilters;
    }

    //----------------------------------
    //  constraintColumns
    //----------------------------------
    
    /**
     *  @private
     *  Storage for the constraintColumns property.
     */
    private var _constraintColumns:Array = [];

    [ArrayElementType("mx.containers.utilityClasses.ConstraintColumn")]
    [Inspectable(arrayType="mx.containers.utilityClasses.ConstraintColumn")]
    
    /**
     *  @copy mx.containers.utilityClasses.IConstraintLayout#constraintColumns
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get constraintColumns():Array
    {
        return _constraintColumns;
    }
    
    /**
     *  @private
     */
    public function set constraintColumns(value:Array):void
    {
        if (value != _constraintColumns)
        {
            var n:int = value.length;
            for (var i:int = 0; i < n; i++)
            {
                ConstraintColumn(value[i]).container = this;
            }
            _constraintColumns = value;

            invalidateSize();
            invalidateDisplayList();
        }
    }

    //----------------------------------
    //  constraintRows
    //----------------------------------
    
    /**
     *  @private
     *  Storage for the constraintRows property.
     */
    private var _constraintRows:Array = [];
    
    [ArrayElementType("mx.containers.utilityClasses.ConstraintRow")]
    [Inspectable(arrayType="mx.containers.utilityClasses.ConstraintRow")]
    
    /**
     *  @copy mx.containers.utilityClasses.IConstraintLayout#constraintRows
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get constraintRows():Array
    {
        return _constraintRows;
    }
    
    /**
     *  @private
     */
    public function set constraintRows(value:Array):void
    {
        if (value != _constraintRows)
        {
            var n:int = value.length;
            for (var i:int = 0; i < n; i++)
            {
                ConstraintRow(value[i]).container = this;
            }
            _constraintRows = value;

            invalidateSize();
            invalidateDisplayList();
        }
    }        
       
    //----------------------------------
    //  controlBar
    //----------------------------------

    /**
     *  A reference to this Panel container's control bar, if any.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var controlBar:IUIComponent;
    
    /**
     *  Proxy to the controlBar property which is protected and can't be accessed externally
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    mx_internal function get _controlBar():IUIComponent
    {
        return controlBar;
    }
        
    //----------------------------------
    //  fontContext
    //----------------------------------
    
    /**
     *  @inheritDoc 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get fontContext():IFlexModuleFactory
    {
        return moduleFactory;
    }

    /**
     *  @private
     */
    public function set fontContext(moduleFactory:IFlexModuleFactory):void
    {
        this.moduleFactory = moduleFactory;
    }
        
    //----------------------------------
    //  layout
    //----------------------------------

    /**
     *  @private
     *  Storage for the layout property.
     */
    private var _layout:String = ContainerLayout.VERTICAL;

    [Bindable("layoutChanged")]
    [Inspectable(category="General", enumeration="vertical,horizontal,absolute", defaultValue="vertical")]

    /**
     *  Specifies the layout mechanism used for this container. 
     *  Panel containers can use <code>"vertical"</code>, <code>"horizontal"</code>, 
     *  or <code>"absolute"</code> positioning. 
     *  Vertical positioning lays out the child components vertically from
     *  the top of the container to the bottom in the specified order.
     *  Horizontal positioning lays out the child components horizontally
     *  from the left of the container to the right in the specified order.
     *  Absolute positioning does no automatic layout and requires you to
     *  explicitly define the location of each child component. 
     *
     *  @default "vertical"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get layout():String
    {
        return _layout;
    }

    /**
     *  @private
     */
    public function set layout(value:String):void
    {
        if (_layout != value)
        {
            _layout = value;

            if (layoutObject)
                // Set target to null for cleanup.
                layoutObject.target = null;

            if (_layout == ContainerLayout.ABSOLUTE)
                layoutObject = new CanvasLayout();
            else
            {
                layoutObject = new BoxLayout();

                if (_layout == ContainerLayout.VERTICAL)
                    BoxLayout(layoutObject).direction
                        = BoxDirection.VERTICAL;
                else
                    BoxLayout(layoutObject).direction
                        = BoxDirection.HORIZONTAL;
            }

            if (layoutObject)
                layoutObject.target = this;

            invalidateSize();
            invalidateDisplayList();

            dispatchEvent(new Event("layoutChanged"));
        }
    }

    //----------------------------------
    //  status
    //----------------------------------

    /**
     *  @private
     *  Storage for the status property.
     */
    private var _status:String = "";
    
    /**
     *  @private
     */
    private var _statusChanged:Boolean = false;
    
    [Bindable("statusChanged")]
    [Inspectable(category="General", defaultValue="")]

    /**
     *  Text in the status area of the title bar.
     *
     *  @default ""
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get status():String
    {
        return _status;
    }

    /**
     *  @private
     */
    public function set status(value:String):void
    {
        _status = value;
        _statusChanged = true;
        
        invalidateProperties();
        
        dispatchEvent(new Event("statusChanged"));
    }
    
    //----------------------------------
    //  statusTextField
    //----------------------------------

    /**
     *  The UITextField sub-control that displays the status.
     *  The status field is a child of the <code>titleBar</code> sub-control.
     * 
     *  @see #titleBar
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var statusTextField:IUITextField;

    //----------------------------------
    //  title
    //----------------------------------

    /**
     *  @private
     *  Storage for the title property.
     */ 
    private var _title:String = "";
    
    /**
     *  @private
     */
    private var _titleChanged:Boolean = false;

    [Bindable("titleChanged")]
    [Inspectable(category="General", defaultValue="")]

    /**
     *  Title or caption displayed in the title bar.
     *
     *  @default ""
     *
     *  @tiptext Gets or sets the title/caption displayed in the title bar
     *  @helpid 3991
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get title():String
    {
        return _title;
    }

    /**
     *  @private
     */
    public function set title(value:String):void
    {
        _title = value;
        _titleChanged = true;
        
        invalidateProperties();
        invalidateSize();
        invalidateViewMetricsAndPadding();
        
        dispatchEvent(new Event("titleChanged"));
    }
    
    //----------------------------------
    //  titleBar
    //----------------------------------

    /**
     *  The TitleBar sub-control that displays the Panel container's title bar.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var titleBar:UIComponent;

    //----------------------------------
    //  titleIcon
    //----------------------------------

    /**
     *  @private
     *  Storage for the titleIcon property.
     */ 
    private var _titleIcon:Class;
    
    /**
     *  @private
     */
    private var _titleIconChanged:Boolean = false;

    [Bindable("titleIconChanged")]
    [Inspectable(category="General", defaultValue="", format="EmbeddedFile")]

    /**
     *  The icon displayed in the title bar.
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get titleIcon():Class
    {
        return _titleIcon;
    }

    /**
     *  @private
     */
    public function set titleIcon(value:Class):void
    {
        _titleIcon = value;
        _titleIconChanged = true;
        
        invalidateProperties();
        invalidateSize();
        
        dispatchEvent(new Event("titleIconChanged"));
    }

    //----------------------------------
    //  titleTextField
    //----------------------------------

    /**
     *  The UITextField sub-control that displays the title.
     *  The title field is a child of the <code>titleBar</code> sub-control.
     * 
     *  @see #titleBar
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var titleTextField:IUITextField;

    //----------------------------------
    //  usePadding
    //----------------------------------

    /**
     *  @private
     */
    override mx_internal function get usePadding():Boolean
    {
        // We use margins for all layouts except absolute.
        return layout != ContainerLayout.ABSOLUTE;
    }

    //----------------------------------
    //  viewMetrics
    //----------------------------------

    //--------------------------------------------------------------------------
    //
    //  Overridden methods: DisplayObjectContainer
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override public function getChildIndex(child:DisplayObject):int
    {
        // This override of getChildIndex() fixes a bug #116637.
        // The FocusManager incorrectly calls this function for the controlBar
        // with isContentAPI as true.  But it's really our fault, because we
        // first add the controlBar as a child (so it gets into the
        // FocusManager's list of focusable objects) and then abduct it.  This,
        // in combination with the contentPane, leads to a runtime error.
        // Simply returning numChildren (meaning "after last child") is
        // harmless and resolves the issue.
        if (controlBar && child == controlBar)
            return numChildren;
        else
            return super.getChildIndex(child);
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods: UIComponent
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function initializeAccessibility():void
    {
        if (Panel.createAccessibilityImplementation != null)
            Panel.createAccessibilityImplementation(this);
    }

    /**
     *  @private
     *  Create child objects.
     */
    override protected function createChildren():void
    {
        super.createChildren();

        // Create the title bar over the top of the floating border.
        if (!titleBar)
        {
            titleBar = new UIComponent();
            titleBar.visible = false;
        
            titleBar.addEventListener(MouseEvent.MOUSE_DOWN,
                                      titleBar_mouseDownHandler);

            rawChildren.addChild(titleBar);
        }

        // Create the titleBarBackground as a child of the titleBar.
        if (!titleBarBackground)
        {
            var titleBarBackgroundClass:Class =
                getStyle("titleBackgroundSkin");
            if (titleBarBackgroundClass)
            {
                titleBarBackground = new titleBarBackgroundClass();

                var backgroundUIComponent:IStyleClient =
                    titleBarBackground as IStyleClient;     
                if (backgroundUIComponent)
                {
                    backgroundUIComponent.setStyle("backgroundImage",
                                                   undefined);
                }

                var backgroundStyleable:ISimpleStyleClient =
                    titleBarBackground as ISimpleStyleClient;
                if (backgroundStyleable)
                    backgroundStyleable.styleName = this;

                titleBar.addChild(DisplayObject(titleBarBackground));
            }
        }

        createTitleTextField(-1);
        createStatusTextField(-1);
        
        // Create the closeButton as a child of the titleBar.
        if (!closeButton)
        {
            closeButton = new Button();
            closeButton.styleName = new StyleProxy(this, closeButtonStyleFilters);

            closeButton.upSkinName = "closeButtonUpSkin";
            closeButton.overSkinName = "closeButtonOverSkin";
            closeButton.downSkinName = "closeButtonDownSkin";
            closeButton.disabledSkinName = "closeButtonDisabledSkin";
            closeButton.skinName = "closeButtonSkin";
            closeButton.explicitWidth = closeButton.explicitHeight = 16;
            
            closeButton.focusEnabled = false;
            closeButton.visible = false;
            closeButton.enabled = enabled;
            
            closeButton.addEventListener(MouseEvent.CLICK,
                                          closeButton_clickHandler);

            // Add the close button on top of the title/status.
            titleBar.addChild(closeButton);
            closeButton.owner = this;
        }
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();

        if (hasFontContextChanged())
        {
            // Re-create the text fields in case the new font
            // is in a  different SWF then the current one.
            var childIndex:int;
            if (titleTextField)
            {
                childIndex = titleBar.getChildIndex(DisplayObject(titleTextField));
                removeTitleTextField();
                createTitleTextField(childIndex);
                
                _titleChanged = true;
            }
            
            if (statusTextField)
            {
                childIndex = titleBar.getChildIndex(DisplayObject(statusTextField));
                removeStatusTextField();
                createStatusTextField(childIndex);
                
                _statusChanged = true;
            }
        }
      
        if (_titleChanged)
        {
            _titleChanged = false;
            titleTextField.text = _title;
            
            // Don't call layoutChrome() if we  haven't initialized,
            // because it causes commit/measure/layout ordering problems
            // for children of the control bar.
            if (initialized)
                layoutChrome(unscaledWidth, unscaledHeight);
        }

        if (_titleIconChanged)
        {
            _titleIconChanged = false;

            if (titleIconObject)
            {
                titleBar.removeChild(DisplayObject(titleIconObject));
                titleIconObject = null;
            }

            if (_titleIcon)
            {
                titleIconObject = new _titleIcon();
                titleBar.addChild(DisplayObject(titleIconObject));
            }

            // Don't call layoutChrome() if we  haven't initialized,
            // because it causes commit/measure/layout ordering problems
            // for children of the control bar.
            if (initialized)
                layoutChrome(unscaledWidth, unscaledHeight);
        }
        
        if (_statusChanged)
        {
            _statusChanged = false;
            statusTextField.text = _status;
            
            // Don't call layoutChrome() if we  haven't initialized,
            // because it causes commit/measure/layout ordering problems
            // for children of the control bar.
            if (initialized)
                layoutChrome(unscaledWidth, unscaledHeight);
        }
    }
    
    /**
     *  Calculates the default mininum and maximum sizes
     *  of the Panel container.
     *  For more information
     *  about the <code>measure()</code> method, see the <code>
     *  UIComponent.measure()</code> method.
     *
     *  <p>The <code>measure()</code> method first calls
     *  <code>VBox.measure()</code> method, and then ensures that the
     *  <code>measuredWidth</code> and
     *  <code>measuredMinWidth</code> properties are wide enough
     *  to display the title and the ControlBar.</p>
     * 
     *  @see mx.core.UIComponent#measure()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    override protected function measure():void
    {
        super.measure();

        layoutObject.measure();

        var textSize:Rectangle = measureHeaderText();
        var textWidth:Number = textSize.width;
        var textHeight:Number = textSize.height;
        
        var bm:EdgeMetrics = EdgeMetrics.EMPTY;
        textWidth += bm.left + bm.right;    
        
        var offset:Number = 5;
        textWidth += offset * 2;

        if (titleIconObject)
            textWidth += titleIconObject.width;
        
        if (closeButton)
            textWidth += closeButton.getExplicitOrMeasuredWidth() + 6;

        measuredMinWidth = Math.max(textWidth, measuredMinWidth);
        measuredWidth = Math.max(textWidth, measuredWidth);
        
        if (controlBar && controlBar.includeInLayout)
        {
            var controlWidth:Number = controlBar.getExplicitOrMeasuredWidth() +
                                      bm.left + bm.right;
            
            measuredWidth =
                Math.max(measuredWidth, controlWidth);
        }
    }       
    
    /**
     *  @private
     *  Draw by making everything visible, then laying out.
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        layoutObject.updateDisplayList(unscaledWidth, unscaledHeight);

        if (border)
            border.visible = true;
        titleBar.visible = true;            
    }

    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        var allStyles:Boolean = !styleProp || styleProp == "styleName";
        
        super.styleChanged(styleProp);
        
        if (allStyles || styleProp == "titleStyleName")
        {
            if (titleTextField)
            {
                var titleStyleName:String = getStyle("titleStyleName");
                titleTextField.styleName = titleStyleName;
            }
        }
        
        if (allStyles || styleProp == "statusStyleName")
        {
            if (statusTextField)
            {
                var statusStyleName:String = getStyle("statusStyleName");
                statusTextField.styleName = statusStyleName;
            }
        }
        
        if (allStyles || styleProp == "controlBarStyleName")
        {
            if (controlBar && controlBar is ISimpleStyleClient)
            {
                var controlBarStyleName:String = getStyle("controlBarStyleName");
                ISimpleStyleClient(controlBar).styleName = controlBarStyleName;
            }
        }
        
        if (allStyles || styleProp == "titleBackgroundSkin")
        {
            if (titleBar)
            {
                var titleBackgroundSkinClass:Class =
                    getStyle("titleBackgroundSkin");
                
                if (titleBackgroundSkinClass)
                {
                    // Remove existing background
                    if (titleBarBackground)
                    {
                        titleBar.removeChild(DisplayObject(titleBarBackground));
                        titleBarBackground = null;
                    }
                    
                    titleBarBackground = new titleBackgroundSkinClass();

                    var backgroundUIComponent:IStyleClient =
                        titleBarBackground as IStyleClient;         
                    if (backgroundUIComponent)
                    {
                        backgroundUIComponent.setStyle("backgroundImage",
                                                       undefined);
                    }

                var backgroundStyleable:ISimpleStyleClient =
                    titleBarBackground as ISimpleStyleClient;
                if (backgroundStyleable)
                    backgroundStyleable.styleName = this;

                    titleBar.addChildAt(DisplayObject(titleBarBackground), 0);
                }
            }
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods: Container
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function layoutChrome(unscaledWidth:Number,
                                             unscaledHeight:Number):void
    {
        super.layoutChrome(unscaledWidth, unscaledHeight);
        
        // Special case for the default borderSkin to inset the chrome content
        // by the borderThickness when borderStyle is "solid", "inset" or "outset". 
        // We use getQualifiedClassName to avoid bringing in a dependency on 
        // mx.skins.halo.PanelSkin. 
        var em:EdgeMetrics = EdgeMetrics.EMPTY;
        var bt:Number = getStyle("borderThickness"); 
        if (getQualifiedClassName(border) == "mx.skins.halo::PanelSkin" &&
            getStyle("borderStyle") != "default" && bt) 
        {
            em = new EdgeMetrics(bt, bt, bt, bt);
        }
        
        // Remove the borderThickness from the border metrics,
        // since the header and control bar overlap any solid border.
        var bm:EdgeMetrics = em;      
        
        var x:Number = bm.left;
        var y:Number = bm.top;
        
        var headerHeight:Number = getHeaderHeight();
        if (headerHeight > 0 && height >= headerHeight)
        {
            var titleBarWidth:Number = unscaledWidth - bm.left - bm.right;
            
            showTitleBar(true);
            titleBar.mouseChildren = true;
            titleBar.mouseEnabled = true;
            
            // Draw an invisible rect in the tileBar. This ensures we
            // will get clicks, even if the background is transparent 
            // and there is no title.
            var g:Graphics = titleBar.graphics;
            g.clear();
            g.beginFill(0xFFFFFF, 0);
            g.drawRect(0, 0, titleBarWidth, headerHeight);
            g.endFill();
            
            // Also draw an invisible unfilled rect whose height
            // is the height of the entire Panel, not just the headerHeight.
            // This is for accessibility; the titlebar of the Panel
            // has an AccessibilityImplementation (see PanelAccImpl)
            // which makes it act like a grouping (ROLE_SYSTEM_GROUPING)
            // for the controls inside the panel.
            // Drawing this rect makes the accLocation rect of the grouping
            // enclose the controls inside the grouping,
            // even though it is a sibling of them, not their parent.
            // (This is because the Player doesn't support Sprites
            // with AccessibilityImplementations inside other Sprites
            // with AccessibilityImplementations; the accessible objects
            // in a Flash SWF are a flat list, not a hierarchy.)
            // This rectangle must be unfilled because the titleBar is
            // actually on top of the content area and would otherwise
            // block mouse events to the controls in the Panel.
            g.lineStyle(0, 0x000000, 0);
            g.drawRect(0, 0, titleBarWidth, unscaledHeight);
            
            // Position the titleBar.
            titleBar.move(x, y);
            titleBar.setActualSize(titleBarWidth, headerHeight);

            // Position the titleBarBackground within the titleBar.
            if (titleBarBackground)
            {
                titleBarBackground.move(0, 0);
                IFlexDisplayObject(titleBarBackground).setActualSize(
                    titleBarWidth, headerHeight);
            }

            // Set the close button next to the upper-right corner,
            // offset by the border thickness.
            closeButton.visible = _showCloseButton;
            if (_showCloseButton)
            {
                closeButton.setActualSize(
                    closeButton.getExplicitOrMeasuredWidth(),
                    closeButton.getExplicitOrMeasuredHeight());

                closeButton.move(
                    unscaledWidth - x - bm.right - 10 -
                    closeButton.getExplicitOrMeasuredWidth(),
                    (headerHeight -
                    closeButton.getExplicitOrMeasuredHeight()) / 2);
            }

            var leftOffset:Number = 10;
            var rightOffset:Number = 10;
            var h:Number;
            var offset:Number;

            // Set the position of the title icon.
            if (titleIconObject)
            {
                h = titleIconObject.height;
                offset = (headerHeight - h) / 2;
                titleIconObject.move(leftOffset, offset);
                leftOffset += titleIconObject.width + 4;
            }

            // Set the position of the title text. 
            h = titleTextField.getUITextFormat().measureText(titleTextField.text).height;
            offset = (headerHeight - h) / 2;

            var borderWidth:Number = bm.left + bm.right;            
            titleTextField.move(leftOffset, offset - 1);
            titleTextField.setActualSize(Math.max(0,
                                   unscaledWidth - leftOffset -
                                   rightOffset - borderWidth),
                                   h + UITextField.TEXT_HEIGHT_PADDING);

            // Set the position of the status text.
            h = statusTextField.text != "" ? statusTextField.getUITextFormat().measureText(statusTextField.text).height : 0;
            offset = (headerHeight - h) / 2;
            var statusX:Number = unscaledWidth - rightOffset - 4 -
                                 borderWidth - statusTextField.textWidth;
            if (_showCloseButton)
                statusX -= (closeButton.getExplicitOrMeasuredWidth() + 4);
            statusTextField.move(statusX, offset - 1);
            statusTextField.setActualSize(
                statusTextField.textWidth + 8,
                statusTextField.textHeight + UITextField.TEXT_HEIGHT_PADDING);

            // Make sure the status text isn't too long.
            // We do simple clipping here.
            var minX:Number = titleTextField.x + titleTextField.textWidth + 8;
            if (statusTextField.x < minX)
            {
                // Show as much as we can.
                statusTextField.width = Math.max(statusTextField.width -
                                        (minX - statusTextField.x), 0);
                statusTextField.x = minX;
            }
        }
        else
        {
            if (titleBar)
            {
                showTitleBar(false);                
                titleBar.mouseChildren = false;
                titleBar.mouseEnabled = false;
            }
        }
        
        if (controlBar)
        {
            var cx:Number = controlBar.x;
            var cy:Number = controlBar.y;
            var cw:Number = controlBar.width;
            var ch:Number = controlBar.height;

            controlBar.setActualSize(
                unscaledWidth - (bm.left + bm.right),
                controlBar.getExplicitOrMeasuredHeight());

            controlBar.move(
                bm.left,
                unscaledHeight - bm.bottom -
                controlBar.getExplicitOrMeasuredHeight());

            if (controlBar.includeInLayout)
                // Hide the control bar if it is spilling out.
                controlBar.visible = controlBar.y >= bm.top;

            // If the control bar's position or size changed, redraw.  This
            // fixes a refresh bug (when the control bar vacates some space,
            // the new space appears blank).
            if (cx != controlBar.x ||
                cy != controlBar.y ||
                cw != controlBar.width ||
                ch != controlBar.height)
            {
                invalidateDisplayList();
            }
        }
    }

    /**
     *  @private
     */
    override public function createComponentsFromDescriptors(
                                recurse:Boolean = true):void
    {
        inCreateComponentsFromDescriptors = true;
        super.createComponentsFromDescriptors();
        
        if (numChildren == 0)
        {
            setControlBar(null);
            inCreateComponentsFromDescriptors = false;
            return;
        }
        
        // If the last content child is a ControlBar, change it
        // from being a content child to a chrome child;
        // i.e., move it to the rawChildren collection.
        var lastChild:IUIComponent = IUIComponent(getChildAt(numChildren - 1));
        if (lastChild is ControlBar)
        {
            var oldChildDocument:Object = lastChild.document;
            
            if (contentPane)
            {
                contentPane.removeChild(DisplayObject(lastChild));
            }
            else
            {
                super.removeChild(DisplayObject(lastChild));
            }       
            // Restore the original document. Otherwise, when we re-add the child when the Panel is
            // a custom component, the child will use the custom component as the document instead of
            // using the document in which the child was declared.
            lastChild.document = oldChildDocument;
            rawChildren.addChild(DisplayObject(lastChild));
            setControlBar(lastChild);
        }
        else
        {
            setControlBar(null);
        }
        
        inCreateComponentsFromDescriptors = false;        
    }

    /**
     *  @private
     * 
     *  Container implements addChild in terms of addChildAt. 
     */
    override public function addChildAt(child:DisplayObject,
                                        index:int):DisplayObject
    {
        // Special case for adding the control bar.
        super.addChildAt(child, index);
        if (!inCreateComponentsFromDescriptors &&
            child is ControlBar)
            createComponentsFromDescriptors();
        
        return child;
    }
    
    /**
     *  @private
     * 
     *  Container implements removeChildAt in terms of removeChild.
     */
    override public function removeChild(child:DisplayObject):DisplayObject
    {
        // If the control bar is the last child.
        if (!inCreateComponentsFromDescriptors &&
            child is ControlBar && numChildren > 0 &&
            child == getChildAt(numChildren - 1))
        {
            rawChildren.removeChild(child);
            createComponentsFromDescriptors();
            return child;
        }
        
        return super.removeChild(child);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Creates the title text field child
     *  and adds it as a child of this component.
     * 
     *  @param childIndex The index of where to add the child.
     *  If -1, the text field is appended to the end of the list.
     */
    mx_internal function createTitleTextField(childIndex:int):void
    {
        // Create the titleTextField as a child of the titleBar.
        if (!titleTextField)
        {
            titleTextField = IUITextField(createInFontContext(UITextField));
            titleTextField.selectable = false;
    
            if (childIndex == -1)
                titleBar.addChild(DisplayObject(titleTextField));
            else 
                titleBar.addChildAt(DisplayObject(titleTextField), childIndex);

            var titleStyleName:String = getStyle("titleStyleName"); 
            titleTextField.styleName = titleStyleName;
            titleTextField.text = title;
            titleTextField.enabled = enabled;
        }
    }

    /**
     *  @private
     *  Removes the title text field from this component.
     */
    mx_internal function removeTitleTextField():void
    {
        if (titleBar && titleTextField)
        {
            titleBar.removeChild(DisplayObject(titleTextField));
            titleTextField = null;
        }
    }
    
    /**
     *  @private
     *  Creates the status text field child
     *  and adds it as a child of this component.
     * 
     *  @param childIndex The index of where to add the child.
     *  If -1, the text field is appended to the end of the list.
     */
    mx_internal function createStatusTextField(childIndex:int):void
    {
        // Create the statusTextField as a child of the titleBar.
        if (titleBar && !statusTextField)
        {
            statusTextField = IUITextField(createInFontContext(UITextField));
            statusTextField.selectable = false;
            
            if (childIndex == -1)
                titleBar.addChild(DisplayObject(statusTextField));                
            else 
                titleBar.addChildAt(DisplayObject(statusTextField), childIndex);

            var statusStyleName:String = getStyle("statusStyleName");
            statusTextField.styleName = statusStyleName;
            statusTextField.text = status;
            statusTextField.enabled = enabled;
        }
    }
    
    /**
     *  @private
     *  Removes the status text field from this component.
     */
    mx_internal function removeStatusTextField():void
    {
        if (titleBar && statusTextField)
        {
            titleBar.removeChild(DisplayObject(statusTextField));
            statusTextField = null;
        }
    }

    /**
     *  @private.
     *  Returns a Rectangle containing the largest piece of header
     *  text (can be either the title or status, whichever is bigger).
     */
    private function measureHeaderText(useDummyString:Boolean = false):Rectangle
    {
        var textWidth:Number = 20;
        var textHeight:Number = 14;

        var textFormat:UITextFormat;
        var metrics:TextLineMetrics;
        
        if (titleTextField && titleTextField.text)
        {
            titleTextField.validateNow();
            textFormat = titleTextField.getUITextFormat();
            metrics = textFormat.measureText(titleTextField.text, false);
            textWidth = metrics.width;
            textHeight = metrics.height;
        }
        else
        {
            if (useDummyString)
            {
                if (titleTextField)
                {
                    textFormat = titleTextField.getUITextFormat();
                    metrics = textFormat.measureText("Wj", false);
                    textWidth = metrics.width;
                    textHeight = metrics.height;
                }
            }
        }
        
        if (statusTextField && statusTextField.text)
        {
            statusTextField.validateNow();
            textFormat = statusTextField.getUITextFormat();
            metrics = textFormat.measureText(statusTextField.text, false);
            textWidth = Math.max(textWidth, metrics.width);
            textHeight = Math.max(textHeight, metrics.height);
        }

        return new Rectangle(0, 0, Math.round(textWidth), Math.round(textHeight));
    }
    
    /**
     *  Returns the height of the header.
     * 
     *  @return The height of the header, in pixels.     
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function getHeaderHeight():Number
    {
        var headerHeight:Number = getStyle("headerHeight");
        
        if (isNaN(headerHeight))
            headerHeight = measureHeaderText().height + HEADER_PADDING;
        
        return headerHeight;
    }
    
    /**
     *  @private
     *  Proxy to getHeaderHeight() for PanelSkin
     *  since we can't change its function signature
     */
    mx_internal function getHeaderHeightProxy(useDummyString:Boolean = false):Number
    {
        var headerHeight:Number = getStyle("headerHeight");
        
        if (isNaN(headerHeight))
            headerHeight = measureHeaderText(useDummyString).height + HEADER_PADDING;
        
        return headerHeight;
    }

    /**
     *  @private
     */
    private function showTitleBar(show:Boolean):void
    {
        titleBar.visible = show;
        
        var n:int = titleBar.numChildren;
        for (var i:int = 0; i < n; i++)
        {
            var child:DisplayObject = titleBar.getChildAt(i);
            child.visible = show;
        }               
    }   

    /**
     *  @private
     */
    private function setControlBar(newControlBar:IUIComponent):void
    {
        if (newControlBar == controlBar)
            return;
            
        controlBar = newControlBar;     
        
        // If roundedBottomCorners is set locally, don't auto-set
        // it when the controlbar is added/removed.
        if (!checkedForAutoSetRoundedCorners)
        {
            checkedForAutoSetRoundedCorners = true;
            autoSetRoundedCorners = styleDeclaration ? 
                    styleDeclaration.getStyle("roundedBottomCorners") === undefined : 
                    true;
        }
        
        if (autoSetRoundedCorners)
            setStyle("roundedBottomCorners", controlBar != null);

        var controlBarStyleName:String = getStyle("controlBarStyleName");
        
        if (controlBarStyleName && controlBar is ISimpleStyleClient)
            ISimpleStyleClient(controlBar).styleName = controlBarStyleName;
        
        if (controlBar)
            controlBar.enabled = enabled;
        if (controlBar is IAutomationObject)
            IAutomationObject(controlBar).showInAutomationHierarchy = false;

        invalidateViewMetricsAndPadding();
        invalidateSize();
        invalidateDisplayList();
    }
    
    /**
     *  Called when the user starts dragging a Panel
     *  that has been popped up by the PopUpManager.
     *
     *  @param event The MouseEvent dispatched when the 
     *  user clicks on the container.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function startDragging(event:MouseEvent):void
    {
        regX = event.stageX - x;
        regY = event.stageY - y;

        var sbRoot:DisplayObject = systemManager.getSandboxRoot();
        sbRoot.addEventListener(
            MouseEvent.MOUSE_MOVE, systemManager_mouseMoveHandler, true);

        sbRoot.addEventListener(
            MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true);

        sbRoot.addEventListener(
            SandboxMouseEvent.MOUSE_UP_SOMEWHERE, stage_mouseLeaveHandler);

        // add the mouse shield so we can drag over untrusted applications.
        systemManager.deployMouseShields(true);
    }

    /**
     *  Called when the user stops dragging a Panel
     *  that has been popped up by the PopUpManager.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function stopDragging():void
    {
        var sbRoot:DisplayObject = systemManager.getSandboxRoot();
        sbRoot.removeEventListener(
            MouseEvent.MOUSE_MOVE, systemManager_mouseMoveHandler, true);

        sbRoot.removeEventListener(
            MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true);

        sbRoot.removeEventListener(
            SandboxMouseEvent.MOUSE_UP_SOMEWHERE, stage_mouseLeaveHandler);

        regX = NaN;
        regY = NaN;

        systemManager.deployMouseShields(false);
    }

    /**
     *  @private
     *  Some other components which use a Panel as an internal
     *  subcomponent need access to the title bar,
     *  but can't access the titleBar var because it is protected
     *  and therefore available only to subclasses.
     */
    mx_internal function getTitleBar():UIComponent
    {
        return titleBar;
    }

    /**
     *  @private
     *  Some other components which use a Panel as an internal
     *  subcomponent need access to the UITextField that displays the title,
     *  but can't access the titleTextField var because it is protected
     *  and therefore available only to subclasses.
     */
    mx_internal function getTitleTextField():IUITextField
    {
        return titleTextField;
    }

    /**
     *  @private
     *  Some other components which use a Panel as an internal
     *  subcomponent need access to the UITextField that displays the status,
     *  but can't access the statusTextField var because it is protected
     *  and therefore available only to subclasses.
     */
    mx_internal function getStatusTextField():IUITextField
    {
        return statusTextField;
    }

    /**
     *  @private
     *  Some other components which use a Panel as an internal
     *  subcomponent need access to the control bar,
     *  but can't access the controlBar var because it is protected
     *  and therefore available only to subclasses.
     */
    mx_internal function getControlBar():IUIComponent
    {
        return controlBar;
    }

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private function titleBar_mouseDownHandler(event:MouseEvent):void
    {
        // A mouseDown on the closeButton will bubble up to the titleBar,
        // but it shouldn't start a drag; it should simply start the
        // normal mouse/Button interaction.
        if (event.target == closeButton)
            return;

        if (enabled && isPopUp && isNaN(regX))
            startDragging(event);
    }

    /**
     *  @private
     */
    private function systemManager_mouseMoveHandler(event:MouseEvent):void
    {
        // during a drag, only the Panel should get mouse move events
        // (e.g., prevent objects 'beneath' it from getting them -- see bug 187569)
        // we don't check the target since this is on the systemManager and the target
        // changes a lot -- but this listener only exists during a drag.
        event.stopImmediatePropagation();
        
        if (isNaN(regX) || isNaN(regY))
        {
            // trace("all the mouse moves were not turned off");
            return;
        }
        
        // trace("systemManager_mouseMoveHandler " + event);
        move(event.stageX - regX, event.stageY - regY);
    }

    /**
     *  @private
     */
    private function systemManager_mouseUpHandler(event:MouseEvent):void
    {
        // trace("systemManager_mouseUpHandler: " + event);
        if (!isNaN(regX))
            stopDragging();
    }

    /**
     *  @private
     */
    private function stage_mouseLeaveHandler(event:Event):void
    {
        // trace("stage_mouseLeaveHandler: " + event);
        if (!isNaN(regX))
            stopDragging();
    }

    /**
     *  @private
     */
    private function closeButton_clickHandler(event:MouseEvent):void
    {
        dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
    }
}

}
