////////////////////////////////////////////////////////////////////////////////
//
//  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 spark.components
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

import mx.core.DPIClassification;
import mx.core.FlexGlobals;
import mx.core.ILayoutElement;
import mx.core.IVisualElement;
import mx.core.LayoutDirection;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.ResizeEvent;
import mx.managers.SystemManager;
import mx.utils.MatrixUtil;
import mx.utils.PopUpUtil;

use namespace mx_internal;

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

/**
 *  Appearance of the <code>contentGroup</code>. 
 *  Valid MXML values are <code>inset</code>, 
 *  <code>flat</code>, and <code>none</code>.
 *
 *  <p>In ActionScript, you can use the following constants
 *  to set this property:
 *  <code>ContentBackgroundAppearance.INSET</code>,
 *  <code>ContentBackgroundAppearance.FLAT</code> and
 *  <code>ContentBackgroundAppearance.NONE</code>.</p>
 *
 *  @default ContentBackgroundAppearance.INSET
 *  
 *  @langversion 3.0
 *  @playerversion Flash 11
 *  @playerversion AIR 3
 *  @productversion Flex 4.6
 */ 
[Style(name="contentBackgroundAppearance", type="String", enumeration="inset,flat,none", inherit="no")]

/**
 *  Color  of the frame border  and arrow outline  of the Callout control.
 *  @default 0
 *
 *  @langversion 3.0
 *  @playerversion Flash 11
 *  @playerversion AIR 3.8
 *  @productversion Flex 4.11
 */

