////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package spark.components.supportClasses
{

import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.MouseEvent;
import flash.geom.Point;

import mx.core.InteractionMode;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
import mx.events.SandboxMouseEvent;
import mx.events.TouchInteractionEvent;

import spark.components.Button;
import spark.events.TrackBaseEvent;

/**
 *  Dispatched when the value of the control changes
 *  as a result of user interaction.
 *
 *  @eventType flash.events.Event.CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Event(name="change", type="flash.events.Event")]

/**
 *  Dispatched at the end of a user interaction 
 *  or when an animation ends.
 *
 *  @eventType mx.events.FlexEvent.CHANGE_END
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Event(name="changeEnd", type="mx.events.FlexEvent")]

/**
 *  Dispatched at the start of a user interaction 
 *  or when an animation starts.
 *
 *  @eventType mx.events.FlexEvent.CHANGE_START
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Event(name="changeStart", type="mx.events.FlexEvent")]

/**
 *  Dispatched when the thumb is pressed and then moved by the mouse.
 *  This event is always preceded by a <code>thumbPress</code> event.
 * 
 *  @eventType spark.events.TrackBaseEvent.THUMB_DRAG
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Event(name="thumbDrag", type="spark.events.TrackBaseEvent")]

/**
 *  Dispatched when the thumb is pressed, meaning
 *  the user presses the mouse button over the thumb.
 *
 *  @eventType spark.events.TrackBaseEvent.THUMB_PRESS
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Event(name="thumbPress", type="spark.events.TrackBaseEvent")]

/**
 *  Dispatched when the thumb is released, 
 *  meaning the user releases the mouse button after 
 *  a <code>thumbPress</code> event.
 *
 *  @eventType spark.events.TrackBaseEvent.THUMB_RELEASE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Event(name="thumbRelease", type="spark.events.TrackBaseEvent")]

/**
 *  Normal State
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[SkinState("normal")]

/**
 *  Disabled State
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[SkinState("disabled")]

/**
 *  Duration in milliseconds for a sliding animation
 *  when you click on the track to move a thumb. This style is
 *  used for both Sliders and Scrollbars. For Sliders, any click
 *  on the track will cause an animation using this style, as the thumb
 *  will move to the clicked position. For ScrollBars, this style is
 *  used only when shift-clicking on the track, which causes the thumb
 *  to move to the clicked position. Clicking on a ScrollBar track when
 *  the shift key is not pressed will result in paging behavior instead.
 *  The <code>smoothScrolling</code> style must also be set on the
 *  ScrollBar to get animated behavior when shift-clicking.
 *  
 * <p>This duration is for an animation that covers the entire distance of the 
 * track; smaller distances will use a proportionally smaller duration.</p>
 *
 *  @default 300
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[Style(name="slideDuration", type="Number", format="Time", inherit="no")]

/**
 *  The TrackBase class is a base class for components with a track
 *  and one or more thumb buttons, such as Slider and ScrollBar. It
 *  declares two required skin parts: <code>thumb</code> and
 *  <code>track</code>. 
 *  The TrackBase class also provides the code for
 *  dragging the thumb button, which is shared by the Slider and ScrollBar classes.
 * 
 *  @mxml
 *
 *  <p>The <code>&lt;s:TrackBase&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:TrackBase
 *    <strong>Styles</strong>
 *    slideDuration="300"
 * 
 *    <strong>Events</strong>
 *    change="<i>No default</i>"
 *    changing="<i>No default</i>"
 *    thumbDrag="<i>No default</i>"
 *    thumbPress="<i>No default</i>"
 *    thumbRelease="<i>No default</i>"
 *  /&gt;
 *  </pre> 
 * 
 *  @see spark.components.supportClasses.Slider
 *  @see spark.components.supportClasses.ScrollBar
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
public class TrackBase extends Range
{
    include "../../core/Version.as";

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

    /**
     *  Constructor. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function TrackBase():void
    {
        super();
        addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
    }

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

    [SkinPart(required="false")]
    
    /**
     *  A skin part that defines a button
     *  that can be dragged along the track to increase or
     *  decrease the <code>value</code> property.
     *  Updates to the <code>value</code> property 
     *  automatically update the position of the thumb button
     *  with respect to the track.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public var thumb:Button;
    
    [SkinPart(required="false")]
    
    /**
     *  A skin part that defines a button
     *  that, when  pressed, sets the <code>value</code> property
     *  to the value corresponding with the current button position on the track.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public var track:Button; 

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

    private var mouseDownTarget:DisplayObject;

    //--------------------------------------------------------------------------
    //
    //  Overridden properties: Range
    //
    //--------------------------------------------------------------------------
    
    //---------------------------------
    // maximum
    //---------------------------------     
    
    [Inspectable(category="General", defaultValue="100.0")]
    
    /**
     *  @private
     *  Overidden so that this property can be the source of a binding expression.
     */
     override public function get maximum():Number
     {
         return super.maximum;
     }
    
    /**
     *  @private
     */
    override public function set maximum(value:Number):void
    {
        if (value == super.maximum)
            return;
        
        super.maximum = value;
        invalidateDisplayList();
    }

    //---------------------------------
    // minimum
    //---------------------------------     

    [Inspectable(category="General", defaultValue="0.0")]
    
    /**
     *  @private
     *  Overidden so that this property can be the source of a binding expression.
     */
     override public function get minimum():Number
     {
         return super.minimum;
     }
     
    /**
     *  @private
     */
    override public function set minimum(value:Number):void
    {
        if (value == super.minimum)
            return;
        
        super.minimum = value;
        invalidateDisplayList();
    }
    
    //---------------------------------
    // scaleX
    //---------------------------------
    
    /**
     *  @private
     *  Overridden so that we can call invalidateDisplayList() 
     *  when scaleX changes since the positioning of the thumb 
     *  is incorrect when scaleX = 0 thanks to globalToLocal/localToGlobal().
     * 
     *  <p>We override it here in TrackBase instead of where the issue 
     *  actually exists (HScrollBar, HSlider, VScrollBar, VSlider) because it 
     *  is easier this way and most subclasses who rely on updateSkinDisplayList() 
     *  will probably run in to this issue.</p>
     */
    override public function set scaleX(value:Number):void
    {
        if (value == super.scaleX)
            return;
        
        // if we were scaled at 0 and are being set to something else,
        // invalidate the display list (see comment above)
        if (super.scaleX == 0)
            invalidateDisplayList();
        
        super.scaleX = value;
    }
    
    //---------------------------------
    // scaleY
    //---------------------------------
    
    /**
     *  @private
     *  Overridden so that we can call invalidateDisplayList() 
     *  when scaleY changes since the positioning of the thumb 
     *  is incorrect when scaleY = 0 thanks to globalToLocal/localToGlobal().
     * 
     *  <p>We override it here in TrackBase instead of where the issue 
     *  actually exists (HScrollBar, HSlider, VScrollBar, VSlider) because it 
     *  is easier this way and most subclasses who rely on updateSkinDisplayList() 
     *  will probably run in to this issue.</p>
     */
    override public function set scaleY(value:Number):void
    {
        if (value == super.scaleY)
            return;
        
        // if we were scaled at 0 and are being set to something else,
        // invalidate the display list (see comment above)
        if (super.scaleY == 0)
            invalidateDisplayList();
        
        super.scaleY = value;
    }
    
    //---------------------------------
    // value
    //---------------------------------     

    [Bindable(event="valueCommit")]  // Warning: must match the Bindable tag in Range
    [Inspectable(category="General", defaultValue="0.0")]
    
    /**
     *  @private 
     *  Overidden so that this property can be the source of a binding expression.
     */
    override public function get value():Number
    {
        return super.value;
    }

    /**
     *  @private
     */
    override public function set value(newValue:Number):void
    {
        if (newValue == super.value)
            return;
        
        super.value = newValue;
        invalidateDisplayList();
    }
  
    /**
     *  @private
     */
    override protected function setValue(value:Number):void
    {
        super.setValue(value);
        invalidateDisplayList();
    }
    
    //--------------------------------------------------------------------------
    //
    // Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Converts a track-relative x,y pixel location into a value between 
     *  the minimum and maximum, inclusive.  
     * 
     *  <p>TrackBase subclasses must override this method and perform conversions
     *  that take their own geometry into account.
     * 
     *  For example, a vertical slider might compute a value like this:
     *  <pre>
     *  return (y / track.height) * (maximum - minimum);
     *  </pre>
     *  </p>
     * 
     *  <p>By default, this method returns <code>minimum</code>.</p>
     * 
     *  @param x The x coordinate of the location relative to the track's origin.
     *  @param y The y coordinate of the location relative to the track's origin.
     *  @return A value between the minimum and maximum, inclusive.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    protected function pointToValue(x:Number, y:Number):Number
    {
        return minimum;
    }

    /**
     *  @private
     */
    override public function changeValueByStep(increase:Boolean = true):void
    {
        var prevValue:Number = this.value;
        
        super.changeValueByStep(increase);
        
        if (value != prevValue)
            dispatchEvent(new Event(Event.CHANGE));
    }
    
    /**
     *  @private   
     */
    override protected function getCurrentSkinState():String
    {
        return enabled ? "normal" : "disabled";
    }
    
    /**
     *  @private
     *  Warning: the goal of the listeners added here (and removed below) is to 
     *  give the TrackBase a change to fixup the thumb's size and position
     *  after the skin's BasicLayout has run.   This particular implementation
     *  is a hack and it begs a solution to the general problem of what we've
     *  called "cooperative layout".   More about that here:
     *  http://opensource.adobe.com/wiki/display/flexsdk/Cooperative+Subtree+Layout
     */
    override protected function partAdded(partName:String, instance:Object):void
    {
		super.partAdded(partName, instance);

        if (instance == thumb)
        {
            thumb.addEventListener(MouseEvent.MOUSE_DOWN, thumb_mouseDownHandler);
            thumb.addEventListener(TouchInteractionEvent.TOUCH_INTERACTION_STARTING, thumb_touchInteractionStartingHandler);
            thumb.addEventListener(ResizeEvent.RESIZE, thumb_resizeHandler);
            thumb.addEventListener(FlexEvent.UPDATE_COMPLETE, thumb_updateCompleteHandler);
            thumb.stickyHighlighting = true;
        }
        else if (instance == track)
        {
            track.addEventListener(ResizeEvent.RESIZE, track_resizeHandler);
            
            // track is only clickable if in mouse interactionMode
            if (getStyle("interactionMode") == InteractionMode.MOUSE)
                track.addEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler);
        }
    }

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

        if (instance == thumb)
        {
            thumb.removeEventListener(MouseEvent.MOUSE_DOWN, thumb_mouseDownHandler);
            thumb.removeEventListener(TouchInteractionEvent.TOUCH_INTERACTION_STARTING, thumb_touchInteractionStartingHandler);
            thumb.removeEventListener(ResizeEvent.RESIZE, thumb_resizeHandler);            
            thumb.removeEventListener(FlexEvent.UPDATE_COMPLETE, thumb_updateCompleteHandler);            
        }
        else if (instance == track)
        {
            track.removeEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler);
            track.removeEventListener(ResizeEvent.RESIZE, track_resizeHandler);
        }
    }
    
    /**
     *  @private
     */ 
    override public function styleChanged(styleName:String):void
    {
        var allStyles:Boolean = styleName == null || styleName == "styleName";
        
        super.styleChanged(styleName);
        
        if (allStyles || styleName == "interactionMode")
        {
            if (track)
            {
                // track is only clickable if in mouse interactionMode
                if (getStyle("interactionMode") == InteractionMode.MOUSE)
                    track.addEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler);
                else
                    track.removeEventListener(MouseEvent.MOUSE_DOWN, track_mouseDownHandler);
            }
        }
    }
    
    /**
     *  @private
     *  If the component is in focus, then it should respond to mouseWheel events. We listen to these
     *  events on systemManager in the capture phase because this behavior should have the highest priority. 
     */ 
    override protected function focusInHandler(event:FocusEvent):void
    {
        super.focusInHandler(event);
        systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_WHEEL, system_mouseWheelHandler, true);
    }
    
    /**
     *  @private
     */
    override protected function focusOutHandler(event:FocusEvent):void
    {
        super.focusOutHandler(event);
        systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_WHEEL, system_mouseWheelHandler, true);
    }
    
    /**
     *  @private
     */
    override protected function updateDisplayList(w:Number, h:Number):void
    {
        super.updateDisplayList(w, h);
        updateSkinDisplayList();
    }

    //--------------------------------------------------------------------------
    // 
    // Event Handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Location of the mouse down event on the thumb, relative to the thumb's origin.
     *  Used to update the value property when the mouse is dragged. 
     */
    private var clickOffset:Point;
    
    /**
     *  Sets the bounds of skin parts, typically the thumb, whose geometry isn't fully
     *  specified by the skin's layout.
     * 
     *  <p>Most subclasses override this method to update the thumb's size, position, and 
     *  visibility, based on the <code>minimum</code>, <code>maximum</code>, and <code>value</code> properties. </p>
     * 
     *  <p>By default, this method does nothing.</p> 
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     * 
     */
    protected function updateSkinDisplayList():void {}

    /**
     *  @private
     *  Redraw whenever added to the stage to ensure the calculations
     *  in updateSkinDisplayList() are correct.
     */
    private function addedToStageHandler(event:Event):void
    {
        updateSkinDisplayList();
    }
    
    /**
     *  @private
     */
    private function track_resizeHandler(event:Event):void
    {
        updateSkinDisplayList();
    }

    /**
     *  @private
     */
    private function thumb_resizeHandler(event:Event):void
    {
        updateSkinDisplayList();
    }
    
    /**
     *  @private
     */
    private function thumb_updateCompleteHandler(event:Event):void
    {
        updateSkinDisplayList();
        thumb.removeEventListener(FlexEvent.UPDATE_COMPLETE, thumb_updateCompleteHandler);
    }
    
    /**
     *  @private
     *  Handles the <code>mouseWheel</code> event when the component is in focus. The thumb is 
     *  moved by the amount of the mouse event delta multiplied by the <code>stepSize</code>.  
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */ 
    protected function system_mouseWheelHandler(event:MouseEvent):void
    {
        if (!event.isDefaultPrevented())
        {
            var newValue:Number = nearestValidValue(value + event.delta * stepSize, stepSize);
            setValue(newValue);
            dispatchEvent(new Event(Event.CHANGE));
            event.preventDefault();
        }
    }

    //---------------------------------
    // Thumb dragging handlers
    //---------------------------------
    
    /**
     *  @private
     *  Handle mouse-down events on the scroll thumb. Records 
     *  the mouse down point in clickOffset.
     */
    protected function thumb_mouseDownHandler(event:MouseEvent):void
    {        
        systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_MOVE, 
            system_mouseMoveHandler, true);
        systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_UP, 
            system_mouseUpHandler, true);
        systemManager.getSandboxRoot().addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, 
            system_mouseUpHandler);
        
        clickOffset = thumb.globalToLocal(new Point(event.stageX, event.stageY));
        
        dispatchEvent(new TrackBaseEvent(TrackBaseEvent.THUMB_PRESS));
        dispatchEvent(new FlexEvent(FlexEvent.CHANGE_START));
    }
    
    /**
     *  @private
     */
    protected function thumb_touchInteractionStartingHandler(event:TouchInteractionEvent):void
    {
        // cancel this event b/c I want to control it
        event.preventDefault();
    }

    /**
     *  @private
     *  Capture mouse-move events anywhere on or off the stage.
     *  First, we calculate the new value based on the new position
     *  using calculateNewValue(). Then, we move the thumb to 
     *  the new value's position. Last, we set the value and
     *  dispatch a "change" event if the value changes. 
     */
    protected function system_mouseMoveHandler(event:MouseEvent):void
    {
        if (!track)
            return;
        
        var p:Point = track.globalToLocal(new Point(event.stageX, event.stageY));
        var newValue:Number = pointToValue(p.x - clickOffset.x, p.y - clickOffset.y);
        newValue = nearestValidValue(newValue, snapInterval);

        if (newValue != value)
        {
            setValue(newValue); 
            dispatchEvent(new TrackBaseEvent(TrackBaseEvent.THUMB_DRAG));
            dispatchEvent(new Event(Event.CHANGE));
        }
    
        event.updateAfterEvent();
    }
 
    /**
     *  @private
     *  Handle mouse-up events anywhere on or off the stage.
     */
    protected function system_mouseUpHandler(event:Event):void
    {
        systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_MOVE, 
            system_mouseMoveHandler, true);
        systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_UP, 
            system_mouseUpHandler, true);
        systemManager.getSandboxRoot().removeEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, 
            system_mouseUpHandler);
        
        dispatchEvent(new TrackBaseEvent(TrackBaseEvent.THUMB_RELEASE));
        dispatchEvent(new FlexEvent(FlexEvent.CHANGE_END));
    }

    //---------------------------------
    // Track down handlers
    //---------------------------------
    
    /**
     *  @private
     *  Handle mouse-down events for the scroll track. Subclasses
     *  should override this method if they want the track to
     *  recognize mouse clicks on the track.
     */
    protected function track_mouseDownHandler(event:MouseEvent):void { }
    
    //---------------------------------
    // Mouse click handlers
    //---------------------------------
    
    /**
     *  @private
     *  Capture any mouse down event and listen for a mouse up event
     */  
    private function mouseDownHandler(event:MouseEvent):void
    {
        systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_UP, 
                                                        system_mouseUpSomewhereHandler, true);
        systemManager.getSandboxRoot().addEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, 
                                                        system_mouseUpSomewhereHandler);
        
        mouseDownTarget = DisplayObject(event.target);      
    }
    
    /**
     *  @private
     */
    private function system_mouseUpSomewhereHandler(event:Event):void
    {
        systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_UP, 
                                                           system_mouseUpSomewhereHandler, true);
        systemManager.getSandboxRoot().removeEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE, 
                                                           system_mouseUpSomewhereHandler);
        
        // If we got a mouse down followed by a mouse up on a different target in the skin, 
        // we want to dispatch a click event. 
        if (mouseDownTarget != event.target && event is MouseEvent && contains(DisplayObject(event.target)))
        { 
            var mEvent:MouseEvent = event as MouseEvent;
            // Convert the mouse coordinates from the target to the TrackBase
            var mousePoint:Point = new Point(mEvent.localX, mEvent.localY);
            mousePoint = globalToLocal(DisplayObject(event.target).localToGlobal(mousePoint));
            
            dispatchEvent(new MouseEvent(MouseEvent.CLICK, mEvent.bubbles, mEvent.cancelable, mousePoint.x,
                                     mousePoint.y, mEvent.relatedObject, mEvent.ctrlKey, mEvent.altKey,
                                     mEvent.shiftKey, mEvent.buttonDown, mEvent.delta));
        }
        
        mouseDownTarget = null;
    }
}

}
