////////////////////////////////////////////////////////////////////////////////
//
//  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.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.text.TextFormatAlign;
import flash.text.TextLineMetrics;
import flash.ui.Keyboard;
import flash.utils.Timer;

import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.EdgeMetrics;
import mx.core.FlexVersion;
import mx.core.IBorder;
import mx.core.IButton;
import mx.core.IDataRenderer;
import mx.core.IFlexAsset;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IFontContextComponent;
import mx.core.IInvalidating;
import mx.core.ILayoutDirectionElement;
import mx.core.IProgrammaticSkin;
import mx.core.IStateClient;
import mx.core.IUIComponent;
import mx.core.IUITextField;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.MoveEvent;
import mx.events.SandboxMouseEvent;
import mx.managers.IFocusManagerComponent;
import mx.styles.ISimpleStyleClient;


use namespace mx_internal;

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

/**
 *  Dispatched when the user presses the Button control.
 *  If the <code>autoRepeat</code> property is <code>true</code>,
 *  this event is dispatched repeatedly as long as the button stays down.
 *
 *  @eventType mx.events.FlexEvent.BUTTON_DOWN
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="buttonDown", type="mx.events.FlexEvent")]

/**
 *  Dispatched when the <code>selected</code> property 
 *  changes for a toggle Button control. A toggle Button control means that the 
 *  <code>toggle</code> property is set to <code>true</code>. 
 * 
 *  For the RadioButton controls, this event is dispatched when the <code>selected</code> 
 *  property changes.
 * 
 *  For the CheckBox controls, this event is dispatched only when the 
 *  user interacts with the control by using the mouse.
 *
 *  @eventType flash.events.Event.CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="change", type="flash.events.Event")]

/**
 *  Dispatched when the <code>data</code> property changes.
 *
 *  <p>When you use a component as an item renderer,
 *  the <code>data</code> property contains the data to display.
 *  You can listen for this event and update the component
 *  when the <code>data</code> property changes.</p>
 * 
 *  @eventType mx.events.FlexEvent.DATA_CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="dataChange", type="mx.events.FlexEvent")]

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

include "../styles/metadata/FocusStyles.as"
include "../styles/metadata/LeadingStyle.as"
include "../styles/metadata/PaddingStyles.as"
include "../styles/metadata/SkinStyles.as"
include "../styles/metadata/TextStyles.as"

/**
 *  Color applied to the button when the emphasized flag is true. 
 * 
 *  @default #0099FF
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="accentColor", type="uint", format="Color", inherit="yes", theme="spark")]

/**
 *  Color of focus ring when the component is in focus
 *   
 *  @default 0x70B2EE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */ 
[Style(name="focusColor", type="uint", format="Color", inherit="yes", theme="spark")]

