////////////////////////////////////////////////////////////////////////////////
//
//  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.events.Event;
import mx.core.Container;
import mx.core.EdgeMetrics;
import mx.core.IUIComponent;
import mx.core.mx_internal;

use namespace mx_internal;

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

/**
 *  Horizontal alignment of each child inside its tile cell.
 *  Possible values are <code>"left"</code>, <code>"center"</code>, and
 *  <code>"right"</code>.
 *  If the value is <code>"left"</code>, the left edge of each child
 *  is at the left edge of its cell.
 *  If the value is <code>"center"</code>, each child is centered horizontally
 *  within its cell.
 *  If the value is <code>"right"</code>, the right edge of each child
 *  is at the right edge of its cell.
 *
 *  @default "left"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="horizontalAlign", type="String", enumeration="left,center,right", inherit="no")]

/**
 *  Number of pixels between children in the horizontal direction.
 *
 *  @default 8
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="horizontalGap", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the container's bottom 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")]

/**
 *  Vertical alignment of each child inside its tile cell.
 *  Possible values are <code>"top"</code>, <code>"middle"</code>, and
 *  <code>"bottom"</code>.
 *  If the value is <code>"top"</code>, the top edge of each child
 *  is at the top edge of its cell.
 *  If the value is <code>"middle"</code>, each child is centered vertically
 *  within its cell.
 *  If the value is <code>"bottom"</code>, the bottom edge of each child
 *  is at the bottom edge of its cell.
 *
 *  @default "top"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="verticalAlign", type="String", enumeration="bottom,middle,top", inherit="no")]

/**
 *  Number of pixels between children in the vertical direction.
 *
 *  @default 6
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="verticalGap", type="Number", format="Length", inherit="no")]

//--------------------------------------
//  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
//--------------------------------------

[IconFile("Tile.png")]

/**
 *  The layout-specific container components in Flex 3 have been replaced by a more generic
 *  Group component that takes a generic layout. To get similar behavior from the new
 *  Group component, set the <code>layout</code> property to <code>TileLayout</code>
 *  or use the TileGroup container.
 */
[Alternative(replacement="spark.components.TileGroup", since="4.0")]
[Alternative(replacement="spark.components.BorderContainer", since="4.0")]