[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark, mobile")]

/**
 *   Thickness of the border stroke around the <code>backgroundColor</code> Callout "frame" and arrow.
 *  Set to NaN or 0 to hide the border ;
 *
 *  @default NaN
 *
 *  @langversion 3.0
 *  @playerversion Flash 11
 *  @playerversion AIR 3.8
 *  @productversion Flex 4.11
 */
[Style(name="borderThickness", type="Number", format="Length", inherit="no", theme="spark,mobile")]

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

[IconFile("Callout.png")]

/**
 *  The Callout container is a SkinnablePopUpContainer that functions as a pop-up
 *  with additional owner-relative positioning options similar to PopUpAnchor.
 *  Callout also adds an optional <code>arrow</code> skin part that visually
 *  displays the direction toward the owner.
 *
 *
 *  <p>You can also use the CalloutButton control to open a callout container. 
 *  The CalloutButton control encapsulates in a single control the callout container 
 *  and all of the logic necessary to open and close the callout. 
 *  The CalloutButton control is then said to the be the owner, or host, 
 *  of the callout.</p>
 *
 *  <p>Callout uses the <code>horizontalPosition</code> and
 *  <code>verticalPosition</code> properties to determine the position of the
 *  Callout relative to the owner that is specified by the <code>open()</code>
 *  method. 
 *  Both properties can be set to <code>CalloutPosition.AUTO</code> which selects a
 *  position based on the aspect ratio of the screen for the Callout to fit
 *  with minimal overlap with the owner and and minimal adjustments at the
 *  screen bounds.</p>
 *
 *  <p>Once positioned, the Callout positions the arrow on the side adjacent
 *  to the owner, centered as close as possible on the horizontal or vertical
 *  center of the owner as appropriate. The arrow is hidden in cases where
 *  the Callout position is not adjacent to any edge.</p>
 *
 *  <p>You do not create a Callout container as part of the normal layout
 *  of its parent container.
 *  Instead, it appears as a pop-up container on top of its parent.
 *  Therefore, you do not create it directly in the MXML code of your application.</p>
 *
 *  <p>Instead, you create is as an MXML component, often in a separate MXML file.
 *  To show the component create an instance of the MXML component, and
 *  then call the <code>open()</code> method.
 *  You can also set the size and position of the component when you open it.</p>
 *
 *  <p>To close the component, call the <code>close()</code> method.
 *  If the pop-up needs to return data to a handler, you can add an event listener for
 *  the <code>PopUp.CLOSE</code> event, and specify the returned data in
 *  the <code>close()</code> method.</p>
 *
 *  <p>The Callout is initially in its <code>closed</code> skin state.
 *  When it opens, it adds itself as a pop-up to the PopUpManager,
 *  and transition to the <code>normal</code> skin state.
 *  To define open and close animations, use a custom skin with transitions between
 *  the <code>closed</code> and <code>normal</code> skin states.</p>
 * 
 *  <p>Callout changes the default inheritance behavior seen in Flex components 
 *  and instead, inherits styles from the top-level application. This prevents
 *  Callout's contents from unintentionally inheriting styles from an owner
 *  (i.e. Button or TextInput) where the default appearance was desired and
 *  expected.</p>
 *
 *  <p>The Callout container has the following default characteristics:</p>
 *     <table class="innertable">
 *     <tr><th>Characteristic</th><th>Description</th></tr>
 *     <tr><td>Default size</td><td>Large enough to display its children</td></tr>
 *     <tr><td>Minimum size</td><td>0 pixels</td></tr>
 *     <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr>
 *     <tr><td>Default skin class</td>
 *     <td>spark.skins.mobile.CalloutSkin<br/>
 *           spark.skins.spark.CalloutSkin on desktops</td></tr>
 *     </table>
 *
 *  @mxml <p>The <code>&lt;s:Callout&gt;</code> tag inherits all of the tag
 *  attributes of its superclass and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:Callout
 *    <strong>Properties</strong>
 *    horizontalPosition="auto"
 *    verticalPosition="auto"
 *
 *    <strong>Styles</strong>
 *    contentBackgroundAppearance="inset"
 *  /&gt;
 *  </pre>
 *
 *  @see spark.components.CalloutButton
 *  @see spark.skins.mobile.CalloutSkin
 *  @see spark.components.ContentBackgroundAppearance
 *  @see spark.components.CalloutPosition
 *
 *  @includeExample examples/CalloutExample.mxml -noswf
 *
 *  @langversion 3.0
 *  @playerversion Flash 11
 *  *  @playerversion AIR 3
 *  @productversion Flex 4.6
 */
public class Callout extends SkinnablePopUpContainer
{

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

    private static var decomposition:Vector.<Number> = new <Number>[0,0,0,0,0];

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

    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function Callout()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //--------------------------------------------------------------------------

    [Bindable]
    [SkinPart(required="false")]

    /**
     *  An optional skin part that visually connects the owner to the
     *  contentGroup.
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public var arrow:UIComponent;
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    private var invalidatePositionFlag:Boolean = false;

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

    //----------------------------------
    //  horizontalPosition
    //----------------------------------

    private var _horizontalPosition:String = CalloutPosition.AUTO;

    [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]

    /**
     *  Horizontal position of the callout relative to the owner.
     *
     *  <p>Possible values are <code>"before"</code>, <code>"start"</code>,
     *  <code>"middle"</code>, <code>"end"</code>, <code>"after"</code>,
     *  and <code>"auto"</code> (default).</p>
     *
     *  @default CalloutPosition.AUTO
     *  @see spark.components.CalloutPosition
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function get horizontalPosition():String
    {
        return _horizontalPosition;
    }

    /**
     *  @private
     */
    public function set horizontalPosition(value:String):void
    {
        if (value == _horizontalPosition)
            return;

        _horizontalPosition = value;

        invalidatePosition();
    }

    //----------------------------------
    //  actualHorizontalPosition
    //----------------------------------

    private var _actualHorizontalPosition:String;

    /**
     *  Fully resolved horizontal position after evaluating CalloutPosition.AUTO.
     * 
     *  <p>Update this property in <code>commitProperties()</code> when the
     *  explicit <code>horizontalPosition</code> is CalloutPosition.AUTO. 
     *  This property must be updated in <code>updatePopUpPosition()</code>
     *  when attempting to reposition the Callout.</p> 
     *  
     *  <p>Subclasses should read this property when computing the <code>arrowDirection</code>,
     *  the arrow position in <code>updateSkinDisplayList()</code>.</p>
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    mx_internal function get actualHorizontalPosition():String
    {
        if (_actualHorizontalPosition)
            return _actualHorizontalPosition;

        return horizontalPosition;
    }

    /**
     *  @private
     */
    mx_internal function set actualHorizontalPosition(value:String):void
    {
        _actualHorizontalPosition = value;
    }

    //----------------------------------
    //  verticalPosition
    //----------------------------------

    private var _verticalPosition:String = CalloutPosition.AUTO;

    [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]

    /**
     *  Vertical position of the callout relative to the owner.
     *
     *  <p>Possible values are <code>"before"</code>, <code>"start"</code>,
     *  <code>"middle"</code>, <code>"end"</code>, <code>"after"</code>,
     *  and <code>"auto"</code> (default).</p>
     *
     *  @default CalloutPosition.AUTO
     *  @see spark.components.CalloutPosition
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function get verticalPosition():String
    {
        return _verticalPosition;
    }

    /**
     *  @private
     */
    public function set verticalPosition(value:String):void
    {
        if (value == _verticalPosition)
            return;

        _verticalPosition = value;

        invalidatePosition();
    }

    //----------------------------------
    //  actualVerticalPosition
    //----------------------------------

    private var _actualVerticalPosition:String;
    
    /**
     *  Fully resolved vertical position after evaluating CalloutPosition.AUTO.
     * 
     *  <p>Update this property in <code>commitProperties()</code> when the
     *  explicit <code>verticalPosition</code> is CalloutPosition.AUTO. 
     *  This property must be updated in <code>updatePopUpPosition()</code>
     *  when attempting to reposition the Callout.</p> 
     *  
     *  <p>Subclasses should read this property when computing the <code>arrowDirection</code>,
     *  the arrow position in <code>updateSkinDisplayList()</code>.</p>
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    mx_internal function get actualVerticalPosition():String
    {
        if (_actualVerticalPosition)
            return _actualVerticalPosition;

        return verticalPosition;
    }

    /**
     *  @private
     */
    mx_internal function set actualVerticalPosition(value:String):void
    {
        _actualVerticalPosition = value;
    }

    //----------------------------------
    //  arrowDirection
    //----------------------------------

    private var _arrowDirection:String = ArrowDirection.NONE;
    
    /**
     *  @private
     *  Indicates if arrow direction was flipped automatically.
     */
    private var arrowDirectionAdjusted:Boolean = false;

    /**
     *  A read-only property that indicates the direction from the callout
     *  towards the owner.
     *
     *  <p>This value is computed based on the callout position given by
     *  <code>horizontalPosition</code> and <code>verticalPosition</code>.
     *  Exterior and interior positions will point from the callout towards
     *  the edge of the owner. Corner and absolute center positions are not
     *  supported and will return a value of <code>"none".</code></p>
     * 
     *  @default none
     *
     *  @see spark.components.ArrowDirection
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function get arrowDirection():String
    {
        return _arrowDirection;
    }
    
    /**
     *  @private
     *  Invalidate skin when the arrowDirection changes. Dispatches an 
     *  "arrowDirectionChanged" event when the property is set.
     */
    mx_internal function setArrowDirection(value:String):void
    {
        if (_arrowDirection == value)
            return;
        
        _arrowDirection = value;
        
        // Instead of using skin states for each arrowDirection, the
        // skin must override commitProperties() and account for
        // arrowDirection on it's own.
        skin.invalidateProperties();
        
        // adjust margins based on arrow direction
        switch (arrowDirection)
        {
            case ArrowDirection.DOWN:
            {
                // Set the marginBottom to zero to place the arrow adjacent to the keyboard
                softKeyboardEffectMarginBottom = 0;
                softKeyboardEffectMarginTop = margin;
                break;
            }
            case ArrowDirection.UP:
            {
                // Arrow should already be adjacent to the owner or the top of
                // the screen.
                softKeyboardEffectMarginTop = 0;
                softKeyboardEffectMarginBottom = margin;
                break;
            }
            default:
            {
                softKeyboardEffectMarginBottom = margin;
                softKeyboardEffectMarginTop = margin;
                break;
            }
        }
        
        if (hasEventListener("arrowDirectionChanged"))
            dispatchEvent(new Event("arrowDirectionChanged"));
    }
    
    //----------------------------------
    //  margin
    //----------------------------------
    
    private var _margin:Number = NaN;
    
    /**
     *  @private
     *  Defines a margin around the Callout to nudge it's position away from the
     *  edge of the screen.
     */
    mx_internal function get margin():Number
    {
        if (isNaN(_margin))
        {
            var dpi:Number = FlexGlobals.topLevelApplication["applicationDPI"];
            
            if (dpi)
            {
                switch (dpi)
                {
					case DPIClassification.DPI_640:
					{
						_margin = 32;
						break;
					}
					case DPIClassification.DPI_480:
					{
						_margin = 24;
						break;
					}
                    case DPIClassification.DPI_320:
                    {
                        _margin = 16;
                        break;
                    }
					case DPIClassification.DPI_240:
					{
						_margin = 12;
						break;
					}
					case DPIClassification.DPI_120:
					{
						_margin = 6;
						break;
					}
                    default:
                    {
                        // default DPI_160
                        _margin = 8;
                        break;
                    }
                }
            }
            else
            {
                _margin = 8;
            }
        }
        
        return _margin;
    }
    
    private var _explicitMoveForSoftKeyboard:Boolean = false;
    
    /**
     *  @private
     */
    override public function get moveForSoftKeyboard():Boolean
    {
        // If no explicit setting, then automatically disable move when
        // pointing up towards the owner.
        if (!_explicitMoveForSoftKeyboard && 
            (arrowDirection == ArrowDirection.UP))
        {
            return false;
        }
        
        return super.moveForSoftKeyboard;
    }
    
    /**
     *  @private
     */
    override public function set moveForSoftKeyboard(value:Boolean):void
    {
        super.moveForSoftKeyboard = value;
        
        _explicitMoveForSoftKeyboard = true;
    }
    
    //----------------------------------
    //  calloutMaxWidth
    //----------------------------------
    
    private var _calloutMaxWidth:Number = NaN;
    
    /**
     *  @private
     */
    mx_internal function get calloutMaxWidth():Number
    {
        return _calloutMaxWidth;
    }
    
    /**
     *  @private
     */
    mx_internal function set calloutMaxWidth(value:Number):void
    {
        if (_calloutMaxWidth == value)
            return;
        
        _calloutMaxWidth = value;
        
        invalidateMaxSize();
    }

    
    //----------------------------------
    //  calloutMaxHeight
    //----------------------------------
    
    private var _calloutMaxHeight:Number = NaN;
    
    /**
     *  @private
     */
    mx_internal function get calloutMaxHeight():Number
    {
        return _calloutMaxHeight;
    }
    
    /**
     *  @private
     */
    mx_internal function set calloutMaxHeight(value:Number):void
    {
        if (_calloutMaxHeight == value)
            return;
        
        _calloutMaxHeight = value;
        
        invalidateMaxSize();
    }


    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override public function get explicitMaxWidth():Number
    {
        if (!isNaN(super.explicitMaxWidth))
            return super.explicitMaxWidth;
        
        return calloutMaxWidth;
    }
    
    /**
     *  @private
     */
    override public function get explicitMaxHeight():Number
    {
        if (!isNaN(super.explicitMaxHeight))
            return super.explicitMaxHeight;
        
        return calloutMaxHeight;
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        // Do not commit position changes if closed (no owner) or owner was 
        // removed from the display list.
        if (!owner || !owner.parent)
            return;
        
        // Compute actual positions when using AUTO
        commitAutoPosition();
        
        // Compute max size based on actual positions
        commitMaxSize();
        
        if (arrow)
        {
            // arrowDirection can be set in 2 ways: (1) horizontalPostion/verticalPosition
            // changes and (2) flipping the axis to fit on screen. 
            if (!arrowDirectionAdjusted)
            {
                // Invalidate only when the arrow direction changes
                var direction:String = determineArrowPosition(actualHorizontalPosition,
                    actualVerticalPosition);
                
                if (arrowDirection != direction)
                {
                    setArrowDirection(direction);
                    
                    if (arrow)
                        arrow.visible = (arrowDirection != ArrowDirection.NONE);
                }
            }
            
            // Always reset the arrow position
            invalidateDisplayList();
        }
    }

    /**
     *  @private
     *  Re-position the pop-up using actualHorizontalPosition and
     *  actualVerticalPosition. 
     */
    override public function updatePopUpPosition():void
    {
        if (!owner || !systemManager)
            return;
        
        var popUpPoint:Point = calculatePopUpPosition();
        var ownerComponent:UIComponent = owner as UIComponent;
        var concatenatedColorTransform:ColorTransform = 
            (ownerComponent) ? ownerComponent.$transform.concatenatedColorTransform : null;
        
        PopUpUtil.applyPopUpTransform(owner, concatenatedColorTransform,
                                      systemManager, this, popUpPoint);
    }

    /**
     *  @private
     *
     *  Cooperative layout
     *  @see spark.components.supportClasses.TrackBase#partAdded
     */
    override protected function partAdded(partName:String, instance:Object):void
    {
        super.partAdded(partName, instance);

        if (instance == arrow)
            arrow.addEventListener(ResizeEvent.RESIZE, arrow_resizeHandler);
    }

    /**
     *  @private
     */
    override protected function partRemoved(partName:String, instance:Object):void
    {
        super.partRemoved(partName, instance);

        if (instance == arrow)
            arrow.removeEventListener(ResizeEvent.RESIZE, arrow_resizeHandler);
    }

    /**
     *  @private
     */
    override public function open(owner:DisplayObjectContainer, modal:Boolean=false):void
    {
        if (isOpen)
            return;
        
        // reset state
        invalidatePositionFlag = false;
        arrowDirectionAdjusted = false;

        // Add to PopUpManager, calls updatePopUpPosition(), and change state
        super.open(owner, modal);
        
        // Reposition the callout when the screen changes
        var systemManagerParent:SystemManager = this.parent as SystemManager;
        
        if (systemManagerParent)
            systemManagerParent.addEventListener(Event.RESIZE, systemManager_resizeHandler);
    }
    
    /**
     *  @private
     */
    override public function close(commit:Boolean=false, data:*=null):void
    {
        if (!isOpen)
            return;
        
        var systemManagerParent:SystemManager = this.parent as SystemManager;
        
        if (systemManagerParent)
            systemManagerParent.removeEventListener(Event.RESIZE, systemManager_resizeHandler);
        
        super.close(commit, data);
    }
    
    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        
        // Callout can be respositioned while open via SystemManager resize or
        // explicit changes to horizontalPostion and verticalPosition.
        if (isOpen && invalidatePositionFlag)
        {
            updatePopUpPosition();
            invalidatePositionFlag = false;
        }

        // Position the arrow
        updateSkinDisplayList();
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private function invalidatePosition():void
    {
        arrowDirectionAdjusted = false;
        
        invalidateProperties();
        
        if (isOpen)
            invalidatePositionFlag = true;
    }
    
    /**
     *  @private
     *  Force a new measurement when callout should use it's screen-constrained
     *  max size.
     */
    private function invalidateMaxSize():void
    {
        // calloutMaxWidth and calloutMaxHeight don't invalidate 
        // explicitMaxWidth or explicitMaxHeight. If callout's max size changes
        // and explicit max sizes aren't set, then invalidate size here so that
        // callout's max size is applied.
        if (!canSkipMeasurement() && !isMaxSizeSet)
            skin.invalidateSize();
    }

    /**
     *  Sets the bounds of <code>arrow</code>, whose geometry isn't fully
     *  specified by the skin's layout.
     *
     *  <p>Subclasses can override this method to update the arrow's size,
     *  position, and visibility, based on the computed
     *  <code>arrowDirection</code>.</p>
     *
     *  <p>By default, this method aligns the arrow on the shorter of either
     *  the <code>arrow</code> bounds or the <code>owner</code> bounds. This
     *  implementation assumes that the <code>arrow</code> and the Callout skin
     *  share the same coordinate space.</p>
     *
     *  @langversion 3.0
     *  @playerversion Flash 11
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected function updateSkinDisplayList():void
    {
        var ownerVisualElement:IVisualElement = owner as IVisualElement;

        // Sanity check to verify owner is still on the display list. If not,
        // leave the arrow in the current position.
        if (!arrow || !ownerVisualElement ||
            (arrowDirection == ArrowDirection.NONE) ||
            (!ownerVisualElement.parent))
            return;

        var isStartPosition:Boolean = false;
        var isMiddlePosition:Boolean = false;
        var isEndPosition:Boolean = false;

        var position:String = (isArrowVertical) ? actualHorizontalPosition : actualVerticalPosition;

        isStartPosition = (position == CalloutPosition.START);
        isMiddlePosition = (position == CalloutPosition.MIDDLE);
        isEndPosition = (position == CalloutPosition.END);

        var isEndOfCallout:Boolean = (arrowDirection == ArrowDirection.DOWN)
            || (arrowDirection == ArrowDirection.RIGHT);

        var calloutWidth:Number = getLayoutBoundsWidth();
        var calloutHeight:Number = getLayoutBoundsHeight();
        var arrowWidth:Number = arrow.getLayoutBoundsWidth();
        var arrowHeight:Number = arrow.getLayoutBoundsHeight();

        // arrow X/Y in pop-up coordinates
        var arrowX:Number = 0;
        var arrowY:Number = 0;

        // Max arrow positions
        var maxArrowX:Number = calloutWidth - arrowWidth;
        var maxArrowY:Number = calloutHeight - arrowHeight;
        
        // Find the registration point of the owner
        var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
        var regPoint:Point = owner.localToGlobal(new Point());
        regPoint = sandboxRoot.globalToLocal(regPoint);

        if (isArrowVertical)
        {
            // Vertical arrows need horizontal alignment
            var ownerX:Number = regPoint.x;
            var ownerVisibleWidth:Number = (ownerVisualElement)
                ? ownerVisualElement.getLayoutBoundsWidth() : owner.width;

            // Edge cases when start/end of owner is not visible
            if ((ownerX < 0) && (ownerVisibleWidth < screen.width))
                ownerVisibleWidth = Math.max(ownerVisibleWidth + ownerX, 0);
            else if ((ownerX >= 0) && ((ownerX + ownerVisibleWidth) >= screen.width))
                ownerVisibleWidth = Math.max(screen.width - ownerX, 0);

            ownerVisibleWidth = Math.min(ownerVisibleWidth, screen.width);

            if (calloutWidth <= ownerVisibleWidth)
            {
                arrowX = (calloutWidth - arrowWidth) / 2;
            }
            else // if (calloutWidth > ownerWidth)
            {
                // Center the arrow on the owner
                arrowX = (ownerVisibleWidth - arrowWidth) / 2;
                
                // Add owner offset
                if (ownerX > 0)
                    arrowX += Math.abs(ownerX - getLayoutBoundsX());
                
                if (ownerX < margin)
                    arrowX -= (margin - ownerX);
            }
            
            // arrow should not extend past the callout bounds
            arrowX = Math.max(Math.min(maxArrowX, arrowX), 0);

            // Move the arrow to the bottom of the callout
            if (isEndOfCallout)
                arrowY = calloutHeight - arrowHeight;
        }
        else
        {
            // Horizontal arrows need vertical alignment
            var ownerY:Number = regPoint.y;
            var ownerVisibleHeight:Number = (ownerVisualElement)
                ? ownerVisualElement.getLayoutBoundsHeight() : owner.height;

            // Edge cases when start/end of owner is not visible
            if ((ownerY < 0) && (ownerVisibleHeight < screen.height))
                ownerVisibleHeight = Math.max(ownerVisibleHeight + ownerY, 0);
            else if ((ownerY >= 0) && ((ownerY + ownerVisibleHeight) >= screen.height))
                ownerVisibleHeight = Math.max(screen.height - ownerY, 0);

            ownerVisibleHeight = Math.min(ownerVisibleHeight, screen.height);

            if (calloutHeight <= ownerVisibleHeight)
            {
                arrowY = (calloutHeight - arrowHeight) / 2;
            }
            else // if (calloutHeight > ownerHeight)
            {
                // Center the arrow on the owner
                arrowY = (ownerVisibleHeight - arrowHeight) / 2;
                
                // Add owner offset
                if (ownerY > 0)
                    arrowY += Math.abs(ownerY - getLayoutBoundsY());
                
                if (ownerY < margin)
                    ownerY -= (margin - ownerY);
            }
            
            // arrow should not extend past the callout bounds
            arrowY = Math.max(Math.min(maxArrowY, arrowY), 0);

            // Move the arrow to the end of the callout
            if (isEndOfCallout)
                arrowX = calloutWidth - arrowWidth;
        }

        arrow.setLayoutBoundsPosition(Math.floor(arrowX), Math.floor(arrowY));
        arrow.invalidateDisplayList();
    }
    
    /**
     *  @private
     * 
     *  Flip or clear the adjusted position when the callout bounds are outside
     *  the screen bounds.
     */
    mx_internal function adjustCalloutPosition(actualPosition:String, preferredPosition:String,
                                               calloutStart:Number, calloutEnd:Number,
                                               screenStart:Number, screenEnd:Number,
                                               ownerStart:Number, ownerEnd:Number,
                                               revert:Boolean=false):String
    {
        if (!actualPosition)
            return null;
        
        var adjustedPosition:String = null;
        var calloutSize:Number = calloutEnd - calloutStart;
        
        // Exterior space
        var exteriorSpaceStart:Number = Math.max(0, ownerStart - screenStart);
        var exteriorSpaceEnd:Number = Math.max(0, ownerEnd - screenEnd);
        
        // Fallback to interior positions if using AUTO and callout can not
        // fit in either exterior positions
        var useInterior:Boolean = (preferredPosition == CalloutPosition.AUTO) &&
            (exteriorSpaceStart < calloutSize) &&
            (exteriorSpaceEnd < calloutSize);
        var isExterior:Boolean = false;
        
        // Flip to opposite position
        switch (actualPosition)
        {
            case CalloutPosition.BEFORE:
            {
                isExterior = true;
                
                if (calloutStart < screenStart)
                    adjustedPosition = CalloutPosition.AFTER;
                
                break;
            }
            case CalloutPosition.AFTER:
            {
                isExterior = true;
                
                if (calloutEnd > screenEnd)
                    adjustedPosition = CalloutPosition.BEFORE;
                
                break;
            }
            case CalloutPosition.END:
            {
                if (calloutStart < screenStart)
                    adjustedPosition = CalloutPosition.START;
                break;
            }
            case CalloutPosition.START:
            {
                if (calloutEnd > screenEnd)
                    adjustedPosition = CalloutPosition.END;
                break;
            }
            // case CalloutPosition.MIDDLE:
            // Nudge instead of flipping
        }
        
        // Use interior position if exterior flipping was necessary
        if (useInterior && adjustedPosition && isExterior)
        {
            // Choose the exterior position with the most available space.
            // Note that START grows towards the exterior END and vice versa.
            adjustedPosition = (exteriorSpaceEnd >= exteriorSpaceStart) ? 
                CalloutPosition.START : CalloutPosition.END;
        }
        
        // Return null to revert the adjusted position
        // Otherwise, return the incoming position
        if (revert)
            return (adjustedPosition) ? null : actualPosition;
        
        // Adjusted position or null if the callout already fits
        return adjustedPosition;
    }
    
    /**
     *  @private
     * 
     *  Nudge the callout position to fit on screen. Prefer top/left positions
     *  and allow overflow to get clipped on the bottom/right.
     */
    mx_internal function nudgeToFit(calloutStart:Number, calloutEnd:Number,
                                    screenStart:Number, screenEnd:Number,
                                    scaleFactor:Number):Number
    {
        var position:Number = 0;
        
        if (calloutStart < screenStart)
            position += (screenStart - calloutStart) / scaleFactor;
        else if (calloutEnd > screenEnd)
            position -= (calloutEnd - screenEnd) / scaleFactor;
        
        return position;
    }

    /**
     *  @private
     *
     *  Basically the same as PopUpAnchor, but with more position options
     *  including exterior, interior and corner positions.
     * 
     *  Nudging to fit the screen accounts for <code>margin</code> so that
     *  the Callout is not positioned in the margin.
     * 
     *  <code>arrowDirection</code> will change if required for the callout
     *  to fit.
     *
     *  @see #margin
     */
    mx_internal function calculatePopUpPosition():Point
    {
        // This implementation doesn't handle rotation
        var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
        var matrix:Matrix = MatrixUtil.getConcatenatedMatrix(owner, sandboxRoot);

        var regPoint:Point = new Point();

        if (!matrix)
            return regPoint;
        
        var adjustedHorizontalPosition:String;
        var adjustedVerticalPosition:String;
        var calloutBounds:Rectangle = determinePosition(actualHorizontalPosition,
            actualVerticalPosition, matrix, regPoint);
        var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());

        // Position the callout in the opposite direction if it
        // does not fit on the screen.
        if (screen)
        {
            adjustedHorizontalPosition = adjustCalloutPosition(
                actualHorizontalPosition, horizontalPosition,
                calloutBounds.left, calloutBounds.right,
                screen.left, screen.right,
                ownerBounds.left, ownerBounds.right);

            adjustedVerticalPosition = adjustCalloutPosition(
                actualVerticalPosition, verticalPosition,
                calloutBounds.top, calloutBounds.bottom,
                screen.top, screen.bottom,
                ownerBounds.top, ownerBounds.bottom);
        }

        var oldArrowDirection:String = arrowDirection;
        var actualArrowDirection:String = null;
        
        // Reset arrowDirectionAdjusted
        arrowDirectionAdjusted = false;

        // Get the new registration point based on the adjusted position
        if ((adjustedHorizontalPosition != null) || (adjustedVerticalPosition != null))
        {
            var adjustedRegPoint:Point = new Point();
            var tempHorizontalPosition:String = (adjustedHorizontalPosition)
                ? adjustedHorizontalPosition : actualHorizontalPosition;
            var tempVerticalPosition:String = (adjustedVerticalPosition)
                ? adjustedVerticalPosition : actualVerticalPosition;

            // Adjust arrow direction after adjusting position
            actualArrowDirection = determineArrowPosition(tempHorizontalPosition,
                tempVerticalPosition);

            // All position flips gaurantee an arrowDirection change
            setArrowDirection(actualArrowDirection);
            arrowDirectionAdjusted = true;

            if (arrow)
                arrow.visible = (arrowDirection != ArrowDirection.NONE);

            // Reposition the arrow
            updateSkinDisplayList();

            var adjustedBounds:Rectangle = determinePosition(tempHorizontalPosition,
                tempVerticalPosition, matrix, adjustedRegPoint);

            if (screen)
            {
                // If we adjusted the position but the callout still doesn't fit,
                // then revert to the original position.
                adjustedHorizontalPosition = adjustCalloutPosition(
                    adjustedHorizontalPosition, horizontalPosition,
                    adjustedBounds.left, adjustedBounds.right,
                    screen.left, screen.right,
                    ownerBounds.left, ownerBounds.right,
                    true);
                
                adjustedVerticalPosition = adjustCalloutPosition(
                    adjustedVerticalPosition, verticalPosition,
                    adjustedBounds.top, adjustedBounds.bottom,
                    screen.top, screen.bottom, 
                    ownerBounds.top, ownerBounds.bottom,
                    true);
            }

            if ((adjustedHorizontalPosition != null) || (adjustedVerticalPosition != null))
            {
                regPoint = adjustedRegPoint;
                calloutBounds = adjustedBounds;

                // Temporarily set actual positions to reposition the arrow
                if (adjustedHorizontalPosition)
                    actualHorizontalPosition = adjustedHorizontalPosition;

                if (adjustedVerticalPosition)
                    actualVerticalPosition = adjustedVerticalPosition;

                // Reposition the arrow with the new actual position
                updateSkinDisplayList();
            }
            else
            {
                // Restore previous arrow direction *before* reversing the
                // adjusted positions
                setArrowDirection(oldArrowDirection);
                arrowDirectionAdjusted = false;

                // Reposition the arrow to the original position
                updateSkinDisplayList();
            }
        }

        MatrixUtil.decomposeMatrix(decomposition, matrix, 0, 0);
        var concatScaleX:Number = decomposition[3];
        var concatScaleY:Number = decomposition[4];

        // If the callout still doesn't fit, then nudge it
        // so it is completely on the screen. Make sure to include scale.
        var screenTop:Number = screen.top;
        var screenBottom:Number = screen.bottom;
        var screenLeft:Number = screen.left;
        var screenRight:Number = screen.right;
        
        // Allow zero margin on the the side with the arrow
        switch (arrowDirection)
        {
            case ArrowDirection.UP:
            {
                screenBottom -= margin;
                screenLeft += margin;
                screenRight -= margin
                break;
            }
            case ArrowDirection.DOWN:
            {
                screenTop += margin;
                screenLeft += margin;
                screenRight -= margin
                break;
            }
            case ArrowDirection.LEFT:
            {
                screenTop += margin;
                screenBottom -= margin;
                screenRight -= margin
                break;
            }
            case ArrowDirection.RIGHT:
            {
                screenTop += margin;
                screenBottom -= margin;
                screenLeft += margin;
                break;
            }
            default:
            {
                screenTop += margin;
                screenBottom -= margin;
                screenLeft += margin;
                screenRight -= margin
                break;
            }
        }
        
        regPoint.y += nudgeToFit(calloutBounds.top, calloutBounds.bottom,
            screenTop, screenBottom, concatScaleY);
        
        regPoint.x += nudgeToFit(calloutBounds.left, calloutBounds.right,
            screenLeft, screenRight, concatScaleX);

        // Compute the stage coordinates of the upper,left corner of the PopUp, taking
        // the postTransformOffsets - which include mirroring - into account.
        // If we're mirroring, then the implicit assumption that x=left will fail,
        // so we compensate here.

        if (layoutDirection == LayoutDirection.RTL)
            regPoint.x += calloutBounds.width;
        return MatrixUtil.getConcatenatedComputedMatrix(owner, sandboxRoot).transformPoint(regPoint);
    }

    /**
     *  @private
     *  Computes <code>actualHorizontalPosition</code> and/or
     *  <code>actualVerticalPosition</code> values when using
     *  <code>CalloutPosition.AUTO</code>. When implementing subclasses of
     *  Callout, use <code>actualHorizontalPosition</code> and
     *  <code>actualVerticalPosition</code> to compute
     *  <code>arrowDirection</code> and positioning in
     *  <code>updatePopUpPosition()</code> and <code>updateSkinDisplayList()</code>.
     *
     *  <p>The default implementation chooses "outer" positions for the callout
     *  such that the owner is not obscured. Horizontal/Vertical orientation
     *  relative to the owner choosen based on the aspect ratio.</p>
     *
     *  <p>When the aspect ratio is landscape, and the callout can fit to the
     *  left or right of the owner, <code>actualHorizontalPosition</code> is
     *  set to <code>CalloutPosition.BEFORE</code> or
     *  <code>CalloutPosition.AFTER</code> as appropriate.
     *  <code>actualVerticalPosition</code> is set to
     *  <code>CalloutPosition.MIDDLE</code> to have the vertical center of the
     *  callout align to the vertical center of the owner.</p>
     *
     *  <p>When the aspect ratio is portrait, and the callout can fit
     *  above or below the owner, <code>actualVerticalPosition</code> is
     *  set to <code>CalloutPosition.BEFORE</code> or
     *  <code>CalloutPosition.AFTER</code> as appropriate.
     *  <code>actualHorizontalPosition</code> is set to
     *  <code>CalloutPosition.MIDDLE</code> to have the horizontal center of the
     *  callout align to the horizontal center of the owner.</p>
     *
     *  <p>Subclasses may override to modify automatic positioning behavior.</p>
     */
    mx_internal function commitAutoPosition():void
    {
        if (!screen || ((horizontalPosition != CalloutPosition.AUTO) &&
            (verticalPosition != CalloutPosition.AUTO)))
        {
            // Use explicit positions instead of AUTO
            actualHorizontalPosition = null;
            actualVerticalPosition = null;
            
            return;
        }

        var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());

        // Use aspect ratio to determine vertical/horizontal preference
        var isLandscape:Boolean = (screen.width > screen.height);

        // Exterior space
        var exteriorSpaceLeft:Number = Math.max(0, ownerBounds.left);
        var exteriorSpaceRight:Number = Math.max(0, screen.width - ownerBounds.right);
        var exteriorSpaceTop:Number = Math.max(0, ownerBounds.top);
        var exteriorSpaceBottom:Number = Math.max(0, screen.height - ownerBounds.bottom);

        if (verticalPosition != CalloutPosition.AUTO)
        {
            // Horizontal auto only
            switch (verticalPosition)
            {
                case CalloutPosition.START:
                case CalloutPosition.MIDDLE:
                case CalloutPosition.END:
                {
                    actualHorizontalPosition = (exteriorSpaceRight > exteriorSpaceLeft) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
                    break;
                }
                default:
                {
                    actualHorizontalPosition = CalloutPosition.MIDDLE;
                    break;
                }
            }
            
            actualVerticalPosition = null;
        }
        else if (horizontalPosition != CalloutPosition.AUTO)
        {
            // Vertical auto only
            switch (horizontalPosition)
            {
                case CalloutPosition.START:
                case CalloutPosition.MIDDLE:
                case CalloutPosition.END:
                {
                    actualVerticalPosition = (exteriorSpaceBottom > exteriorSpaceTop) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
                    break;
                }
                default:
                {
                    actualVerticalPosition = CalloutPosition.MIDDLE;
                    break;
                }
            }
            
            actualHorizontalPosition = null;
        }
        else // if ((verticalPosition == CalloutPosition.AUTO) && (horizontalPosition == CalloutPosition.AUTO))
        {
            if (!isLandscape)
            {
                // Arrow will be vertical when in portrait
                actualHorizontalPosition = CalloutPosition.MIDDLE;
                actualVerticalPosition = (exteriorSpaceBottom > exteriorSpaceTop) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
            }
            else
            {
                // Arrow will be horizontal when in landscape
                actualHorizontalPosition = (exteriorSpaceRight > exteriorSpaceLeft) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
                actualVerticalPosition = CalloutPosition.MIDDLE;
            }
        }
    }
    
    /**
     *  @private
     *  Return true if user-specified max size if set
     */
    mx_internal function get isMaxSizeSet():Boolean
    {
        var explicitMaxW:Number = super.explicitMaxWidth;
        var explicitMaxH:Number = super.explicitMaxHeight;
        
        return (!isNaN(explicitMaxW) && !isNaN(explicitMaxH));
    }
    
    /**
     *  @private
     *  Return the original height if the soft keyboard is active. This height
     *  is used to stabilize AUTO positioning so that the position is based
     *  on the original height of the Callout instead of a possibly shorter
     *  height due to soft keyboard effects.
     */
    mx_internal function get calloutHeight():Number
    {
        return (isSoftKeyboardEffectActive) ? softKeyboardEffectCachedHeight : getLayoutBoundsHeight();
    }
    
    /**
     *  @private
     *  Compute max width and max height. Uses the the owner and screen bounds 
     *  as well as preferred positions to determine max width and max height  
     *  for all possible exterior and interior positions.
     */
    mx_internal function commitMaxSize():void
    {
        var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
        var ownerLeft:Number = ownerBounds.left;
        var ownerRight:Number = ownerBounds.right;
        var ownerTop:Number = ownerBounds.top;
        var ownerBottom:Number = ownerBounds.bottom;
        var maxW:Number;
        var maxH:Number;
        
        switch (actualHorizontalPosition)
        {
            case CalloutPosition.MIDDLE:
            {
                // Callout matches screen width
                maxW = screen.width - (margin * 2);
                break;
            }
            case CalloutPosition.START:
            case CalloutPosition.END:
            {
                // Flip left and right when using inner positions
                ownerLeft = ownerBounds.right;
                ownerRight = ownerBounds.left;
                
                // Fall through
            }
            default:
            {
                // Maximum is the larger of the actual position or flipped position
                maxW = Math.max(ownerLeft, screen.right - ownerRight) - margin;
                break;
            }
        }
        
        // If preferred position was AUTO, then allow maxWidth to grow to
        // fit the interior position if the owner is wide
        if ((horizontalPosition == CalloutPosition.AUTO) &&
            (ownerBounds.width > maxW))
            maxW += ownerBounds.width;
        
        switch (actualVerticalPosition)
        {
            case CalloutPosition.MIDDLE:
            {
                // Callout matches screen height
                maxH = screen.height - (margin * 2);
                break;
            }
            case CalloutPosition.START:
            case CalloutPosition.END:
            {
                // Flip top and bottom when using inner positions
                ownerTop = ownerBounds.bottom;
                ownerBottom = ownerBounds.top;
                
                // Fall through
            }
            default:
            {
                // Maximum is the larger of the actual position or flipped position
                maxH = Math.max(ownerTop, screen.bottom - ownerBottom) - margin;
                break;
            }
        }
        
        // If preferred position was AUTO, then allow maxHeight to grow to
        // fit the interior position if the owner is tall
        if ((verticalPosition == CalloutPosition.AUTO) && 
            (ownerBounds.height > maxH))
            maxH += ownerBounds.height;
        
        calloutMaxWidth = maxW;
        calloutMaxHeight = maxH;
    }

    /**
     *  @private
     */
    mx_internal function determineArrowPosition(horizontalPos:String, verticalPos:String):String
    {
        // Determine arrow direction, outer positions get priority.
        // Corner positions and center show no arrow
        var direction:String = ArrowDirection.NONE;

        if (horizontalPos == CalloutPosition.BEFORE)
        {
            if ((verticalPos != CalloutPosition.BEFORE)
                &&  (verticalPos != CalloutPosition.AFTER))
            {
                direction = ArrowDirection.RIGHT;
            }
        }
        else if (horizontalPos == CalloutPosition.AFTER)
        {
            if ((verticalPos != CalloutPosition.BEFORE)
                && (verticalPos != CalloutPosition.AFTER))
            {
                direction = ArrowDirection.LEFT;
            }
        }
        else if (verticalPos == CalloutPosition.BEFORE)
        {
            direction = ArrowDirection.DOWN;
        }
        else if (verticalPos == CalloutPosition.AFTER)
        {
            direction = ArrowDirection.UP;
        }
        else if (horizontalPos == CalloutPosition.START)
        {
            direction = ArrowDirection.LEFT;
        }
        else if (horizontalPos == CalloutPosition.END)
        {
            direction = ArrowDirection.RIGHT;
        }
        else if (verticalPos == CalloutPosition.START)
        {
            direction = ArrowDirection.UP;
        }
        else if (verticalPos == CalloutPosition.END)
        {
            direction = ArrowDirection.DOWN;
        }

        return direction;
    }

    /**
     *  @private
     * 
     *  Uses horizontalPosition and verticalPosition to determine the bounds of
     *  the callout.
     */
    mx_internal function determinePosition(horizontalPos:String, verticalPos:String,
                                           matrix:Matrix, registrationPoint:Point):Rectangle
    {
        var ownerVisualElement:ILayoutElement = owner as ILayoutElement;
        var ownerWidth:Number = (ownerVisualElement) ? ownerVisualElement.getLayoutBoundsWidth() : owner.width;
        var ownerHeight:Number = (ownerVisualElement) ? ownerVisualElement.getLayoutBoundsHeight() : owner.height;
        var calloutWidth:Number = getLayoutBoundsWidth();
        var calloutHeight:Number = this.calloutHeight;

        switch (horizontalPos)
        {
            case CalloutPosition.BEFORE:
            {
                // The full width of the callout is before the owner
                // All arrow directions are ArrowDirection.RIGHT x=(width - arrow.width)
                registrationPoint.x = -calloutWidth;
                break;
            }
            case CalloutPosition.START:
            {
                // ArrowDirection.LEFT is at x=0
                registrationPoint.x = 0;
                break;
            }
            case CalloutPosition.END:
            {
                // The ends of the owner and callout are aligned
                registrationPoint.x = (ownerWidth - calloutWidth);
                break;
            }
            case CalloutPosition.AFTER:
            {
                // The full width of the callout is after the owner
                // All arrow directions are ArrowDirection.LEFT (x=0)
                registrationPoint.x = ownerWidth;
                break;
            }
            default: // case CalloutPosition.MIDDLE:
            {
                registrationPoint.x = Math.floor((ownerWidth - calloutWidth) / 2);
                break;
            }
        }

        switch (verticalPos)
        {
            case CalloutPosition.BEFORE:
            {
                // The full height of the callout is before the owner
                // All arrow directions are ArrowDirection.DOWN y=(height - arrow.height)
                registrationPoint.y = -calloutHeight;
                break;
            }
            case CalloutPosition.START:
            {
                // ArrowDirection.UP is at y=0
                registrationPoint.y = 0;
                break;
            }
            case CalloutPosition.MIDDLE:
            {
                registrationPoint.y = Math.floor((ownerHeight - calloutHeight) / 2);
                break;
            }
            case CalloutPosition.END:
            {
                // The ends of the owner and callout are aligned
                registrationPoint.y = (ownerHeight - calloutHeight);
                break;
            }
            default: //case CalloutPosition.AFTER:
            {
                // The full height of the callout is after the owner
                // All arrow directions are ArrowDirection.UP (y=0)
                registrationPoint.y = ownerHeight;
                break;
            }
        }

        var topLeft:Point = registrationPoint.clone();
        var size:Point = MatrixUtil.transformBounds(calloutWidth, calloutHeight, matrix, topLeft);
        var bounds:Rectangle = new Rectangle();
        
        bounds.left = topLeft.x;
        bounds.top = topLeft.y;
        bounds.width = size.x;
        bounds.height = size.y;
        
        return bounds;
    }
    
    /**
     * @private
     */
    mx_internal function get isArrowVertical():Boolean
    {
        return (arrowDirection == ArrowDirection.UP ||
                arrowDirection == ArrowDirection.DOWN);
    }

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

    /**
     *  @private
     */
    private function arrow_resizeHandler(event:Event):void
    {
        updateSkinDisplayList();
    }
    
    /**
     *  @private
     */
    private function systemManager_resizeHandler(event:Event):void
    {
        // Remove explicit settings if due to Resize effect
        softKeyboardEffectResetExplicitSize();
        
        // Screen resize might require a new arrow direction and callout position
        invalidatePosition();
        
        if (!isSoftKeyboardEffectActive)
        {
            // Force validation and use new screen size only if the keyboard
            // effect is not active. The stage dimensions may be invalid while 
            // the soft keyboard is active. See SDK-31860.
            validateNow();
        }
    }
}
}