/**
 *  Gap between the label and icon, when the <code>labelPlacement</code> property
 *  is set to <code>left</code> or <code>right</code>.
 * 
 *  @default 2
 *  
 *  @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 of vertical offset to apply to the label position.
 *  Positive numbers move the label down.
 *  
 *  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 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="labelVerticalOffset", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the component's bottom border
 *  and the bottom of its content area.
 *  
 *  The default value for the Halo theme is <code>2</code>.
 *  The default value for the Spark theme is <code>0</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the component's top border
 *  and the top of its content area.
 *  
 *  The default value for the Halo theme is <code>2</code>.
 *  The default value for the Spark theme is <code>0</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

/**
 *  Number of milliseconds to wait after the first <code>buttonDown</code>
 *  event before repeating <code>buttonDown</code> events at each 
 *  <code>repeatInterval</code>.
 * 
 *  @default 500
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="repeatDelay", type="Number", format="Time", inherit="no")]

/**
 *  Number of milliseconds between <code>buttonDown</code> events
 *  if the user presses and holds the mouse on a button.
 *  
 *  @default 35
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="repeatInterval", type="Number", format="Time", inherit="no")]

/**
 *  Text color of the label as the user moves the mouse pointer over the button.
 *  
 *  The default value for the Halo theme is <code>0x2B333C</code>.
 *  The default value for the Spark theme is <code>0x000000</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="textRollOverColor", type="uint", format="Color", inherit="yes")]

/**
 *  Text color of the label as the user presses it.
 *  
 *  The default value for the Halo theme is <code>0x2B333C</code>.
 *  The default value for the Spark theme is <code>0x000000</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="textSelectedColor", type="uint", format="Color", inherit="yes")]

/**
 *  Gap between the button's label and icon when the <code>labelPlacement</code>
 *  property is set to <code>"top"</code> or <code>"bottom"</code>.
 * 
 *  @default 2
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="verticalGap", type="Number", format="Length", inherit="no")]

//--------------------------------------
//  Skins
//--------------------------------------

/**
 *  Name of the class to use as the default skin for the background and border.
 *  
 *  The default value for the Halo theme is <code>mx.skins.halo.ButtonSkin</code>.
 *  The default value for the Spark theme is <code>mx.skins.spark.ButtonSkin</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="skin", type="Class", inherit="no", states="up, over, down, disabled, selectedUp, selectedOver, selectedDown, selectedDisabled")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when the button is not selected and the mouse is not over the control.
 *  
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="upSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when the button is not selected and the mouse is over the control.
 *  
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="overSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when the button is not selected and the mouse button is down.
 *  
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="downSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when the button is not selected and is disabled.
 * 
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="disabledSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the button when the button
 *  is <code>emphasized</code> (such as when serving as the default
 *  button for a container).
 * 
 *  The default value for the Halo theme is <code>mx.skins.halo.ButtonSkin</code>.
 *  The default value for the Spark theme is <code>mx.skins.spark.DefaultButtonSkin</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="emphasizedSkin", type="Class", inherit="no", states="up, over, down, disabled, selectedUp, selectedOver, selectedDown, selectedDisabled")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when a toggle button is selected and the mouse is not over the control.
 * 
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedUpSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when a toggle button is selected and the mouse is over the control.
 *  
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedOverSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when a toggle button is selected and the mouse button is down.
 *  
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedDownSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the skin for the background and border
 *  when a toggle button is selected and disabled.
 * 
 *  <p>The default skin class is based on the theme. For example, with the Halo theme,
 *  the default skin class is <code>mx.skins.halo.ButtonSkin</code>. For the Spark theme, the default skin
 *  class is <code>mx.skins.spark.ButtonSkin</code>.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedDisabledSkin", type="Class", inherit="no")]

/**
 *  Name of the class to use as the default icon. 
 *  Setting any other icon style overrides this setting.
 *  
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="icon", type="Class", inherit="no", states="up, over, down, disabled, selectedUp, selectedOver, selectedDown, selectedDisabled")]

/**
 *  Name of the class to use as the icon when a toggle button is not 
 *  selected and the mouse is not over the button.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="upIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon when the button is not 
 *  selected and the mouse is over the control.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="overIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon when the button is not 
 *  selected and the mouse button is down.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="downIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon
 *  when the button is disabled and not selected.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="disabledIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon
 *  when the button is selected and the mouse button is up.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedUpIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon
 *  when the button is selected and the mouse is over the control.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedOverIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon
 *  when the button is selected and the mouse button is down.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedDownIcon", type="Class", inherit="no")]

/**
 *  Name of the class to use as the icon
 *  when the button is selected and disabled.
 * 
 *  @default null 
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectedDisabledIcon", type="Class", inherit="no")]

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

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

[DefaultBindingProperty(source="selected", destination="label")]

[DefaultTriggerEvent("click")]

[IconFile("Button.png")]

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

/**
 *  The Button control is a commonly used rectangular button.
 *  Button controls look like they can be pressed.
 *  They can have a text label, an icon, or both on their face.
 *
 *  <p>Buttons typically use event listeners to perform an action 
 *  when the user selects the control. When a user clicks the mouse 
 *  on a Button control, and the Button control is enabled, 
 *  it dispatches a <code>click</code> event and a <code>buttonDown</code> event. 
 *  A button always dispatches events such as the <code>mouseMove</code>, 
 *  <code>mouseOver</code>, <code>mouseOut</code>, <code>rollOver</code>, 
 *  <code>rollOut</code>, <code>mouseDown</code>, and 
 *  <code>mouseUp</code> events whether enabled or disabled.</p>
 *
 *  <p>You can customize the look of a Button control
 *  and change its functionality from a push button to a toggle button.
 *  You can change the button appearance by using a skin
 *  for each of the button's states.</p>
 *
 *  <p>The label of a Button control uses a bold typeface. If you embed 
 *  a font that you want to use for the label of the Button control, you must 
 *  embed the bold typeface; for example:</p>
 * 
 *  <pre>
 *  &lt;fx:style&gt;
 *    &#64;font-face {
 *      src:url("../MyFont-Bold.ttf");        
 *      fontFamily: myFont;
 *      fontWeight: bold;
 *    }
 *   .myBoldStyle {
 *      fontFamily: myFont;
 *      fontWeight: bold;
 *    } 
 *  &lt;/fx:style&gt;
 *  ...
 *  &lt;mx:Button ... styleName="myBoldStyle"/&gt;
 *  </pre>
 *  
 *  <p>The Button control has the following default characteristics:</p>
 *  <table class="innertable">
 *     <tr><th>Characteristic</th><th>Description</th></tr>
 *     <tr><td>Default size</td><td>A size large enough to hold the label text, and any icon</td></tr>
 *     <tr><td>Minimum size</td><td>0 pixels</td></tr>
 *     <tr><td>Maximum size</td><td>No limit</td></tr>
 *  </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:Button&gt;</code> tag inherits all the tag attributes
 *  of its superclass, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:Button
 *    <b>Properties</b>
 *    autoRepeat="false|true"
 *    emphasized="false|true"
 *    fontContext="<i>IFontModuleFactory</i>"
 *    label=""
 *    labelPlacement="right|left|bottom|top"
 *    selected="false|true"
 *    selectedField="null"
 *    stickyHighlighting="false|true"
 *    toggle="false|true"
 * 
 *    <b>Styles</b>
 *    borderColor="0xAAB3B3"
 *    color="0x0B333C"
 *    cornerRadius="4"
 *    disabledColor="0xAAB3B3"
 *    disabledIcon="null"
 *    disabledSkin="mx.skins.halo.ButtonSkin"
 *    downIcon="null"
 *    downSkin="mx.skins.halo.ButtonSkin"
 *    fillAlphas="[0.6, 0.4]"
 *    fillColors="[0xE6EEEE, 0xFFFFFF]"
 *    focusAlpha="0.5"
 *    focusRoundedCorners"tl tr bl br"
 *    fontAntiAliasType="advanced"
 *    fontFamily="Verdana"
 *    fontGridFitType="pixel"
 *    fontSharpness="0"
 *    fontSize="10"
 *    fontStyle="normal|italic"
 *    fontThickness="0"
 *    fontWeight="bold|normal"
 *    highlightAlphas="[0.3, 0.0]"
 *    horizontalGap="2"
 *    icon="null"
 *    kerning="false|true"
 *    leading="2"
 *    letterSpacing="0"
 *    overIcon="null"
 *    overSkin="mx.skins.halo.ButtonSkin"
 *    paddingBottom="2"
 *    paddingLeft="0"
 *    paddingRight="0"
 *    paddingTop="2"
 *    repeatDelay="500"
 *    repeatInterval="35"
 *    selectedDisabledIcon="null"
 *    selectedDisabledSkin="mx.skins.halo.ButtonSkin"
 *    selectedDownIcon="null"
 *    selectedDownSkin="mx.skins.halo.ButtonSkin"
 *    selectedOverIcon="null"
 *    selectedOverSkin="mx.skins.halo.ButtonSkin"
 *    selectedUpIcon="null"
 *    selectedUpSkin="mx.skins.halo.ButtonSkin"
 *    skin="mx.skins.halo.ButtonSkin"
 *    textAlign="center|left|right"
 *    textDecoration="none|underline"
 *    textIndent="0"
 *    textRollOverColor="0x2B333C"
 *    textSelectedColor="0x000000"
 *    upIcon="null"
 *    upSkin="mx.skins.halo.ButtonSkin"
 *    verticalGap="2"
 * 
 *    <b>Events</b>
 *    buttonDown="<i>No default</i>"
 *    change="<i>No default</i>"
 *    dataChange="<i>No default</i>"
 *  /&gt;
 *  </pre>
 *
 *  @includeExample examples/ButtonExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class Button extends UIComponent
       implements IDataRenderer, IDropInListItemRenderer,
       IFocusManagerComponent, IListItemRenderer,
       IFontContextComponent, IButton
{
    include "../core/Version.as";

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

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

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

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

        // DisplayObjectContainer properties.
        // Setting mouseChildren to false ensure that mouse events
        // are dispatched from the Button itself,
        // not from its skins, icons, or TextField.
        // One reason for doing this is that if you press the mouse button
        // while over the TextField and release the mouse button while over
        // a skin or icon, we want the player to dispatch a "click" event.
        // Another is that if mouseChildren were true and someone uses
        // Sprites rather than Shapes for the skins or icons,
        // then we we wouldn't get a click because the current skin or icon
        // changes between the mouseDown and the mouseUp.
        // (This doesn't happen even when mouseChildren is true if the skins
        // and icons are Shapes, because Shapes never dispatch mouse events;
        // they are dispatched from the Button in this case.)
        mouseChildren = false;

        // Register for player events.
        addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
        addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
        addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        addEventListener(MouseEvent.CLICK, clickHandler);
    }

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

    /**
     *  @private
     *  Skins for the various states (falseUp, trueOver, etc.)
     *  are created just-in-time as they are needed.
     *  Each skin is a child Sprite of this Button.
     *  Each skin has a name property indicating which skin it is;
     *  for example, the instance of the class specified by the falseUpSkin
     *  style has the name "falseUpSkin" and can be found using
     *  getChildByName(). Note that there is no falseUpSkin property
     *  of Button containing a reference to this skin instance.
     *  This array contains references to all skins that have been created,
     *  for looping over them; without this array we wouldn't know
     *  which of the children are the skins.
     *  New skins are created and added to this array in viewSkin().
     */
    private var skins:Array /* of Sprite */ = [];

    /**
     *  @private
     *  A reference to the current skin.
     *  Set by viewSkin().
     */
    mx_internal var currentSkin:IFlexDisplayObject;

    /**
     *  The icons array contains references to all icons
     *  that have been created. Since each icon is a child
     *  Sprite of this button, we need this array to keep
     *  track of which children are icons. Each icon has a 
     *  name property indicating which icon it is; for example,
     *  the instance of the class specified by the falseUpIcon
     *  style has the name "falseUpIcon" and can be found using
     *  getChildByName(). Note that there is no falseUpIcon property
     *  of Button containing a reference to this icon instance.
     *  New icons are created and added to this array in viewIcon().
     * 
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var icons:Array /* of Sprite */ = [];

    /**
     *  @private
     *  A reference to the current icon.
     *  Set by viewIcon().
     */
    mx_internal var currentIcon:IFlexDisplayObject;

    /**
     *  @private
     *  Timer for doing auto-repeat.
     */
    private var autoRepeatTimer:Timer;

    /**
     *  @private
     *  Number used to offset the label and/or icon
     *  when button is pressed.
     */
    mx_internal var buttonOffset:Number = 0;
    
    /**
     *  @private
     *  used by old measure/layout logic
     */
    mx_internal var centerContent:Boolean = true;

    /**
     *  @private
     *  used by old measure/layout logic
     */
    mx_internal var extraSpacing:Number = 10 + 10;
    
     /**
     *  @private
     */
    mx_internal static var TEXT_WIDTH_PADDING:Number = UITextField.TEXT_WIDTH_PADDING + 1;

    /**
     *  @private
     */
    private var styleChangedFlag:Boolean = true;

    /**
     *  @private
     *  The measured width of the first skin loaded.
     */
    private var skinMeasuredWidth:Number;

    /**
     *  @private
     *  The measured height of the first skin loaded.
     */
    private var skinMeasuredHeight:Number;

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

    /**
     *  @private
     *  Flags that will block default data/listData behavior
     */
    private var selectedSet:Boolean;
    private var labelSet:Boolean;

    /**
     *  @private
     *  Flags used to save information about the skin and icon styles
     */
    mx_internal var checkedDefaultSkin:Boolean = false;
    mx_internal var defaultSkinUsesStates:Boolean = false;  
    mx_internal var checkedDefaultIcon:Boolean = false;
    mx_internal var defaultIconUsesStates:Boolean = false;

    /**
     *  @private
     *  Skin names.
     *  Allows subclasses to re-define the skin property names.
     */
    mx_internal var skinName:String = "skin"; 
    mx_internal var emphasizedSkinName:String = "emphasizedSkin"; 
    mx_internal var upSkinName:String = "upSkin";
    mx_internal var overSkinName:String = "overSkin";
    mx_internal var downSkinName:String = "downSkin";
    mx_internal var disabledSkinName:String = "disabledSkin";
    mx_internal var selectedUpSkinName:String = "selectedUpSkin";
    mx_internal var selectedOverSkinName:String = "selectedOverSkin";
    mx_internal var selectedDownSkinName:String = "selectedDownSkin";
    mx_internal var selectedDisabledSkinName:String = "selectedDisabledSkin";

    /**
     *  @private
     *  Icon names.
     *  Allows subclasses to re-define the icon property names.
     */
    mx_internal var iconName:String = "icon";
    mx_internal var upIconName:String = "upIcon";
    mx_internal var overIconName:String = "overIcon";
    mx_internal var downIconName:String = "downIcon";
    mx_internal var disabledIconName:String = "disabledIcon";
    mx_internal var selectedUpIconName:String = "selectedUpIcon";
    mx_internal var selectedOverIconName:String = "selectedOverIcon";
    mx_internal var selectedDownIconName:String = "selectedDownIcon";
    mx_internal var selectedDisabledIconName:String = "selectedDisabledIcon";

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

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

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

        return textField.y + textField.baselinePosition;
    }

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

    /**
     *  @private
     */
    private var enabledChanged:Boolean = false;

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

    /**
     *  @private
     *  This is called whenever the enabled state changes.
     */
    override public function set enabled(value:Boolean):void
    {
        if (super.enabled == value)
            return;

        super.enabled = value;
        enabledChanged = true;

        invalidateProperties();
        invalidateDisplayList();
    }

    //----------------------------------
    //  textField
    //----------------------------------

    /**
     *  The internal UITextField object that renders the label of this Button.
     * 
     *  @default null 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var textField:IUITextField;

    //----------------------------------
    //  toolTip
    //----------------------------------

    /**
     *  @private
     */
    private var toolTipSet:Boolean = false;

    [Inspectable(category="General", defaultValue="null")]

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

        if (value)
        {
            toolTipSet = true;
        }
        else
        {
            toolTipSet = false;
            invalidateDisplayList();
        }
    }

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

    //----------------------------------
    //  autoRepeat
    //----------------------------------

    /**
     *  @private
     *  Storage for the autoRepeat property.
     */
    private var _autoRepeat:Boolean = false;

    [Inspectable(defaultValue="false")]

    /**
     *  Specifies whether to dispatch repeated <code>buttonDown</code>
     *  events if the user holds down the mouse button.
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get autoRepeat():Boolean
    {
        return _autoRepeat;
    }

    /**
     *  @private
     */
    public function set autoRepeat(value:Boolean):void
    {
        _autoRepeat = value;

        if (value)
        {
            // Create a Timer object for driving the autorepeat.
            // The duration gets set in mouseDownHandler and reset
            // in autoRepeatTimer_timerDelayHandler, because
            // there is a delay before the first autorepeat
            // and then a possibly different interval
            // between subsequent ones.
            autoRepeatTimer = new Timer(1);
        }
        else
        {
            autoRepeatTimer = null;
        }
    }

    //----------------------------------
    //  data
    //----------------------------------

    /**
     *  @private
     *  Storage for the data property;
     */
    private var _data:Object;

    [Bindable("dataChange")]
    [Inspectable(environment="none")]

    /**
     *  The <code>data</code> property lets you pass a value
     *  to the component when you use it as an item renderer or item editor.
     *  You typically use data binding to bind a field of the <code>data</code>
     *  property to a property of this component.
     *
     *  <p>When you use the control as a drop-in item renderer or drop-in
     *  item editor, Flex automatically writes the current value of the item
     *  to the <code>selected</code> property of this control.</p>
     *
     *  <p>You do not set this property in MXML.</p>
     *
     *  @default null
     *  @see mx.core.IDataRenderer
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get data():Object
    {
        return _data;
    }

    /**
     *  @private
     */
    public function set data(value:Object):void
    {
        var newSelected:*;
        var newLabel:*;

        _data = value;

        if (_listData && _listData is DataGridListData && 
            DataGridListData(_listData).dataField !=null)
        {
            newSelected = _data[DataGridListData(_listData).dataField];

            newLabel = "";
        }
        else if (_listData)
        {
            if (selectedField)
                newSelected = _data[selectedField];

            newLabel = _listData.label;
        }
        else
        {
            newSelected = _data;
        }

        if (newSelected !== undefined && !selectedSet)
        {
            selected = newSelected as Boolean;
            selectedSet = false;
        }
        if (newLabel !== undefined && !labelSet)
        {
            label = newLabel;
            labelSet = false;
        }

        dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
    }

    //----------------------------------
    //  emphasized
    //----------------------------------

    /**
     *  @private
     *  Storage for the emphasized property.
     */
    mx_internal var _emphasized:Boolean = false;

    /**
     *  @private
     */
    private var emphasizedChanged:Boolean = false;


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

    /**
     *  Draws a thick border around the Button control
     *  when the control is in its up state if <code>emphasized</code>
     *  is set to <code>true</code>. 
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get emphasized():Boolean
    {
        return _emphasized;
    }

    /**
     *  @private
     */
    public function set emphasized(value:Boolean):void
    {
        _emphasized = value;
        emphasizedChanged = true;        

        invalidateDisplayList();
    }

    //----------------------------------
    //  fontContext
    //----------------------------------
    
    /**
     *  @inheritDoc 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get fontContext():IFlexModuleFactory
    {
        return moduleFactory;
    }

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

    /**
     *  @private
     *  Storage for label property.
     */
    private var _label:String = "";

    /**
     *  @private
     */
    private var labelChanged:Boolean = false;

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

    /**
     *  Text to appear on the Button control.
     *
     *  <p>If the label is wider than the Button control,
     *  the label is truncated and terminated by an ellipsis (...).
     *  The full label displays as a tooltip
     *  when the user moves the mouse over the Button control.
     *  If you have also set a tooltip by using the <code>tooltip</code>
     *  property, the tooltip is displayed rather than the label text.</p>
     *
     *  @default ""
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get label():String
    {
        return _label;
    }

    /**
     *  @private
     */
    public function set label(value:String):void
    {
        labelSet = true;

        if (_label != value)
        {
            _label = value;
            labelChanged = true;

            invalidateSize();
            invalidateDisplayList();

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

    //----------------------------------
    //  labelPlacement
    //----------------------------------

    /**
     *  @private
     *  Storage for labelPlacement property.
     */
    mx_internal var _labelPlacement:String = ButtonLabelPlacement.RIGHT;

    [Bindable("labelPlacementChanged")]
    [Inspectable(category="General", enumeration="left,right,top,bottom", defaultValue="right")]

    /**
     *  Orientation of the label in relation to a specified icon.
     *  Valid MXML values are <code>right</code>, <code>left</code>,
     *  <code>bottom</code>, and <code>top</code>.
     *
     *  <p>In ActionScript, you can use the following constants
     *  to set this property:
     *  <code>ButtonLabelPlacement.RIGHT</code>,
     *  <code>ButtonLabelPlacement.LEFT</code>,
     *  <code>ButtonLabelPlacement.BOTTOM</code>, and
     *  <code>ButtonLabelPlacement.TOP</code>.</p>
     *
     *  @default ButtonLabelPlacement.RIGHT
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get labelPlacement():String
    {
        return _labelPlacement;
    }

    /**
     *  @private
     */
    public function set labelPlacement(value:String):void
    {
        _labelPlacement = value;

        invalidateSize();
        invalidateDisplayList();

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

    //-----------------------------------
    //  listData
    //-----------------------------------

    /**
     *  @private
     *  Storage for the listData property.
     */
    private var _listData:BaseListData;

    [Bindable("dataChange")]
    [Inspectable(environment="none")]

    /**
     *  When a component is used as a drop-in item renderer or drop-in
     *  item editor, Flex initializes the <code>listData</code> property
     *  of the component with the appropriate data from the list control.
     *  The component can then use the <code>listData</code> property
     *  to initialize the <code>data</code> property
     *  of the drop-in item renderer or drop-in item editor.
     *
     *  <p>You do not set this property in MXML or ActionScript;
     *  Flex sets it when the component is used as a drop-in item renderer
     *  or drop-in item editor.</p>
     *
     *  @default null
     *  @see mx.controls.listClasses.IDropInListItemRenderer
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get listData():BaseListData
    {
        return _listData;
    }

    /**
     *  @private
     */
    public function set listData(value:BaseListData):void
    {
        _listData = value;
    }

    //----------------------------------
    //  phase
    //----------------------------------

    /**
     *  @private
     *  Mouse and focus events set this to
     *  ButtonPhase.UP, ButtonPhase.OVER, or ButtonPhase.DOWN.
     */
    private var _phase:String = ButtonPhase.UP;

    /**
     *  @private
     */
    mx_internal var phaseChanged:Boolean = false;
    
    /**
     *  @private
     */
    mx_internal function get phase():String
    {
        return _phase;
    }

    /**
     *  @private
     */
    mx_internal function set phase(value:String):void
    {
        _phase = value;
        phaseChanged = true;
        
        invalidateSize();
        invalidateProperties();
        invalidateDisplayList();
    }

    //----------------------------------
    //  selected
    //----------------------------------

    /**
     *  @private
     *  Storage for selected property.
     */
    mx_internal var _selected:Boolean = false;

    [Bindable("click")]
    [Bindable("valueCommit")]
    [Inspectable(category="General", defaultValue="false")]

    /**
     *  Indicates whether a toggle button is toggled
     *  on (<code>true</code>) or off (<code>false</code>).
     *  This property can be set only if the <code>toggle</code> property
     *  is set to <code>true</code>.
     *
     *  <p>For a CheckBox control, indicates whether the box
     *  is displaying a check mark. For a RadioButton control, 
     *  indicates whether the control is selected.</p>
     *
     *  <p>The user can change this property by clicking the control,
     *  but you can also set the property programmatically.</p>
     *
     *  <p>In previous versions, If the <code>toggle</code> property 
     *  was set to <code>true</code>, changing this property also dispatched 
     *  a <code>change</code> event. Starting in version 3.0, setting this 
     *  property programmatically only dispatches a 
     *  <code>valueCommit</code> event.</p>
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get selected():Boolean
    {
        return _selected;
    }

    /**
     *  @private
     */
    public function set selected(value:Boolean):void
    {
        selectedSet = true;
        setSelected(value, true);
    }

    mx_internal function setSelected(value:Boolean, 
                                     isProgrammatic:Boolean = false):void
    {
        if (_selected != value)
        {
            _selected = value;

            invalidateDisplayList();
            
            if (toggle && !isProgrammatic)
                dispatchEvent(new Event(Event.CHANGE));
            
            dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
        }
    }

    //----------------------------------
    //  selectedField
    //----------------------------------

    /**
     *  The name of the field in the <code>data</code> property which specifies
     *  the value of the Button control's <code>selected</code> property. 
     *  You can set this property when you use the Button control in an item renderer.
     *  The default value is null, which means that the Button control does 
     *  not set its selected state based on a property in the <code>data</code> property.
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public var selectedField:String = null;

    //----------------------------------
    //  skinLayoutDirection
    //----------------------------------
    
    private var skinLayoutDirectionSet:Boolean = false;
    private var _skinLayoutDirection:String;
    /**
     *  @private 
     */ 
    mx_internal function set skinLayoutDirection(value:String):void
    {
        skinLayoutDirectionSet = true;
        _skinLayoutDirection = value;
    }
    
    //----------------------------------
    //  stickyHighlighting
    //----------------------------------

    /**
     *  If <code>false</code>, the Button displays its down skin
     *  when the user presses it but changes to its over skin when
     *  the user drags the mouse off of it.
     *  If <code>true</code>, the Button displays its down skin
     *  when the user presses it, and continues to display this skin
     *  when the user drags the mouse off of it.
     *
     *  <p>Button subclasses, such as the SliderThumb and ScrollThumb classes
     *  or the up and down arrows of a ScrollBar, set 
     *  this property to <code>true</code>.</p>
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public var stickyHighlighting:Boolean = false;

    //----------------------------------
    //  toggle
    //----------------------------------

    /**
     *  @private
     *  Storage for toggle property.
     */
    mx_internal var _toggle:Boolean = false;

    /**
     *  @private
     */
    mx_internal var toggleChanged:Boolean = false;

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

    /**
     *  Controls whether a Button is in a toggle state or not. 
     * 
     *  If <code>true</code>, clicking the button toggles it
     *  between a selected and an unselected state.
     *  You can get or set this state programmatically
     *  by using the <code>selected</code> property.
     *
     *  If <code>false</code>, the button does not stay pressed
     *  after the user releases it.
     *  In this case, its <code>selected</code> property
     *  is always <code>false</code>.
     *  Buttons like this are used for performing actions.
     *
     *  When <code>toggle</code> is set to <code>false</code>,
     *  <code>selected</code> is forced to <code>false</code>
     *  because only toggle buttons can be selected.
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get toggle():Boolean
    {
        return _toggle;
    }

    /**
     *  @private
     */
    public function set toggle(value:Boolean):void
    {
        _toggle = value;
        toggleChanged = true;

        invalidateProperties();
        invalidateDisplayList();

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

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

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

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

        // Create a UITextField to display the label.
        if (!textField)
        {
            textField = IUITextField(createInFontContext(UITextField));
            textField.styleName = this;
            addChild(DisplayObject(textField));
        }
 
    }

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

         // if the font changed and we already created the textfield, we will need to 
        // destory it so it can be re-created, possibly in a different swf context.
        if (hasFontContextChanged() && textField != null)
        {
            removeChild(DisplayObject(textField));
            textField = null;
        }
        
         // Create a UITextField to display the label.
        if (!textField)
        {
            textField = IUITextField(createInFontContext(UITextField));
            textField.styleName = this;
            addChild(DisplayObject(textField));

            enabledChanged = true;
            toggleChanged = true;
        }

        if (!initialized)
        {
            viewSkin();
            viewIcon();
        }

        if (enabledChanged)
        {
            textField.enabled = enabled;
            
            if (currentIcon && currentIcon is IUIComponent)
                IUIComponent(currentIcon).enabled = enabled;
            
            enabledChanged = false;
        }

        if (toggleChanged)
        {
            // If the button is no longer toggleable,
            // deselect it.
            if (!toggle)
                selected = false;
            toggleChanged = false;
        }  
        
        if (phaseChanged)
        {
            // Ensure all potential pseudo-selectors are reevaluated if 
            // necessary.
            var prevState:String = _currentButtonState;
            if (prevState != getCurrentButtonState())
                stateChanged(prevState, _currentButtonState, false);
            phaseChanged = false;
        }
    }
    
    /**
     *  @private
     */
    override protected function measure():void
    {
        super.measure();

        var textWidth:Number = 0;
        var textHeight:Number = 0;

        if (label)
        {
            var lineMetrics:TextLineMetrics = measureText(label);
            textWidth = lineMetrics.width + TEXT_WIDTH_PADDING;
            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
        }
    
        var tempCurrentIcon:IFlexDisplayObject = getCurrentIcon();  
        var iconWidth:Number = tempCurrentIcon ? tempCurrentIcon.width : 0;
        var iconHeight:Number = tempCurrentIcon ? tempCurrentIcon.height : 0;
        var w:Number = 0;
        var h:Number = 0;

        if (labelPlacement == ButtonLabelPlacement.LEFT ||
            labelPlacement == ButtonLabelPlacement.RIGHT)
        {
            w = textWidth + iconWidth;
            if (textWidth && iconWidth)
                w += getStyle("horizontalGap");
            h = Math.max(textHeight, iconHeight);
        }
        else
        {
            w = Math.max(textWidth, iconWidth);
            h = textHeight + iconHeight;
            if (textHeight && iconHeight)
                h += getStyle("verticalGap");
        }

        // Add padding. !!!Need a hack here to only add padding if we don't
        // have text or icon. This is required to make small buttons (like scroll
        // arrows and numeric stepper buttons) look correct.
        if (textWidth || iconWidth)
        {
            w += getStyle("paddingLeft") + getStyle("paddingRight");
            h += getStyle("paddingTop") + getStyle("paddingBottom");
        }
        
        var bm:EdgeMetrics = currentSkin &&
                             currentSkin is IBorder && !(currentSkin is IFlexAsset) ?
                             IBorder(currentSkin).borderMetrics :
                             null;
        
        if (bm)
        {
            w += bm.left + bm.right;
            h += bm.top + bm.bottom
        }
        
        // Use the larger of the measured sizes and the skin's preferred sizes.
        // Each skin should override measure() with their measuredWidth
        // and measuredHeight.
        if (currentSkin && (isNaN(skinMeasuredWidth) || isNaN(skinMeasuredHeight)))
        {
            skinMeasuredWidth = currentSkin.measuredWidth;
            skinMeasuredHeight = currentSkin.measuredHeight;
        }

        if (!isNaN(skinMeasuredWidth))
            w = Math.max(skinMeasuredWidth, w);

        if (!isNaN(skinMeasuredHeight))
            h = Math.max(skinMeasuredHeight, h);

        measuredMinWidth = measuredWidth = w;
        measuredMinHeight = measuredHeight = h;
        // trace("measure: Button width = " + w + " height = " + h);
    }
    
    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        if (emphasizedChanged)
        {
            changeSkins();
            emphasizedChanged = false;
        }
        
        // Set each skin's size to the layout size of this Button.
        var n:int = skins.length;
        for (var i:int = 0; i < n; i++)
        {
            var skin:IFlexDisplayObject = IFlexDisplayObject(skins[i]);
            skin.setActualSize(unscaledWidth, unscaledHeight);
        }

        // Show the appropriate skin and icon, based on whether this
        // Button is enabled or disabled, whether it is selected
        // or unselected, and how it is currently interacting
        // with the mouse (i.e., the up/over/down phase).
        viewSkin();
        viewIcon();

        /* if (currentIcon && currentIcon is IUIComponent)
            IUIComponent(currentIcon).enabled = enabled; */

        layoutContents(unscaledWidth, unscaledHeight,
                       phase == ButtonPhase.DOWN);

        // If our width changed, reset the label text to get it to fit.
        if (oldUnscaledWidth > unscaledWidth ||
            textField.text != label ||
            labelChanged ||
            styleChangedFlag)
        {
            textField.text = label;
            var truncated:Boolean = textField.truncateToFit();
            if (!toolTipSet)
            {
                if (truncated)
                    super.toolTip = label;
                else
                    super.toolTip = null;
            }

            styleChangedFlag = false;
            labelChanged = false;
        }

        oldUnscaledWidth = unscaledWidth;
    }

    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        styleChangedFlag = true;

        super.styleChanged(styleProp);

        // Check for skin/icon changes here.
        // We could only throw out any skins that change,
        // but since dynamic re-skinning is uncommon, we'll take
        // the simpler approach of throwing out all skins.
        if (!styleProp || styleProp == "styleName")
        {
            // All style props have changed, so dump skins and icons.
            changeSkins();
            changeIcons();
            if (initialized)
            {
                viewSkin();
                viewIcon();
            }
        }
        else if (styleProp.toLowerCase().indexOf("skin") != -1)
        {
            changeSkins();
        }
        else if (styleProp.toLowerCase().indexOf("icon") != -1)
        {
            changeIcons();
            invalidateSize();
        }
    }

    /**
     *  @private
     */
    override protected function adjustFocusRect(
                                    object:DisplayObject = null):void
    {
        // If we don't have a skin, show focus around the icon.
        super.adjustFocusRect(!currentSkin ? DisplayObject(currentIcon) : this);
    }
    
    /**
     *  @private 
     *  The state to be used when matching CSS pseudo-selectors. This override
     *  returns the current button state.
     */ 
    override protected function get currentCSSState():String
    {
        return getCurrentButtonState();
    }

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

    /**
     *  @private
     *  Displays one of the eight possible skins,
     *  creating it if it doesn't already exist.
     */
    mx_internal function viewSkin():void
    {
        // Determine which skin to display, based on whether this
        // button is enabled or disabled, whether it is
        // selected or unselected, and how it is currently interacting
        // with the mouse (i.e., the up/over/down state).
        var tempSkinName:String;
        
        if (!enabled)
            tempSkinName = selected ? selectedDisabledSkinName : disabledSkinName;
        else if (phase == ButtonPhase.UP)
            tempSkinName = selected ? selectedUpSkinName : upSkinName;
        else if (phase == ButtonPhase.OVER)
            tempSkinName = selected ? selectedOverSkinName : overSkinName;
        else if (phase == ButtonPhase.DOWN)
            tempSkinName = selected ? selectedDownSkinName : downSkinName;
            
        viewSkinForPhase(tempSkinName, getCurrentButtonState());
    }

    /**
     *  @private
     *  Displays one of the several possible skins,
     *  depending on the skinName and creating
     *  it if it doesn't already exist.
     */
    mx_internal function viewSkinForPhase(tempSkinName:String, stateName:String):void
    {
        var newSkinClass:Class = Class(getStyle(tempSkinName));
        var newSkin:IFlexDisplayObject;
                
        if (!newSkinClass)
        {
            // Try the default skin
            newSkinClass = _emphasized ? Class(getStyle(emphasizedSkinName)) : Class(getStyle(skinName));
            newSkinClass = !newSkinClass && _emphasized ? Class(getStyle(skinName)) : newSkinClass;
            
            // If we are using the default skin, then 
            if (defaultSkinUsesStates)
                tempSkinName = skinName;
            
            if (!checkedDefaultSkin && newSkinClass)
            {
                newSkin = IFlexDisplayObject(new newSkinClass());
                // Check if the skin class is a state client or a programmatic skin
                if (!(newSkin is IProgrammaticSkin) && newSkin is IStateClient)
                {
                    defaultSkinUsesStates = true;
                    tempSkinName = skinName; 
                }
                
                if (newSkin)
                {
                    checkedDefaultSkin = true;
                    
                    if (newSkin is ILayoutDirectionElement && skinLayoutDirectionSet)
                        ILayoutDirectionElement(newSkin).layoutDirection = _skinLayoutDirection;
                }
            }
        }
        
        // Has this skin already been created?
        newSkin = IFlexDisplayObject(getChildByName(tempSkinName));
        // If not, create it.
        if (!newSkin)
        {           
            if (newSkinClass)
            {
                newSkin = IFlexDisplayObject(new newSkinClass());
                // Set its name so that we can find it in the future
                // using getChildByName().
                newSkin.name = tempSkinName;

                // Make the getStyle() calls in ButtonSkin find the styles
                // for this Button.
                var styleableSkin:ISimpleStyleClient = newSkin as ISimpleStyleClient;
                if (styleableSkin)
                    styleableSkin.styleName = this;

                if (newSkin is ILayoutDirectionElement && skinLayoutDirectionSet)
                    ILayoutDirectionElement(newSkin).layoutDirection = _skinLayoutDirection;
                
                addChild(DisplayObject(newSkin));

                // Make the skin the proper size for this Button.
                // This will cause to skin to be drawn by drawHaloRect()
                // in ButtonSkin.
                newSkin.setActualSize(unscaledWidth, unscaledHeight);

                // If the skin is programmatic, and we've already been
                // initialized, update it now to avoid flicker.
                if (newSkin is IInvalidating && initialized)
                {
                    IInvalidating(newSkin).validateNow();
                }
                else if (newSkin is IProgrammaticSkin && initialized)
                {
                    IProgrammaticSkin(newSkin).validateDisplayList()
                }

                // Keep track of all skin children that have been created.
                skins.push(newSkin);
            }
        }

        // Hide the old skin.
        if (currentSkin)
            currentSkin.visible = false;

        // Keep track of which skin is current.
        currentSkin = newSkin;

        // Update the state of the skin if it accepts states and it implements the IStateClient interface.
        if (defaultSkinUsesStates && currentSkin is IStateClient)
        {
            IStateClient(currentSkin).currentState = stateName;
            if (currentSkin is IInvalidating)
                IInvalidating(currentSkin).validateNow();
        }

        // Show the new skin.
        if (currentSkin)
            currentSkin.visible = true;

        var labelColor:Number;

        if (enabled)
        {
            if (phase == ButtonPhase.OVER)
                labelColor = textField.getStyle("textRollOverColor");
            else if (phase == ButtonPhase.DOWN)
                labelColor = textField.getStyle("textSelectedColor");
            else
                labelColor = textField.getStyle("color");

            textField.setColor(labelColor);
        }
    }

    /**
     *  @private
     *  Gets the currentIconName (string) based on the Button's phase.
     */
    mx_internal function getCurrentIconName():String
    {
        var tempIconName:String;

        if (!enabled)
        {
            tempIconName = selected ?
                           selectedDisabledIconName :
                           disabledIconName;
        }
        else if (phase == ButtonPhase.UP)
        {
            tempIconName = selected ? selectedUpIconName : upIconName;
        }
        else if (phase == ButtonPhase.OVER)
        {
            tempIconName = selected ? selectedOverIconName : overIconName;
        }
        else if (phase == ButtonPhase.DOWN)
        {
            tempIconName = selected ? selectedDownIconName : downIconName;
        }
        
        return tempIconName;
    }


    /**
     *  @private
     *  gets the currentIcon based on the button.phase 
     */
    mx_internal function getCurrentIcon():IFlexDisplayObject
    {
        // Determine which icon will get displayed, based on whether this
        // Button is enabled or disabled, whether it is
        // selected or unselected, and how it is currently interacting
        // with the mouse (i.e., the up/over/down state).

        var tempIconName:String = getCurrentIconName(); 

        if (!tempIconName)
            return null;

        return viewIconForPhase(tempIconName);
    }   

    /**
     *  @private
     *  Displays one of the eight possible icons,
     *  creating it if it doesn't already exist.
     */
    mx_internal function viewIcon():void
    {
        // Determine which icon to display, based on whether this
        // Button is enabled or disabled, whether it is
        // selected or unselected, and how it is currently interacting
        // with the mouse (i.e., the up/over/down state).
        var tempIconName:String = getCurrentIconName();

        viewIconForPhase(tempIconName);
    }

    /**
     *  @private
     *  Displays one of the several possible icons,
     *  depending on the iconName and creating it if it
     *  doesn't already exist.
     */
    mx_internal function viewIconForPhase(tempIconName:String):IFlexDisplayObject
    {
        var newIconClass:Class = Class(getStyle(tempIconName));
        var newIcon:IFlexDisplayObject;
        
        if (!newIconClass)
        {
            newIconClass = Class(getStyle(iconName));
            
            // If we are using the default icon, then set use the default icon name
            if (defaultIconUsesStates)
                tempIconName = iconName;
            
            if (!checkedDefaultIcon && newIconClass)
            {
                newIcon = IFlexDisplayObject(new newIconClass());
                // Check if the icon class is a state client or a programmatic skin
                if (!(newIcon is IProgrammaticSkin) && newIcon is IStateClient)
                {
                    defaultIconUsesStates = true;
                    tempIconName = iconName; 
                }
                
                if (newIcon)
                    checkedDefaultIcon = true;
            }
        }
        
        // Has this icon already been created?
        newIcon = IFlexDisplayObject(getChildByName(tempIconName));
        // If not, create it.
        if (newIcon == null)
        {
            if (newIconClass != null)
            {
                newIcon = IFlexDisplayObject(new newIconClass());

                // Set its name so that we can find it in the future
                // using getChildByName().
                newIcon.name = tempIconName;

                if (newIcon is ISimpleStyleClient)
                    ISimpleStyleClient(newIcon).styleName = this;

                addChild(DisplayObject(newIcon));

                
                // If the skin is programmatic, and we've already been
                // initialized, update it now to avoid flicker.
                var sizeIcon:Boolean = false;
                if (newIcon is IInvalidating)
                {
                    IInvalidating(newIcon).validateNow();
                    sizeIcon = true;
                }
                else if (newIcon is IProgrammaticSkin)
                {
                    IProgrammaticSkin(newIcon).validateDisplayList();
                    sizeIcon = true;
                }
                if (newIcon && newIcon is IUIComponent)
                    IUIComponent(newIcon).enabled = enabled;              

                if (sizeIcon)
                    newIcon.setActualSize(newIcon.measuredWidth, newIcon.measuredHeight); 


                // Keep track of all icon children that have been created.
                icons.push(newIcon);
            }
        }
        
        // Hide the old icon.
        if (currentIcon != null)
            currentIcon.visible = false;

        // Keep track of which icon is current.
        currentIcon = newIcon;
        
        if (defaultIconUsesStates && currentIcon is IStateClient)
        {            
            IStateClient(currentIcon).currentState = getCurrentButtonState();
            if (currentIcon is IInvalidating)
                IInvalidating(currentIcon).validateNow();
        }

        // Show the new icon.
        if (currentIcon != null)
            currentIcon.visible = true;
            
        return newIcon;
    }

    /**
     *  @private
     *  Storage for the most recent button state.
     */
    protected var _currentButtonState:String;
    
    /**
     *  @private
     *  Computes the current button state based on whether this button is 
     *  enabled or disabled, whether it is selected or unselected, and how it 
     *  is currently interacting with the mouse (i.e. the up/over/down state).
     */
    mx_internal function getCurrentButtonState():String
    {
        _currentButtonState = "";
        
        if (!enabled)
            _currentButtonState = selected ? "selectedDisabled" : "disabled";
        else if (phase == ButtonPhase.UP)
            _currentButtonState = selected ? "selectedUp" : "up";
        else if (phase == ButtonPhase.OVER)
            _currentButtonState = selected ? "selectedOver" : "over";
        else if (phase == ButtonPhase.DOWN)
            _currentButtonState = selected ? "selectedDown" : "down";
        
        return _currentButtonState;
    }
    
   /**
     *  @private
     *  Controls the layout of the icon and the label within the button.
     *  The text/icon are aligned based on the textAlign style setting.
     */
    mx_internal function layoutContents(unscaledWidth:Number,
                                        unscaledHeight:Number,
                                        offset:Boolean):void
    {
        var labelWidth:Number = 0;
        var labelHeight:Number = 0;

        var labelX:Number = 0;
        var labelY:Number = 0;

        var iconWidth:Number = 0;
        var iconHeight:Number = 0;

        var iconX:Number = 0;
        var iconY:Number = 0;

        var horizontalGap:Number = 0;
        var verticalGap:Number = 0;

        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingRight:Number = getStyle("paddingRight");
        var paddingTop:Number = getStyle("paddingTop");
        var paddingBottom:Number = getStyle("paddingBottom");

        var textWidth:Number = 0;
        var textHeight:Number = 0;

        var lineMetrics:TextLineMetrics;

        if (label)
        {
            lineMetrics = measureText(label);
            textWidth = lineMetrics.width + TEXT_WIDTH_PADDING;
            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
        }
        else
        {
            lineMetrics = measureText("Wj");
            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
        }

        var n:Number = offset ? buttonOffset : 0;

        var textAlign:String = getStyle("textAlign");
        // Map new Spark values that might be set in a selector
        // affecting both Halo and Spark components.
        if (textAlign == "start") 
            textAlign = TextFormatAlign.LEFT;
        else if (textAlign == "end")
            textAlign = TextFormatAlign.RIGHT;

        var viewWidth:Number = unscaledWidth;
        var viewHeight:Number = unscaledHeight;

        var bm:EdgeMetrics = currentSkin &&
                             currentSkin is IBorder && !(currentSkin is IFlexAsset) ?
                             IBorder(currentSkin).borderMetrics :
                             null;

        if (bm)
        {
            viewWidth -= bm.left + bm.right;
            viewHeight -= bm.top + bm.bottom;
        }

        if (currentIcon)
        {
            iconWidth = currentIcon.width;
            iconHeight = currentIcon.height;
        }

        if (labelPlacement == ButtonLabelPlacement.LEFT ||
            labelPlacement == ButtonLabelPlacement.RIGHT)
        {
            horizontalGap = getStyle("horizontalGap");

            if (iconWidth == 0 || textWidth == 0)
                horizontalGap = 0;

            if (textWidth > 0)
            {
                textField.width = labelWidth = 
                    Math.max(Math.min(viewWidth - iconWidth - horizontalGap -
                                      paddingLeft - paddingRight, textWidth), 0);
            }
            else
            {
                textField.width = labelWidth = 0;
            }
            textField.height = labelHeight = Math.min(viewHeight, textHeight);

            if (textAlign == "left")
            {
                labelX += paddingLeft;
            }
            else if (textAlign == "right")
            {
                labelX += (viewWidth - labelWidth - iconWidth - 
                           horizontalGap - paddingRight);
            }
            else // "center" -- default value
            {
                labelX += ((viewWidth - labelWidth - iconWidth - 
                           horizontalGap - paddingLeft - paddingRight) / 2) + paddingLeft;
            }

            if (labelPlacement == ButtonLabelPlacement.RIGHT)
            {
                labelX += iconWidth + horizontalGap;
                iconX = labelX - (iconWidth + horizontalGap);
            }
            else
            {
                iconX  = labelX + labelWidth + horizontalGap; 
            }

            iconY  = ((viewHeight - iconHeight - paddingTop - paddingBottom) / 2) + paddingTop;
            labelY = ((viewHeight - labelHeight - paddingTop - paddingBottom) / 2) + paddingTop;
        }
        else
        {
            verticalGap = getStyle("verticalGap");

            if (iconHeight == 0 || label == "")
                verticalGap = 0;

            if (textWidth > 0)
            {
                textField.width = labelWidth = Math.max(viewWidth - paddingLeft - paddingRight, 0);
                textField.height = labelHeight =
                    Math.min(viewHeight - iconHeight - paddingTop - paddingBottom - verticalGap, textHeight);
            }
            else
            {
                textField.width = labelWidth = 0;
                textField.height = labelHeight = 0;
            }

            labelX = paddingLeft;

            if (textAlign == "left")
            {
                iconX += paddingLeft;
            }
            else if (textAlign == "right")
            {
                iconX += Math.max(viewWidth - iconWidth - paddingRight, paddingLeft);
            }
            else
            {
                iconX += ((viewWidth - iconWidth - paddingLeft - paddingRight) / 2) + paddingLeft;
            }

            if (labelPlacement == ButtonLabelPlacement.TOP)
            {
                labelY += ((viewHeight - labelHeight - iconHeight - 
                            paddingTop - paddingBottom - verticalGap) / 2) + paddingTop;
                iconY += labelY + labelHeight + verticalGap;
            }
            else
            {
                iconY += ((viewHeight - labelHeight - iconHeight - 
                            paddingTop - paddingBottom - verticalGap) / 2) + paddingTop;
                labelY += iconY + iconHeight + verticalGap;
            }

        }
        var buffX:Number = n;
        var buffY:Number = n;

        if (bm)
        {
            buffX += bm.left;
            buffY += bm.top;
        }
        
        if (FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0)
            labelY += getStyle("labelVerticalOffset");

        textField.x = Math.round(labelX + buffX);
        textField.y = Math.round(labelY + buffY);

        if (currentIcon)
        {
            iconX += buffX;
            iconY += buffY;

            // dispatch a move on behalf of the icon
            // the focus system uses that to adjust
            // focus rectangles
            var moveEvent:MoveEvent = new MoveEvent(MoveEvent.MOVE);
            moveEvent.oldX = currentIcon.x;
            moveEvent.oldY = currentIcon.y;

            currentIcon.x = Math.round(iconX);
            currentIcon.y = Math.round(iconY);
            currentIcon.dispatchEvent(moveEvent);
        }

        // The skins and icons get created on demand as the user interacts
        // with the Button, and as they are created they become the
        // frontmost child.
        // Here we ensure that the textField is the frontmost child,
        // with the current icon behind it and the current skin behind that.
        // Any other skins and icons are left behind these three,
        // with arbitrary layering.
        if (currentSkin)
            setChildIndex(DisplayObject(currentSkin), numChildren - 1);
        if (currentIcon)
            setChildIndex(DisplayObject(currentIcon), numChildren - 1);
        if (textField)
            setChildIndex(DisplayObject(textField), numChildren - 1);
    }

    /**
     *  @private
     */
    mx_internal function changeSkins():void
    {
        var n:int = skins.length;
        for (var i:int = 0; i < n; i++)
        {
            removeChild(skins[i]);
        }
        skins = [];
        
        skinMeasuredWidth = NaN;
        skinMeasuredHeight = NaN;
        
        checkedDefaultSkin = false;
        defaultSkinUsesStates = false;
        
        if (initialized)
        {
            viewSkin();
            invalidateSize();
        }
    }

    /**
     *  @private
     */
    mx_internal function changeIcons():void
    {
        var n:int = icons.length;
        for (var i:int = 0; i < n; i++)
        {
            removeChild(icons[i]);
        }
        icons = [];
        
        checkedDefaultIcon = false;
        defaultIconUsesStates = false;
    }

    /**
     *  @private
     */
    mx_internal function buttonPressed():void
    {
        phase = ButtonPhase.DOWN;
        
        dispatchEvent(new FlexEvent(FlexEvent.BUTTON_DOWN));

        if (autoRepeat)
        {
            autoRepeatTimer.delay = getStyle("repeatDelay");
            autoRepeatTimer.addEventListener(
                TimerEvent.TIMER, autoRepeatTimer_timerDelayHandler);
            autoRepeatTimer.start();
        }
    }

    /**
     *  @private
     */
    mx_internal function buttonReleased():void
    {
        // Remove the handlers that were added in mouseDownHandler().
        systemManager.getSandboxRoot().removeEventListener(
            MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true);
        systemManager.getSandboxRoot().removeEventListener(
            SandboxMouseEvent.MOUSE_UP_SOMEWHERE, stage_mouseLeaveHandler);
        
        if (autoRepeatTimer)
        {
            autoRepeatTimer.removeEventListener(
                TimerEvent.TIMER, autoRepeatTimer_timerDelayHandler);
            autoRepeatTimer.removeEventListener(
                TimerEvent.TIMER, autoRepeatTimer_timerHandler);
            autoRepeatTimer.reset();
        }
    }

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

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

    /**
     *  @private
     */
    override protected function focusOutHandler(event:FocusEvent):void
    {
        super.focusOutHandler(event);

        // Most of the time the system sends a rollout, but there are
        // situations where the mouse is over something else
        // that you don't get one so we force one here.
        if (phase != ButtonPhase.UP)
            phase = ButtonPhase.UP;
    }

    /**
     *  @private
     */
    override protected function keyDownHandler(event:KeyboardEvent):void
    {
        if (!enabled)
            return;

        if (event.keyCode == Keyboard.SPACE)
            buttonPressed();
    }

    /**
     *  @private
     */
    override protected function keyUpHandler(event:KeyboardEvent):void
    {
        if (!enabled)
            return;

        if (event.keyCode == Keyboard.SPACE)
        {
            buttonReleased();

            if (phase == ButtonPhase.DOWN)
                dispatchEvent(new MouseEvent(MouseEvent.CLICK));
            phase = ButtonPhase.UP;
        }
    }

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

    /*

    Mouse interaction sequences that Button must handle:

    All start with Button in "up" phase, mouse outside Button,
    and mouse button up.

    Normal click:
        roll over Button -> "over" phase
        mouse down on Button -> "down" phase, dispatch "buttonDown"
        mouse up while over Button -> "over" phase, dispatch "click"
        roll out of Button -> "up" phase

    Click canceled:
        roll over Button -> "over" phase
        mouse down on Button -> "down" phase, dispatch "buttonDown"
        roll out of Button -> "over" phase
        maybe roll over and out of other objects -> dispatch events from them
        maybe roll off the stage, or off and back on
        mouse up while out of Button -> "up" phase
        if mouseup was over another Button, it goes into "over" phase

    Click resumed:
        roll over Button -> "over" phase
        mouse down on Button -> "down" phase, dispatch "buttonDown"
        roll out of Button -> "over" phase
        maybe roll over and out of other objects -> dispatch events from them
        roll over Button -> "down" phase
        maybe roll off the stage, or off and back on
        maybe repeat last four steps
        mouse up while over Button -> "over" phase, dispatch "click"
        roll out of Button -> "up" phase

    Drag over and out
        mouse down while out of Button
        roll over Button -> stay in "up" phase
        roll out of Button -> stay in "up" phase

    Drag over and up
        mouse down while out of Button
        roll over Button -> stay in "up" phase
        mouse up while over Button -> "over" phase
        continue with step 2 of first three sequences above

    */

    /**
     *  The default handler for the <code>MouseEvent.ROLL_OVER</code> event.
     *
     *  @param The event object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function rollOverHandler(event:MouseEvent):void
    {
        
        // Note that we don't prevent the propagation of rollOver
        // from a disabled Button.
        // Developers may want to detect this low-level event.

        if (phase == ButtonPhase.UP)
        {
            if (event.buttonDown)
                return;

            phase = ButtonPhase.OVER;
            
            // Force a "render" event, which will cause updateDisplayList()
            // to show the appropriate skin for the new phase.
            event.updateAfterEvent();
        }

        else if (phase == ButtonPhase.OVER)
        {
            phase = ButtonPhase.DOWN;
            
            // Force a "render" event, which will cause updateDisplayList()
            // to show the appropriate skin for the new phase.
            event.updateAfterEvent();
            
            // The mouse is back over the Button and the Button is down again,
            // so resume auto-repeating.
            if (autoRepeatTimer)
                autoRepeatTimer.start();
        }
    }

    /**
     *  The default handler for the <code>MouseEvent.ROLL_OUT</code> event.
     *
     *  @param The event object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function rollOutHandler(event:MouseEvent):void
    {

        // Note that we don't prevent the propagation of rollOut
        // from a disabled Button.
        // Developers may want to detect this low-level event.

        if (phase == ButtonPhase.OVER)
        {
            phase = ButtonPhase.UP;
            
            // Force a "render" event, which will cause updateDisplayList()
            // to show the appropriate skin for the new phase.
            event.updateAfterEvent();
        }

        else if (phase == ButtonPhase.DOWN && !stickyHighlighting)
        {
            phase = ButtonPhase.OVER;
            
            // Force a "render" event, which will cause updateDisplayList()
            // to show the appropriate skin for the new phase.
            event.updateAfterEvent();

            // If the Button no longer looks "down", it shouldn't auto-repeat.
            if (autoRepeatTimer)
                autoRepeatTimer.stop();
        }
    }

    /**
     *  The default handler for the <code>MouseEvent.MOUSE_DOWN</code> event.
     *
     *  @param The event object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function mouseDownHandler(event:MouseEvent):void
    {
        if (!enabled)
            return;

        // Note that we don't prevent the propagation of mouseDown
        // from a disabled Button.
        // Developers may want to detect this low-level event.

        // In case the user drags out of the Button and then releases
        // the mouse button, we need to get the mouseUp.
        // To accomplish this, we temporarily place a capture-phase
        // mouseUp handler on the SystemManager.
        // We also place a mouseLeave handler on the stage
        // in case the user drags off the stage and releases the mouse.
        // These handlers are removed in buttonReleased().
        systemManager.getSandboxRoot().addEventListener(
            MouseEvent.MOUSE_UP, systemManager_mouseUpHandler, true);
        systemManager.getSandboxRoot().addEventListener(
            SandboxMouseEvent.MOUSE_UP_SOMEWHERE, stage_mouseLeaveHandler);

        buttonPressed();

        // Force a "render" event, which will cause updateDisplayList()
        // to show the appropriate skin for the new phase.
        event.updateAfterEvent();
    }

    /**
     *  The default handler for the <code>MouseEvent.MOUSE_UP</code> event.
     *
     *  @param The event object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function mouseUpHandler(event:MouseEvent):void
    {
        if (!enabled)
            return;

        // Note that we don't prevent the propagation of mouseUp
        // from a disabled Button.
        // Developers may want to detect this low-level event.
        phase = ButtonPhase.OVER;
        buttonReleased();
        
        // Force a "render" event, which will cause updateDisplayList()
        // to show the appropriate skin for the new phase.    
        if (!toggle)
            event.updateAfterEvent(); 
    }

    /**
     *  The default handler for the <code>MouseEvent.CLICK</code> event.
     *
     *  @param The event object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function clickHandler(event:MouseEvent):void
    {
        if (!enabled)
        {
            // Prevent the propagation of click from a disabled Button.
            // This is conceptually a higher-level event and
            // developers will expect their click handlers not to fire
            // if the Button is disabled.
            event.stopImmediatePropagation();
            return;
        }

        if (toggle)
        {
            setSelected(!selected);
            event.updateAfterEvent(); 
        }
        
          
    }

    /**
     *  @private
     *  This method is called when the user has pressed the Button
     *  and then released the mouse button anywhere.
     *  It's purpose is to get the mouseUp event when the user has
     *  dragged out of the Button before releasing.
     *  However, it gets an inside mouseUp as well;
     *  we have to check for this case becuase mouseHandler()
     *  already deals with it..
     */
    private function systemManager_mouseUpHandler(event:MouseEvent):void
    {
        // If the mouse button was released over the Button,
        // mouseUpHandler() will handle it, so do nothing. 
        if (contains(DisplayObject(event.target)))
            return;

        phase = ButtonPhase.UP;
        buttonReleased();

        // Force a "render" event, which will cause updateDisplayList()
        // to show the appropriate skin for the new phase.
        event.updateAfterEvent();
    }

    /**
     *  @private
     *  This method is called when the user has pressed the Button,
     *  dragged of the stage, and released the mouse button.
     */
    private function stage_mouseLeaveHandler(event:Event):void
    {
        phase = ButtonPhase.UP;
        buttonReleased();
    }

    /**
     *  @private
     */
    private function autoRepeatTimer_timerDelayHandler(event:Event):void
    {
        if (!enabled)
            return;

        dispatchEvent(new FlexEvent(FlexEvent.BUTTON_DOWN));

        if (autoRepeat)
        {
            autoRepeatTimer.reset();
            autoRepeatTimer.removeEventListener(
                TimerEvent.TIMER, autoRepeatTimer_timerDelayHandler);
            autoRepeatTimer.delay = getStyle("repeatInterval");
            autoRepeatTimer.addEventListener(
                TimerEvent.TIMER, autoRepeatTimer_timerHandler);
            autoRepeatTimer.start();
        }
    }

    /**
     *  @private
     */
    private function autoRepeatTimer_timerHandler(event:Event):void
    {
        if (!enabled)
            return;

        dispatchEvent(new FlexEvent(FlexEvent.BUTTON_DOWN));
    }
}

}