/**
 *  A Halo Tile container lays out its children
 *  in a grid of equal-sized cells.
 *  You can specify the size of the cells by using the
 *  <code>tileWidth</code> and <code>tileHeight</code> properties,
 *  or let the Tile container determine the cell size
 *  based on the largest child.
 *  A Tile container's <code>direction</code> property
 *  determines whether its cells are laid out horizontally or
 *  vertically, beginning from the upper-left corner of the
 *  Tile container.
 * 
 *  <p><b>Note:</b> Adobe recommends that, when possible, you use the Spark containers 
 *  with TileLayout instead of the Halo Tile container.</p>
 *
 *  <p>A Tile container has the following default sizing characteristics:</p>
 *     <table class="innertable">
 *        <tr>
 *           <th>Characteristic</th>
 *           <th>Description</th>
 *        </tr>
 *        <tr>
 *           <td>Direction</td>
 *           <td>horizontal</td>
 *        </tr>
 *        <tr>
 *           <td>Default size of all cells</td>
 *           <td>Height is the default or explicit height of the tallest child.<br/>
 *               Width is the default or explicit width of the widest child.<br/>
 *               All cells have the same default size.</td>
 *        </tr>
 *        <tr>
 *           <td>Default size of Tile container</td>
 *           <td>Flex computes the square root of the number of children, and rounds up to the nearest 
 *               integer. For example, if there are 26 children, the square root is 5.1, which is rounded up to 6. 
 *               Flex then lays out the Tile container in a 6 by 6 grid.<br/>
 *               Default height of the Tile container is equal to 
 *               (tile cell default height) <strong>x</strong> (rounded square root of the number of children),
 *               plus any gaps between children and any padding.<br/>
 *               Default width is equal to
 *               (tile cell default width) <strong>x</strong> (rounded square root of the number of children),
 *               plus any gaps between children and any padding.</td>
 *        </tr>
 *        <tr>
 *           <td>Minimum size of Tile container</td>
 *           <td>The default size of a single cell. Flex always allocates enough space to display at least 
 *               one cell.</td>
 *        </tr>
 *        <tr>
 *           <td>Default padding</td>
 *           <td>0 pixels for the top, bottom, left, and right values.</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:Tile&gt;</code> tag inherits all of the tag attributes
 *  of its superclass, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:Tile
 *    <b>Properties</b>
 *    direction="horizontal|vertical"
 *    tileHeight="NaN"
 *    tileWidth="NaN"
 * 
 *    <b>Sttles</b>
 *    horizontalAlign="left|center|right"
 *    horizontalGap="8"
 *    paddingBottom="0"
 *    paddingTop="0"
 *    verticalAlign="top|middle|bottom"
 *    verticalGap="6"
 *    &gt;
 *      ...
 *      <i>child tags</i>
 *     ...
 *  &lt;/mx:Tile&gt;
 *  </pre>
 *
 *  @includeExample examples/TileLayoutExample.mxml
 *
 *  @see mx.core.Container
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class Tile extends Container
{
    include "../core/Version.as";

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

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

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Cached value from findCellSize() call in measure(),
     *  so that updateDisplayList() doesn't also have to call findCellSize().
     */
    mx_internal var cellWidth:Number;
    
    /**
     *  @private
     *  Cached value from findCellSize() call in measure(),
     *  so that updateDisplaylist() doesn't also have to call findCellSize().
     */
    mx_internal var cellHeight:Number;

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

    //----------------------------------
    //  direction
    //----------------------------------

    /**
     *  @private
     *  Storage for the direction property.
     */
    private var _direction:String = TileDirection.HORIZONTAL;

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

    /**
     *  Determines how children are placed in the container.
     *  Possible MXML values  are <code>"horizontal"</code> and
     *  <code>"vertical"</code>.
     *  In ActionScript, you can set the direction using the values
     *  TileDirection.HORIZONTAL or TileDirection.VERTICAL.
     *  The default value is <code>"horizontal"</code>.
     *  (If the container is a Legend container, which is a subclass of Tile,
     *  the default value is <code>"vertical"</code>.)
     *
     *  <p>The first child is always placed at the upper-left of the
     *  Tile container.
     *  If the <code>direction</code> is <code>"horizontal"</code>,
     *  the children are placed left-to-right in the topmost row,
     *  and then left-to-right in the second row, and so on.
     *  If the value is <code>"vertical"</code>, the children are placed
     *  top-to-bottom in the leftmost column, and then top-to-bottom
     *  in the second column, and so on.</p>
     *
     *  @default "horizontal"
     * 
     *  @see TileDirection
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get direction():String
    {
        return _direction;
    }

    /**
     *  @private
     */
    public function set direction(value:String):void
    {
        _direction = value;
        
        invalidateSize();
        invalidateDisplayList();
        
        dispatchEvent(new Event("directionChanged"));
    }

    //----------------------------------
    //  tileHeight
    //----------------------------------

    /**
     *  @private
     *  Storage for the tileHeight property.
     */
    private var _tileHeight:Number;

    [Bindable("resize")]
    [Inspectable(category="General")]

    /**
     *  Height of each tile cell, in pixels. 
     *  If this property is <code>NaN</code>, the default, the height
     *  of each cell is determined by the height of the tallest child.
     *  If you set this property, the specified value overrides
     *  this calculation.
     *
     *  @default NaN
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get tileHeight():Number
    {
        return _tileHeight;
    }

    /**
     *  @private
     */
    public function set tileHeight(value:Number):void
    {
        _tileHeight = value;
        
        invalidateSize();
    }

    //----------------------------------
    //  tileWidth
    //----------------------------------

    /**
     *  @private
     *  Storage for the tileWidth property.
     */
    private var _tileWidth:Number;

    [Bindable("resize")]
    [Inspectable(category="General")]

    /**
     *  Width of each tile cell, in pixels.
     *  If this property is <code>NaN</code>, the defualt, the width
     *  of each cell is determined by the width of the widest child.
     *  If you set this property, the specified value overrides
     *  this calculation.
     *
     *  @default NaN
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get tileWidth():Number
    {
        return _tileWidth;
    }

    /**
     *  @private
     */
    public function set tileWidth(value:Number):void
    {
        _tileWidth = value;

        invalidateSize();
    }

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

    /**
     *  Calculates the default minimum and maximum sizes of the
     *  Tile container.
     *  For more information about the <code>measure()</code> method,
     *  see the <code>UIComponent.measure()</code> method.
     *  
     *  <p>This method first calculates the size of each tile cell.
     *  For a description of how the cell size is determined, see the
     *  <code>tileWidth</code> and <code>tileHeight</code> properties.</p>
     *  
    *  <p>The measured size of a Tile container with children
     *  is sufficient to display the cells in an N-by-N grid
     *  with an equal number of rows and columns, plus room for
     *  the Tile container's padding and borders.
     *  However, there are various special cases, as in the following
     *  examples:</p>
     *
     *  <ul>
     *  <li>If a horizontal Tile container has an
     *  explicit width set, that value determines how many
     *  cells will fit horizontally, and the height required to fit all the
     *  children is calculated, producing an M-by-N grid.</li>
     *
     *  <li>If a vertical Tile container has an
     *  explicit height set, that value determines how many
     *  cells will fit vertically, and the height required to fit all the
     *  children is calculated, producing an N-by-M grid.</li>
     *  </ul>
     *
     *  <p>If there are no children, the measured size is just
     *  large enough for its padding and borders.</p>
     *  
     *  <p>The minimum measured size of a Tile container
     *  with children is just large enough for a single tile cell,
     *  plus padding and borders.
     *  If there are no children, the minimum measured size is just
     *  large enough for its padding and borders.</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();

        var preferredWidth:Number;
        var preferredHeight:Number;
        var minWidth:Number;
        var minHeight:Number;

        // Determine the size of each tile cell and cache the values
        // in cellWidth and cellHeight for later use by updateDisplayList().
        findCellSize();

        // Min width and min height are large enough to display a single child.
        minWidth = cellWidth;
        minHeight = cellHeight;

        // Determine the width and height necessary to display the tiles
        // in an N-by-N grid (with number of rows equal to number of columns).
        var n:int = numChildren;

        // Don't count children that don't need their own layout space.
        var temp:int = n;
        for (var i:int = 0; i < n; i++)
        {
            if (!IUIComponent(getChildAt(i)).includeInLayout)
                temp--;
        }
        n = temp;

        if (n > 0)
        {
            var horizontalGap:Number = getStyle("horizontalGap");
            var verticalGap:Number = getStyle("verticalGap");
            
            var majorAxis:Number;

            // If an explicit dimension or flex is set for the majorAxis,
            // set as many children as possible along the axis.
            if (direction == TileDirection.HORIZONTAL)
            {
                var unscaledExplicitWidth:Number = explicitWidth / Math.abs(scaleX);
                if (!isNaN(unscaledExplicitWidth))
                {
                    // If we have an explicit height set,
                    // see how many children can fit in the given height:
                    // majorAxis * (cellWidth + horizontalGap) - horizontalGap == unscaledExplicitWidth
                    majorAxis = Math.floor((unscaledExplicitWidth + horizontalGap) /
                                           (cellWidth + horizontalGap));
                }
            }
            else
            {
                var unscaledExplicitHeight:Number = explicitHeight / Math.abs(scaleY);
                if (!isNaN(unscaledExplicitHeight))
                {
                    // If we have an explicit height set,
                    // see how many children can fit in the given height:
                    // majorAxis * (cellHeight + verticalGap) - verticalGap == unscaledExplicitHeight
                    majorAxis = Math.floor((unscaledExplicitHeight + verticalGap) /
                                           (cellHeight + verticalGap));
                }
            }

            // Finally, if majorAxis still isn't defined, use the
            // square root of the number of children.
            if (isNaN(majorAxis))
                majorAxis = Math.ceil(Math.sqrt(n));

            // Even if there's not room, force at least one cell
            // on each row/column.
            if (majorAxis < 1)
                majorAxis = 1;

            var minorAxis:Number = Math.ceil(n / majorAxis);

            if (direction == TileDirection.HORIZONTAL)
            {
                preferredWidth = majorAxis * cellWidth +
                                 (majorAxis - 1) * horizontalGap;

                preferredHeight = minorAxis * cellHeight +
                                  (minorAxis - 1) * verticalGap;
            }
            else
            {
                preferredWidth = minorAxis * cellWidth +
                                 (minorAxis - 1) * horizontalGap;

                preferredHeight = majorAxis * cellHeight +
                                  (majorAxis - 1) * verticalGap;
            }
        }
        else
        {
            preferredWidth = minWidth;
            preferredHeight = minHeight;
        }

        var vm:EdgeMetrics = viewMetricsAndPadding;
        var hPadding:Number = vm.left + vm.right;
        var vPadding:Number = vm.top + vm.bottom;
        
        // Add padding for margins and borders.
        minWidth += hPadding;
        preferredWidth += hPadding;
        minHeight += vPadding;
        preferredHeight += vPadding;

        measuredMinWidth = Math.ceil(minWidth);
        measuredMinHeight = Math.ceil(minHeight);
        measuredWidth = Math.ceil(preferredWidth);
        measuredHeight = Math.ceil(preferredHeight);
    }

    /**
     *  Sets the positions and sizes of this container's children.
     *  For more information about the <code>updateDisplayList()</code>
     *  method, see the <code>UIComponent.updateDisplayList()</code> method.
     *  
     *  <p>This method positions the children in a checkboard-style grid of
     *  equal-sized cells within the content area of the Tile
     *  container (i.e., the area inside its padding).
     *  For a description of how the cell size is determined,
     *  see the <code>tileWidth</code> and
     *  <code>tileHeight</code>properties.</p>
     *  
     *  <p>The separation between the cells is determined by the
     *  <code>horizontalGap</code> and <code>verticalGap</code> styles.
     *  The placement of each child within its cell is determined by the
     *  <code>horizontalAlign</code> and <code>verticalAlign</code> styles.</p>
     *  
     *  <p>The flow of the children is determined by the
     *  <code>direction</code> property.
     *  The first cell is always placed at the upper left of the content area.
     *  If <code>direction</code> is set to <code>"horizontal"</code>, the
     *  cells are placed left-to-right in the topmost row, and then
     *  left-to-right in the second row, and so on.
     *  If <code>direction</code> is set to <code>"vertical"</code>, the cells
     *  are placed top-to-bottom in the leftmost column, and then top-to-bottom
     *  in the second column, and so on.</p>
     *  
     *  <p>If a child has a <code>percentWidth</code> or
     *  <code>percentHeight</code> value, it is resized in that direction
     *  to fill the specified percentage of its tile cell.</p>
     *
     *  @param unscaledWidth Specifies the width of the component, in pixels,
     *  in the component's coordinates, regardless of the value of the
     *  <code>scaleX</code> property of the component.
     *
     *  @param unscaledHeight Specifies the height of the component, in pixels,
     *  in the component's coordinates, regardless of the value of the
     *  <code>scaleY</code> property of the component.   
     * 
     *  @see mx.core.UIComponent#updateDisplayList()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        // The measure function isn't called if the width and height of
        // the Tile are hard-coded. In that case, we compute the cellWidth
        // and cellHeight now.
        if (isNaN(cellWidth) || isNaN(cellHeight))
            findCellSize();
        
        var vm:EdgeMetrics = viewMetricsAndPadding;
        
        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingTop:Number = getStyle("paddingTop");

        var horizontalGap:Number = getStyle("horizontalGap");
        var verticalGap:Number = getStyle("verticalGap");
       
        var horizontalAlign:String = getStyle("horizontalAlign");
        var verticalAlign:String = getStyle("verticalAlign");

        var xPos:Number = paddingLeft;
        var yPos:Number = paddingTop;

        var xOffset:Number;
        var yOffset:Number;
        
        var n:int = numChildren;
        var i:int;
        var child:IUIComponent;
        
        if (direction == TileDirection.HORIZONTAL)
        {
            var xEnd:Number = Math.ceil(unscaledWidth) - vm.right;

            for (i = 0; i < n; i++)
            {
                child = getLayoutChildAt(i);

                if (!child.includeInLayout)
                    continue;

                // Start a new row?
                if (xPos + cellWidth > xEnd)
                {
                    // Only if we have not just started one...
                    if (xPos != paddingLeft)
                    {
                        yPos += (cellHeight + verticalGap);
                        xPos = paddingLeft;
                    }
                }
                
                setChildSize(child); // calls child.setActualSize()

                // Calculate the offsets to align the child in the cell.
                xOffset = Math.floor(calcHorizontalOffset(
                    child.width, horizontalAlign));
                yOffset = Math.floor(calcVerticalOffset(
                    child.height, verticalAlign));
                            
                child.move(xPos + xOffset, yPos + yOffset);

                xPos += (cellWidth + horizontalGap);
            }
        }
        else
        {
            var yEnd:Number = Math.ceil(unscaledHeight) - vm.bottom;

            for (i = 0; i < n; i++)
            {
                child = getLayoutChildAt(i);

                if (!child.includeInLayout)
                    continue;

                // Start a new column?
                if (yPos + cellHeight > yEnd)
                {
                    // Only if we have not just started one...
                    if (yPos != paddingTop)
                    {
                        xPos += (cellWidth + horizontalGap);
                        yPos = paddingTop;
                    }
                }
                
                setChildSize(child); // calls child.setActualSize()

                // Calculate the offsets to align the child in the cell.
                xOffset = Math.floor(calcHorizontalOffset(
                    child.width, horizontalAlign));
                yOffset = Math.floor(calcVerticalOffset(
                    child.height, verticalAlign));
            
                child.move(xPos + xOffset, yPos + yOffset);

                yPos += (cellHeight + verticalGap);
            }
        }

        // Clear the cached cell size, because if a child's size changes
        // it will be invalid. These cached values are only used to
        // avoid recalculating in updateDisplayList() the same values
        // that were just calculated in measure().
        // They should not persist across invalidation/validation cycles.
        // (An alternative approach we tried was to clear these
        // values in an override of invalidateSize(), but this gets called
        // called indirectly by setChildSize() and child.move() inside
        // the loops above. So we had to save and restore cellWidth
        // and cellHeight around these calls in the loops, which is ugly.)
        cellWidth = NaN;
        cellHeight = NaN;
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Calculate and store the cellWidth and cellHeight.
     */
    mx_internal function findCellSize():void
    {
        // If user explicitly supplied both a tileWidth and
        // a tileHeight, then use those values.
        var widthSpecified:Boolean = !isNaN(tileWidth);
        var heightSpecified:Boolean = !isNaN(tileHeight);
        if (widthSpecified && heightSpecified)
        {
            cellWidth = tileWidth;
            cellHeight = tileHeight;
            return;
        }

        // Reset the max child width and height
        var maxChildWidth:Number = 0;
        var maxChildHeight:Number = 0;
        
        // Loop over the children to find the max child width and height.
        var n:int = numChildren;
        for (var i:int = 0; i < n; i++)
        {
            var child:IUIComponent = getLayoutChildAt(i);

            if (!child.includeInLayout)
                continue;
            
            var width:Number = child.getExplicitOrMeasuredWidth();
            if (width > maxChildWidth)
                maxChildWidth = width;
            
            var height:Number = child.getExplicitOrMeasuredHeight();
            if (height > maxChildHeight) 
                maxChildHeight = height;
        }
        
        // If user explicitly specified either width or height, use the
        // user-supplied value instead of the one we computed.
        cellWidth = widthSpecified ? tileWidth : maxChildWidth;
        cellHeight = heightSpecified ? tileHeight : maxChildHeight;
    }

    /**
     *  @private
     *  Assigns the actual size of the specified child,
     *  based on its measurement properties and the cell size.
     */
    private function setChildSize(child:IUIComponent):void
    {
        var childWidth:Number;
        var childHeight:Number;
        var childPref:Number;
        var childMin:Number;

        if (child.percentWidth > 0)
        {
            // Set child width to be a percentage of the size of the cell.
            childWidth = Math.min(cellWidth,
                                  cellWidth * child.percentWidth / 100);
        }
        else
        {
            // The child is not flexible, so set it to its preferred width.
            childWidth = child.getExplicitOrMeasuredWidth();

            // If an explicit tileWidth has been set on this Tile,
            // then the child may extend outside the bounds of the tile cell.
            // In that case, we'll honor the child's width or minWidth,
            // but only if those values were explicitly set by the developer,
            // not if they were implicitly set based on measurements.
            if (childWidth > cellWidth)
            {
                childPref = isNaN(child.explicitWidth) ?
                            0 :
                            child.explicitWidth;

                childMin = isNaN(child.explicitMinWidth) ?
                           0 :
                           child.explicitMinWidth;

                childWidth = (childPref > cellWidth ||
                              childMin > cellWidth) ?
                             Math.max(childMin, childPref) :
                             cellWidth;
            }
        }

        if (child.percentHeight > 0)
        {
            childHeight = Math.min(cellHeight,
                                   cellHeight * child.percentHeight / 100);
        }
        else
        {
            childHeight = child.getExplicitOrMeasuredHeight();

            if (childHeight > cellHeight)
            {
                childPref = isNaN(child.explicitHeight) ?
                            0 :
                            child.explicitHeight;

                childMin = isNaN(child.explicitMinHeight) ?
                           0 :
                           child.explicitMinHeight;

                childHeight = (childPref > cellHeight ||
                               childMin > cellHeight) ?
                               Math.max(childMin, childPref) :
                               cellHeight;
            }
        }

        child.setActualSize(childWidth, childHeight);
    }

    /**
     *  @private
     *  Compute how much adjustment must occur in the x direction
     *  in order to align a component of a given width into the cell.
     */
    mx_internal function calcHorizontalOffset(width:Number,
                                              horizontalAlign:String):Number
    {
        var xOffset:Number;

        if (horizontalAlign == "left")
            xOffset = 0;

        else if (horizontalAlign == "center")
            xOffset = (cellWidth - width) / 2;

        else if (horizontalAlign == "right")
            xOffset = (cellWidth - width);

        return xOffset;
    }

    /**
     *  @private
     *  Compute how much adjustment must occur in the y direction
     *  in order to align a component of a given height into the cell.
     */
    mx_internal function calcVerticalOffset(height:Number,
                                            verticalAlign:String):Number
    {
        var yOffset:Number;

        if (verticalAlign == "top")
            yOffset = 0;

        else if (verticalAlign == "middle")
            yOffset = (cellHeight - height) / 2;

        else if (verticalAlign == "bottom")
            yOffset = (cellHeight - height);

        return yOffset;
    }
}

}
