////////////////////////////////////////////////////////////////////////////////
//
//  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.controls
{

import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.EventPhase;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;

import mx.containers.BoxDirection;
import mx.controls.buttonBarClasses.ButtonBarButton;
import mx.core.ClassFactory;
import mx.core.EdgeMetrics;
import mx.core.FlexVersion;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IUIComponent;
import mx.core.mx_internal;
import mx.events.ChildExistenceChangedEvent;
import mx.events.ItemClickEvent;
import mx.managers.IFocusManagerComponent;
import mx.styles.CSSSelector;
import mx.styles.CSSStyleDeclaration;
import mx.styles.IStyleManager2;

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when a user clicks a button.
 *  This event is only dispatched if the <code>dataProvider</code> property
 *  does not refer to a ViewStack container.
 *
 *  @eventType mx.events.ItemClickEvent.ITEM_CLICK
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="itemClick", type="mx.events.ItemClickEvent")]

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

/**
 *  Height of each button, in pixels.
 *  If undefined, the height of each button is determined by the font styles
 *  applied to the container.
 *  If you set this property, the specified value overrides this calculation.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="buttonHeight", type="Number", format="Length", inherit="no")]

/**
 *  Name of CSS style declaration that specifies styles for the buttons.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="buttonStyleName", type="String", inherit="no")]

/**
 *  Width of each button, in pixels.
 *  If undefined, the default width of each button is calculated from its label text.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="buttonWidth", type="Number", format="Length", inherit="no")]

/**
 *  Name of CSS style declaration that specifies styles for the first button.
 *  If this is unspecified, the default value
 *  of the <code>buttonStyleName</code> style property is used.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="firstButtonStyleName", type="String", inherit="no")]

/**
 *  Horizontal alignment of all buttons within the ButtonBar. Since individual 
 *  buttons stretch to fill the entire ButtonBar, this style is only useful if you
 *  use the buttonWidth style and the combined widths of the buttons are less than
 *  than the width of the ButtonBar.
 *  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="horizontalAlign", type="String", enumeration="left,center,right", inherit="no")]

/**
 *  Number of pixels between children in the horizontal direction.
 *
 *  The default value for the Halo theme is <code>0</code>.
 *  The default value for the Spark theme is <code>-1</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="horizontalGap", type="Number", format="Length", inherit="no")]

/**
 *  Name of CSS style declaration that specifies styles for the last button.
 *  If this is unspecified, the default value
 *  of the <code>buttonStyleName</code> style property is used.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="lastButtonStyleName", type="String", inherit="no")]

/**
 *  Vertical alignment of all buttons within the ButtonBar. Since individual 
 *  buttons stretch to fill the entire ButtonBar, this style is only useful if you
 *  use the buttonHeight style and the combined heights of the buttons are less than
 *  than the width of the ButtonBar.
 *  Possible values are <code>"top"</code>, <code>"middle"</code>,
 *  and <code>"bottom"</code>.
 *
 *  @default "middle"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="verticalAlign", type="String", enumeration="top,middle,bottom", inherit="no")]

/**
 *  Number of pixels between children in the vertical direction.
 *
 *  @default 0
 *  
 *  @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="horizontalLineScrollSize", kind="property")]
[Exclude(name="horizontalPageScrollSize", kind="property")]
[Exclude(name="horizontalScrollBar", kind="property")]
[Exclude(name="horizontalScrollPolicy", kind="property")]
[Exclude(name="horizontalScrollPosition", kind="property")]
[Exclude(name="maxHorizontalScrollPosition", kind="property")]
[Exclude(name="maxVerticalScrollPosition", kind="property")]
[Exclude(name="verticalLineScrollSize", kind="property")]
[Exclude(name="verticalPageScrollSize", kind="property")]
[Exclude(name="verticalScrollBar", kind="property")]
[Exclude(name="verticalScrollPolicy", kind="property")]
[Exclude(name="verticalScrollPosition", kind="property")]

[Exclude(name="scroll", kind="event")]
[Exclude(name="click", kind="event")]

[Exclude(name="backgroundAlpha", kind="style")]
[Exclude(name="backgroundAttachment", kind="style")]
[Exclude(name="backgroundColor", kind="style")]
[Exclude(name="backgroundImage", kind="style")]
[Exclude(name="backgroundSize", kind="style")]
[Exclude(name="borderColor", kind="style")]
[Exclude(name="borderSides", kind="style")]
[Exclude(name="borderSkin", kind="style")]
[Exclude(name="borderStyle", kind="style")]
[Exclude(name="borderThickness", kind="style")]
[Exclude(name="cornerRadius", kind="style")]
[Exclude(name="dropShadowColor", kind="style")]
[Exclude(name="dropShadowEnabled", kind="style")]
[Exclude(name="horizontalScrollBarStyleName", kind="style")]
[Exclude(name="shadowCapColor", kind="style")]
[Exclude(name="shadowColor", kind="style")]
[Exclude(name="shadowDirection", kind="style")]
[Exclude(name="shadowDistance", kind="style")]
[Exclude(name="verticalScrollBarStyleName", kind="style")]

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

[DefaultProperty("dataProvider")]

[DefaultTriggerEvent("itemClick")]

[IconFile("ButtonBar.png")]

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

[MaxChildren(0)]

/**
 *  The ButtonBar control defines a horizontal or vertical group of 
 *  logically related push buttons with a common look and navigation.
 *
 *  <p>A push button is one that does not remember its selected state
 *  when selected.
 *  The typical use for a push button in a button bar is for grouping
 *  a set of related buttons together, which gives them a common look
 *  and navigation, and handling the logic for the <code>click</code> event
 *  in a single place. </p>
 *
 *  <p>The ButtonBar control creates Button controls based on the value of 
 *  its <code>dataProvider</code> property. 
 *  Even though ButtonBar is a subclass of Container, do not use methods such as 
 *  <code>Container.addChild()</code> and <code>Container.removeChild()</code> 
 *  to add or remove Button controls. 
 *  Instead, use methods such as <code>addItem()</code> and <code>removeItem()</code> 
 *  to manipulate the <code>dataProvider</code> property. 
 *  The ButtonBar control automatically adds or removes the necessary children based on 
 *  changes to the <code>dataProvider</code> property.</p>
 *
 *  <p>To control the styling of the buttons of the ButtonBar control, use the 
 *  <code>buttonStyleName</code>, <code>firstButtonStyleName</code>, 
 *  and <code>lastButtonStyleName</code> style properties; 
 *  do not try to style the individual Button controls 
 *  that make up the ButtonBar control.</p>
 *
 *  <p>You can use the ToggleButtonBar control to define a group
 *  of toggle buttons.</p>
 *
 *  <p>ButtonBar control has the following default characteristics:</p>
 *  <table class="innertable">
 *     <tr>
 *        <th>Characteristic</th>
 *        <th>Description</th>
 *     </tr>
 *     <tr>
 *        <td>Preferred size</td>
 *        <td>Wide enough to contain all buttons with their label text and icons, if any, plus any padding and separators, and high enough to accommodate the button height.</td>
 *     </tr>
 *     <tr>
 *        <td>Control resizing rules</td>
 *        <td>The controls do not resize by default. Specify percentage sizes if you want your ButtonBar to resize based on the size of its parent container.</td>
 *     </tr>
 *     <tr>
 *        <td>Padding</td>
 *        <td>0 pixels for the top, bottom, left, and right properties.</td>
 *     </tr>
 *  </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:ButtonBar&gt;</code> tag inherits all the tag attributes
 *  of its superclass, and adds the following tag attributes:</p>
 *  
 *  <pre>
 *  &lt;mx:ButtonBar
 *    <b>Styles</b>
 *    buttonHeight="undefined"
 *    buttonStyleName="<i>Name of CSS style declaration, which specifies
 *    styles for the buttons</i>"
 *    buttonWidth="undefined"
 *    firstButtonStyleName="<i>The value of</i> <code>buttonStyleName</code>"
 *    horizontalAlign="center|left|right"
 *    horizontalGap="0"
 *    lastButtonStyleName="<i>The value of</i> <code>buttonStyleName</code>"
 *    verticalAlign="middle|top|bottom"
 *    verticalGap="0"
 *     
 *    <b>Events</b>
 *    itemClick="<i>No default</i>"
 *    &gt;
 *    ...
 *       <i>child tags</i>
 *    ...
 *  &lt;/mx:ButtonBar&gt;
 *  </pre>
 *
 *  @see mx.controls.ToggleButtonBar
 *  @see mx.controls.LinkBar
 *  @includeExample examples/ButtonBarExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
 public class ButtonBar extends NavBar implements IFocusManagerComponent
{
    include "../core/Version.as";

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

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

        tabEnabled = true;
        tabFocusEnabled = true;

        navItemFactory = new ClassFactory(ButtonBarButton);

        // Add event listeners for scaleX/scaleY changed.
        // Since we hard-code sizes into our children,
        // scaling can cause rounding errors so we need
        // to clear our hard-coded values whenever the scale changes.
        addEventListener("scaleXChanged", scaleChangedHandler);
        addEventListener("scaleYChanged", scaleChangedHandler);
        
        addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE, 
                         childRemoveHandler);
    }

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

    /**
     *  @private
     *  Internal flag to indicate when a click event has been triggered
     *  programmatically, as opposed to an actual user click.
     *  This happens when the button selection happens by keyboard navigation
     *  or when selectedIndex is set programmatically.
     *  When this is true, the focus rect shouldn't be drawn
     *  for the currently selected button.
     */
    mx_internal var simulatedClickTriggerEvent:Event = null;

    /**
     *  @private
     *  Name of style used to specify buttonStyleName.
     *  Overridden by TabBar.
     */
    mx_internal var buttonStyleNameProp:String = "buttonStyleName";

    /**
     *  @private
     *  Name of style used to specify buttonStyleName.
     *  Overridden by TabBar.
     */
    mx_internal var firstButtonStyleNameProp:String = "firstButtonStyleName";

    /**
     *  @private
     *  Name of style used to specify buttonStyleName.
     *  Overridden by TabBar.
     */
    mx_internal var lastButtonStyleNameProp:String = "lastButtonStyleName";

    /**
     *  @private
     *  Name of style used to specify buttonWidth.
     *  Overridden by TabBar.
     */
    mx_internal var buttonWidthProp:String = "buttonWidth";

    /**
     *  @private
     *  Name of style used to specify buttonHeight.
     *  Overridden by TabBar.
     */
    mx_internal var buttonHeightProp:String = "buttonHeight";

    /**
     *  @private
     *  Flag indicating whether buttons widths should be recalculated.
     */
    private var recalcButtonWidths:Boolean = false;

    /**
     *  @private
     *  Flag indicating whether buttons heights should be recalculated.
     */
    private var recalcButtonHeights:Boolean = false;

    /**
     *  @private
     *  The value of the unscaledWidth parameter during the most recent
     *  call to updateDisplayList
     */
    private var oldUnscaledWidth:Number;

    /**
     *  @private
     *  The value of the unscaledHeight parameter during the most recent
     *  call to updateDisplayList
     */
    private var oldUnscaledHeight:Number;

    /**
     *  @private
     *  Index of currently focused child.
     */
    mx_internal var focusedIndex:int = 0;

    /**
     *  @private
     *  Flag indicating whether direction has changed.
     */
    private var directionChanged:Boolean = false;

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

    //----------------------------------
    //  borderMetrics
    //----------------------------------

    /**
     *  @private
     */
    override public function get borderMetrics():EdgeMetrics
    {
        return EdgeMetrics.EMPTY;
    }

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

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

    /**
     *  @private
     */
    override public function set direction(value:String):void
    {
        if (initialized && value != direction)
        {
            directionChanged = true;
            invalidateProperties();
        }

        super.direction = value;
    }

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

    /**
     *  @private
     */
    override public function get viewMetrics():EdgeMetrics
    {
        return EdgeMetrics.EMPTY;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        var allStyles:Boolean = styleProp == null || styleProp == "styleName";

        super.styleChanged(styleProp);

        if (allStyles ||
            styleProp == buttonStyleNameProp ||
            styleProp == firstButtonStyleNameProp ||
            styleProp == lastButtonStyleNameProp)
        {
            resetNavItems();
        }
        else if (styleProp == buttonWidthProp)
        {
            recalcButtonWidths = true;
        }
        else if (styleProp == buttonHeightProp)
        {
            recalcButtonHeights = true;
        }
        else if (styleManager.isInheritingStyle(styleProp) && 
            styleManager.isSizeInvalidatingStyle(styleProp))
        {
            recalcButtonWidths = recalcButtonHeights = true;
        }        
    }

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

        if (directionChanged)
        {
            directionChanged = false;

            // refresh skins
            var n:int = numChildren;
            for (var i:int = 0; i < n; i++)
                Button(getChildAt(i)).changeSkins();
        }
        
        // Buttons widths and/or heights must be reset before measurement. We do
        // not reset these flags here since they will be used in updateDisplayList().
        if (recalcButtonHeights)
            resetButtonHeights();
        
        if (recalcButtonWidths)
            resetButtonWidths();    
    }

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

        var vm:EdgeMetrics = viewMetricsAndPadding;

        measuredWidth = calcFullWidth() + vm.left + vm.right;
        measuredHeight = calcFullHeight() + vm.top + vm.bottom;

        // If explicit button sizes are specified, our preferred sizes are our
        // minimum sizes.
        if (getStyle(buttonWidthProp))
            measuredMinWidth = measuredWidth;
        if (getStyle(buttonHeightProp))
            measuredMinHeight = measuredHeight;

    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        // We pre-process our child sizes, so we call super.updateDisplayList() later.
        
        const isHorizontal:Boolean = (direction == BoxDirection.HORIZONTAL);
        const isVertical:Boolean = !isHorizontal;

        var buttonWidth:Number = getStyle(buttonWidthProp);
        var buttonHeightStyle:Number = getStyle(buttonHeightProp);
        var buttonHeight:Number = buttonHeightStyle;

        var vm:EdgeMetrics = viewMetricsAndPadding;

        var n:int = numChildren;
        var horizontalGap:Number = getStyle("horizontalGap");
        var verticalGap:Number = getStyle("verticalGap");
        var totalHorizontalGap:Number = isHorizontal && numChildren > 0 ? 
        								horizontalGap * (n - 1) : 0;
        var totalVerticalGap:Number = isVertical && numChildren > 0 ? 
        							  verticalGap * (n - 1) : 0;
        var w:Number = unscaledWidth - vm.left - vm.right - totalHorizontalGap;
        var h:Number = unscaledHeight - vm.top - vm.bottom - totalVerticalGap;
        if (!w || !h)
            return;

        if (border)
            border.visible = false;

        if (unscaledWidth != oldUnscaledWidth)
        {
            recalcButtonWidths = true;
            oldUnscaledWidth = unscaledWidth;
        }

        if (unscaledHeight != oldUnscaledHeight)
        {
            recalcButtonHeights = true;
            oldUnscaledHeight = unscaledHeight;
        }

        var i:int;
        var c:Button;

        var excessSpace:Number;

        // See if we need to recalculate the button widths
        if (recalcButtonWidths)
        {
            recalcButtonWidths = false;

            if (isNaN(buttonWidth) && isVertical)
                buttonWidth = w;

            excessSpace = w - (calcFullWidth() - totalHorizontalGap);
            var averageWidth:int = n > 0 ? w / n : 0;
            // Number of children larger than average width
            var nLarge:int = 0;

            // Sum of all preferred widths (required if excessSpace != 0)
            var tw:Number = 0;
            // Sum of all preferred widths of children
            // smaller than average width.
            var tSmall:int = 0;
            if (excessSpace != 0 && isHorizontal)
            {
                for (i = 0; i < n; i++)
                {
                    c = Button(getChildAt(i));
                    if (isNaN(c.explicitWidth))
                    {
                        var mw:int = c.measuredWidth;
                        tw += mw;
                        if (mw > averageWidth)
                            nLarge++;
                        else
                            tSmall += mw;
                    }
                }
            }
            else
            {
                tw = w;
            }

            for (i = 0; i < n; i++)
            {
                c = Button(getChildAt(i));
                if (isNaN(c.explicitWidth))
                {
                    c.minWidth = 0;
                    if (!isNaN(buttonWidth))
                    {
                            c.minWidth = c.maxWidth = buttonWidth;
                            c.percentWidth = buttonWidth / Math.min(w, tw) * 100;
                    }

                    // Assign measured width to children smaller than average.
                    // Distribute the remaining width to others.
                    else if (excessSpace < 0)
                    {
                        var assignedWidth:Number = c.measuredWidth;
                        if (assignedWidth > averageWidth)
                            assignedWidth = (w - tSmall) / nLarge;

                        c.percentWidth = assignedWidth / w * 100;
                    }

                    // If they fit comfortably with extra space left,
                    // expand them.
                    else if (excessSpace > 0)
                    {
                        c.percentWidth = c.measuredWidth / tw * 100;
                    }

                    else
                    {
                        c.percentWidth = NaN;
                    }

                    // If vertical, expand to fit horizontally.
                    if (isVertical)
                        c.percentWidth = 100;
                }
            }
        }

        // See if we need to recalculate the button heights
        if (recalcButtonHeights)
        {
            recalcButtonHeights = false;

            if (isNaN(buttonHeight) && isHorizontal)
                buttonHeight = h;

            excessSpace = h - (calcFullHeight() - totalVerticalGap);

            // Sum of all preferred heights (required if excessSpace != 0).
            var th:Number = 0;
            if (excessSpace != 0 && isVertical)
            {
                for (i = 0; i < n; i++)
                {
                    c = Button(getChildAt(i));
                    if (isNaN(c.explicitHeight))
                        th += c.measuredHeight;
                }
            }

            for (i = 0; i < n; i++)
            {
                c = Button(getChildAt(i));
                if (isNaN(c.explicitHeight))
                {
                    c.minHeight = 0;
                    if (!isNaN(buttonHeight))
                    {
                        c.minHeight = buttonHeight;
                        c.percentHeight = buttonHeight / Math.min(th, h) * 100;
                    }
                    if (!isNaN(buttonHeightStyle))
                        c.maxHeight = buttonHeightStyle;

                    // If horizontal, expand to fit vertically.
                    if (isHorizontal)
                        c.percentHeight = 100;

                    // If they won't fit, squeeze them in.
                    else if (excessSpace < 0)
                        c.percentHeight = c.measuredHeight / th * 100;

                    // If they fit comfortably with extra space left,
                    // expand them.
                    else if (excessSpace > 0)
                        c.percentHeight = c.measuredHeight / th * 100;

                    else
                        c.percentHeight = NaN;
                }
            }
        }
        
        // Since we pre-process our child dimensions, we call super.updateDisplayList()
        // last.
        super.updateDisplayList(unscaledWidth, unscaledHeight);
    }

    /**
     *  @private
     */
    override public function drawFocus(isFocused:Boolean):void
    {
        drawButtonFocus(focusedIndex, isFocused);
    }

    /**
     *  @private
     */
    override protected function createNavItem(
                                        label:String,
                                        icon:Class = null):IFlexDisplayObject
    {
        var newButton:Button = Button(navItemFactory.newInstance());

        // Set focusEnabled to false so individual buttons don't get focus.
        newButton.focusEnabled = false;
        newButton.label = label;
        newButton.setStyle("icon", icon);
        newButton.addEventListener(MouseEvent.CLICK, clickHandler);

        addChild(newButton);

        recalcButtonWidths = recalcButtonHeights = true;

        return newButton;
    }

    /**
     *  @private
     */
    override protected function resetNavItems():void
    {
        var buttonStyleName:String = getStyle(buttonStyleNameProp);
        var firstButtonStyleName:String = getStyle(firstButtonStyleNameProp);
        var lastButtonStyleName:String = getStyle(lastButtonStyleNameProp);

        if (!buttonStyleName)
            buttonStyleName = "ButtonBarButton";
        if (!firstButtonStyleName)
            firstButtonStyleName = buttonStyleName;
        if (!lastButtonStyleName)
            lastButtonStyleName = buttonStyleName;

        var button:Button;
        var n:int = numChildren;
        for (var i:int = 0; i < n; i++)
        {
            button = Button(getChildAt(i));
            if (i == 0)
            {
                button.styleName = firstButtonStyleName;
            }
            else if (i == (n - 1))
            {
                button.styleName = lastButtonStyleName;
            }
            else
            {
                button.styleName = buttonStyleName;
            }

            button.changeSkins();
            button.invalidateDisplayList();
        }

        recalcButtonWidths = recalcButtonHeights = true;

        invalidateDisplayList();
    }

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

    /**
     *  @private
     */
    private function calcFullWidth():Number
    {
        var n:int = numChildren;
        var gap:Number = 0;

        if (n == 0)
            return 0;
        else if (n > 1)
            gap = getStyle("horizontalGap");

        var horizontal:Boolean = (direction == BoxDirection.HORIZONTAL);

        var buttonWidth:Number = getStyle(buttonWidthProp);

        var child:IUIComponent = IUIComponent(getChildAt(0));

        var w:Number;
        if (buttonWidth)
            w = isNaN(child.explicitWidth) ? buttonWidth : child.explicitWidth;
        else
            w = child.getExplicitOrMeasuredWidth();

        for (var i:int = 1; i < n; i++)
        {
            child = IUIComponent(getChildAt(i));

            var cw:Number;
            if (buttonWidth)
            {
                cw = isNaN(child.explicitWidth) ?
                     buttonWidth :
                     child.explicitWidth;
            }
            else
            {
                cw = child.getExplicitOrMeasuredWidth();
            }

            if (horizontal)
                w += (gap + cw);
            else
                w = Math.max(w, cw);
        }

        return w;
    }

    /**
     *  @private
     */
    private function calcFullHeight():Number
    {
        var n:int = numChildren;
        var gap:Number;

        if (n == 0)
            return 0;
        else if (n > 1)
            gap = getStyle("verticalGap");

        var vertical:Boolean = (direction == BoxDirection.VERTICAL);

        var buttonHeight:Number = getStyle(buttonHeightProp);

        var child:IUIComponent = IUIComponent(getChildAt(0));

        var h:Number;
        if (buttonHeight)
        {
            h = isNaN(child.explicitHeight) ?
                buttonHeight :
                child.explicitHeight;
        }
        else
        {
            h = child.getExplicitOrMeasuredHeight();
        }

        for (var i:int = 1; i < n; i++)
        {
            child = IUIComponent(getChildAt(i));

            var ch:Number;
            if (buttonHeight)
            {
                ch = isNaN(child.explicitHeight) ?
                     buttonHeight :child.explicitHeight;
            }
            else
            {
                ch = child.getExplicitOrMeasuredHeight();
            }

            if (vertical)
                h += (gap + ch);
            else
                h = Math.max(h, ch);
        }

        return h;
    }

    /**
     *  @private
     *  Returns the previous valid child index, or -1 if there are no children.
     *  Used by keyboard navigation.
     */
    mx_internal function prevIndex(index:int):int
    {
        var n:int = numChildren;
        return index == 0 ? n - 1 : index - 1;
    }

    /**
     *  @private
     *  Returns the next valid child index, or -1 if there are no children.
     *  Used by keyboard navigation.
     */
    mx_internal function nextIndex(index:int):int
    {
        var n:int = numChildren;
        if (n == 0)
            return -1;
        else
            return index == n - 1 ? 0 : index + 1;
    }

    /**
     *  @private
     */
    mx_internal function drawButtonFocus(index:int, focused:Boolean):void
    {
        if (numChildren > 0 && index < numChildren)
        {
            var b:Button = Button(getChildAt(index));
            b.drawFocus(focused && focusManager.showFocusIndicator);

            // internal event for accessibility
            if (focused)
                dispatchEvent(new Event("focusDraw"));

            // If the button is losing focus, set its phase to UP,
            // which will cause a redraw.
            if (!focused && b.phase != ButtonPhase.UP)
                b.phase = ButtonPhase.UP;
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden event handlers: UIComponent
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function keyDownHandler(event:KeyboardEvent):void
    {
        // Ignore events that bubble up from the child ButtonBarButtons.
        // such as the one we redispatch below from the focused child
        // when the SPACE key is released.
        if (event.eventPhase != EventPhase.AT_TARGET)
            return;

        // If rtl layout, need to swap LEFT and RIGHT so correct action
        // is done.
        var keyCode:uint = mapKeycodeForLayoutDirection(event, true);
        
        switch (keyCode)
        {
            case Keyboard.DOWN:
            case Keyboard.RIGHT:
            {
                focusManager.showFocusIndicator = true;
                drawButtonFocus(focusedIndex, false);
                focusedIndex = nextIndex(focusedIndex);

                if (focusedIndex != -1)
                {
                    drawButtonFocus(focusedIndex, true);
                }

                event.stopPropagation();
                break;
            }

            case Keyboard.UP:
            case Keyboard.LEFT:
            {
                focusManager.showFocusIndicator = true;
                drawButtonFocus(focusedIndex, false);
                focusedIndex = prevIndex(focusedIndex);

                if (focusedIndex != -1)
                {
                    drawButtonFocus(focusedIndex, true);
                }
 
                event.stopPropagation();
                break;
            }

            case Keyboard.SPACE:
            {
                if (focusedIndex != -1)
                {
                    // Redispatch from the focused ButtonBarButton
                    // to get it to appear pressed.
                    var child:Button = Button(getChildAt(focusedIndex));
                    child.dispatchEvent(event);
                }

                event.stopPropagation();
                break;
            }
        }
    }

    /**
     *  @private
     */
    override protected function keyUpHandler(event:KeyboardEvent):void
    {
        // Ignore events that bubble up from the child ButtonBarButtons.
        // such as the one we redispatch below from the focused child
        // when the SPACE key is released.
        if (event.eventPhase != EventPhase.AT_TARGET)
            return;

        switch (event.keyCode)
        {
            case Keyboard.SPACE:
            {
                if (focusedIndex != -1)
                {
                    // Redispatch from the focused ButtonBarButton
                    // to get it to appear released.
                    var child:Button = Button(getChildAt(focusedIndex));
                    child.dispatchEvent(event);
                }

                event.stopPropagation();
                break;
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden event handlers: NavBar
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function clickHandler(event:MouseEvent):void
    {
        if (simulatedClickTriggerEvent == null)
        {
            focusedIndex = getChildIndex(DisplayObject(event.currentTarget));
            drawButtonFocus(focusedIndex, true);
        }

        super.clickHandler(event);
    }

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

    /**
     *  @private
     */
    private function childRemoveHandler(event:ChildExistenceChangedEvent):void
    {   
        var child:DisplayObject = event.relatedObject;
        var index:int = getChildIndex(child);
        var n:int = numChildren;
        if (n < 2)
        {
            // Don't bother if it's the last child.
            return;
        }

        var buttonStyleName:String = getStyle(buttonStyleNameProp);
        var firstButtonStyleName:String = getStyle(firstButtonStyleNameProp);
        var lastButtonStyleName:String = getStyle(lastButtonStyleNameProp);

        if (!buttonStyleName)
            buttonStyleName = "buttonBarButtonStyle";
        if (!firstButtonStyleName)
            firstButtonStyleName = buttonStyleName;
        if (!lastButtonStyleName)
            lastButtonStyleName = buttonStyleName;

        // Refresh the skins for the last button that was in this position.
        if (index == 0 || index == n - 1)
        {
            var button:Button = Button(getChildAt(index == n - 1 ? n - 2 : 0));
            
            button.styleName = index == 0 ?
                               firstButtonStyleName :
                               lastButtonStyleName;
            
            button.changeSkins();
            button.invalidateDisplayList();
        }
    }

    /**
     *  @private
     *  Reset buttons widths so that it can be recalculated.
     */
    protected function resetButtonWidths():void
    {
        for (var i:int = 0; i < numChildren; i++)
        {
            var child:Button = getChildAt(i) as Button;
            if (child)
            {
                child.explicitWidth = NaN;
                child.minWidth = NaN;
                child.maxWidth = NaN;
            }
        }
    }

    /**
     *  @private
     *  Reset buttons heights so that it can be recalculated.
     */
    protected function resetButtonHeights():void
    {
        for (var i:int = 0; i < numChildren; i++)
        {
            var child:Button = getChildAt(i) as Button;
            if (child)
            {
                child.explicitHeight = NaN;
                child.minHeight = NaN;
                child.maxHeight = NaN;
            }
        }
    }

    /**
     *  @private
     */
    private function scaleChangedHandler(event:Event):void
    {
    	// This is called whenever scaleX or scaleY is changed.
        // We need to clear out the preferredWidth/preferredHeight
        // of our children since scaling can cause rounding errors
        // which then are not corrected when un-scaled.  
        resetButtonHeights();
        resetButtonWidths();
    }
}

}
