 import mx.managers.IFocusManagerComponent;
 
 /**
- *  Dispatched when the user presses the Button control.
+ *  Dispatched when the user presses the FxButton control.
  *  If the <code>autoRepeat</code> property is <code>true</code>,
  *  this event is dispatched repeatedly as long as the button stays down.
  *

    //--------------------------------------------------------------------------
    
    [SkinPart(required="false")]
    public var labelField:TextBox;
    
    //--------------------------------------------------------------------------

    //
    //--------------------------------------------------------------------------
    
    /**
     *  @inheritDoc
     */
    override protected function partAdded(partName:String, instance:Object):void
    {
        super.partAdded(partName, instance);
        
        if (instance == labelField)
        {
            labelField.text = label;
        }
    }

    //--------------------------------------------------------------------------
    //
    //  States
    //
    //--------------------------------------------------------------------------

    private function isDown():Boolean
    {
        if (!isEnabled)
            return false;

        if (isKeyboardPressed)
            return true;
        
        if (isMouseCaptured && (isHoveredOver || stickyHighlighting))
            return true;
        return false;
    }

    // GetState returns a string representation of the component's state as
    // a combination of some of its public properties   
    /**
     *  @inheritDoc
     */
    protected override function getUpdatedSkinState():String
    {
        if (!isEnabled)
            return "disabled";

        if (isDown())
            return "down";
            
        if (isHoveredOver || isMouseCaptured )
            return "over";
            
        return "up";
    }
    
    /**
     *  @inheritDoc
     */
    override protected function commitSkinState(newState:String):void
    {
        super.commitSkinState(newState);
        
        // Our state has changed, see whether we need to start/stop dispatching buttonDown
        checkDownEventConditions();
    } 

    private function checkDownEventConditions():void
    {
        var isCurrentlyDown:Boolean = isDown();

        // If down state hasn't changed, simply return
        if (!flags.update(downEventFiredFlag, isCurrentlyDown))
            return;

        if( isCurrentlyDown )
            dispatchEvent(new FlexEvent(FlexEvent.BUTTON_DOWN));
        
        checkAutoRepeatTimerConditions( isCurrentlyDown );
    }

    //--------------------------------------------------------------------------
    //
    //  Event handling
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    protected function addHandlers():void
    {
        addEventListener(MouseEvent.ROLL_OVER, mouseEventHandler);
        addEventListener(MouseEvent.ROLL_OUT, mouseEventHandler);
        addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler);
        addEventListener(MouseEvent.MOUSE_UP, mouseEventHandler);
        // TODO EGeorgie: should revisit, we are handling the CLICK during capture phase,
        // since instance handlers are registered before base class handlers.
        addEventListener(MouseEvent.CLICK, mouseEventHandler, true /*useCapture*/);
        addEventListener("enabledChanged", enableChangedHandler);
    }
    
    private function addSystemMouseHandlers():void
    {
        systemManager.addEventListener(MouseEvent.MOUSE_UP, mouseEventHandler, true /*useCapture*/);
        systemManager.stage.addEventListener(Event.MOUSE_LEAVE, mouseEventHandler);             
    }

    private function removeSystemMouseHandlers():void
    {
        systemManager.removeEventListener(MouseEvent.MOUSE_UP, mouseEventHandler, true /*useCapture*/);
        systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, mouseEventHandler);
    }
    
    /**
     *  @private
     */
    protected function enableChangedHandler(event:Event):void
    {
        // Since enabled is part of our state, we need to invalidate it on changes.
        invalidateSkinState();
    }
    
    /**
     *  @private
     */
    protected function mouseEventHandler(event:Event):void
    {
        var mouseEvent:MouseEvent = event as MouseEvent;
        switch (event.type)
        {
            case MouseEvent.ROLL_OVER:
            {
                // if the user rolls over while holding the mouse button
                if (mouseEvent.buttonDown && !isMouseCaptured)
                    return;
                    setHoveredOver(true);
                break;
            }

            case MouseEvent.ROLL_OUT:
            {
                setHoveredOver(false);
                break;
            }
            
            case MouseEvent.MOUSE_DOWN:
            {
                // When the button is down we need to listen for mouse events outsied the button so that
                // we update the state appropriately on mouse up.  Whenever isMouseCaptured changes to false,
                // it will take care to remove those handlers.
                addSystemMouseHandlers();
                setMouseCaptured(true);
                break;
            }

            case MouseEvent.MOUSE_UP:
            {
                if (event.currentTarget == this)
                    setHoveredOver(true);
            } //fallthrough:
            case Event.MOUSE_LEAVE:
            {
                setMouseCaptured(false);
                break;
            }

            // 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.
            case MouseEvent.CLICK:
            {
                if(!isEnabled )
                    event.stopImmediatePropagation();
                return;
            }
        }
        if (mouseEvent)
            mouseEvent.updateAfterEvent();
    }

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

    /**
     *  @private
     */
    override protected function focusOutHandler(event:FocusEvent):void
    {
        // 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 on FOCUS_OUT.
        super.focusOutHandler(event);

        setMouseCaptured(false);
        setKeyboardPressed(false);
    }

    /**
     *  @private
     */
    override protected function keyDownHandler(event:KeyboardEvent):void
    {
        if( event.keyCode != Keyboard.SPACE )
            return;
        setKeyboardPressed(true);
        event.updateAfterEvent();
    }

    /**
     *  @private
     */
    override protected function keyUpHandler(event:KeyboardEvent):void
    {
        if( event.keyCode != Keyboard.SPACE )
            return;
        setKeyboardPressed(false);
        
        if( isEnabled )
            dispatchEvent(new MouseEvent(MouseEvent.CLICK));
        event.updateAfterEvent();
    }

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