////////////////////////////////////////////////////////////////////////////////
//
//  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.skins.mobile
{
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;

import mx.core.DPIClassification;
import mx.core.IVisualElement;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.utils.ColorUtil;

import spark.components.ToggleSwitch;
import spark.components.supportClasses.StyleableTextField;
import spark.core.SpriteVisualElement;
import spark.skins.mobile.supportClasses.MobileSkin;
import spark.skins.mobile120.assets.ToggleSwitch_contentShadow;
import spark.skins.mobile160.assets.ToggleSwitch_contentShadow;
import spark.skins.mobile240.assets.ToggleSwitch_contentShadow;
import spark.skins.mobile320.assets.ToggleSwitch_contentShadow;
import spark.skins.mobile480.assets.ToggleSwitch_contentShadow;
import spark.skins.mobile640.assets.ToggleSwitch_contentShadow;

use namespace mx_internal;

/**
 *  ActionScript-based skin for the ToggleSwitch control. 
 *  The colors of the component can
 *  be customized using styles. This class is responsible for most of the
 *  graphics drawing, with some additional fxg assets.
 *  
 *  @langversion 3.0
 *  @playerversion AIR 3
 *  @productversion Flex 4.6
 *
 *  @see spark.components.ToggleSwitch 
 */
public class ToggleSwitchSkin extends MobileSkin
{
    //----------------------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //----------------------------------------------------------------------------------------------
    /**
     *  Constructor.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     **/
    public function ToggleSwitchSkin()
    {
        super();
        
        switch(applicationDPI) 
        {	
			case DPIClassification.DPI_640:
			{
				layoutThumbWidth = 94;
				layoutThumbHeight = 56;
				layoutStrokeWeight = 2;
				layoutBorderSize = 2;
				layoutTextShadowOffset = -2;
				layoutInnerPadding = 14;
				layoutOuterPadding = 22;
				slidingContentOverlayClass = spark.skins.mobile320.assets.ToggleSwitch_contentShadow;
				break;
			}
			case DPIClassification.DPI_480:
			{
				// Note provisional may need changes
				layoutThumbWidth = 140;
				layoutThumbHeight = 84;
				layoutStrokeWeight = 2;
				layoutBorderSize = 2;
				layoutTextShadowOffset = -2;
				layoutInnerPadding = 20;
				layoutOuterPadding = 34;
				slidingContentOverlayClass = spark.skins.mobile480.assets.ToggleSwitch_contentShadow;
				break;
			}		
            case DPIClassification.DPI_320:
            {
                layoutThumbWidth = 94;
                layoutThumbHeight = 56;
                layoutStrokeWeight = 2;
                layoutBorderSize = 2;
                layoutTextShadowOffset = -2;
                layoutInnerPadding = 14;
                layoutOuterPadding = 22;
                slidingContentOverlayClass = spark.skins.mobile320.assets.ToggleSwitch_contentShadow;
                break;
            }
			case DPIClassification.DPI_240:
			{
				layoutThumbWidth = 70;
				layoutThumbHeight = 42;
				layoutStrokeWeight = 2;
				layoutBorderSize = 1;
				layoutTextShadowOffset = -1;
				layoutInnerPadding = 10;
				layoutOuterPadding = 17;
				slidingContentOverlayClass = spark.skins.mobile240.assets.ToggleSwitch_contentShadow;
				break;
			}
			case DPIClassification.DPI_120:
			{
				layoutThumbWidth = 35;
				layoutThumbHeight = 21;
				layoutStrokeWeight = 2;
				layoutBorderSize = 1;
				layoutTextShadowOffset = -1;
				layoutInnerPadding = 5;
				layoutOuterPadding = 9;
				slidingContentOverlayClass = spark.skins.mobile120.assets.ToggleSwitch_contentShadow;
				break;
			}
            default:
            {
                layoutThumbWidth = 47;
                layoutThumbHeight = 28;
                layoutStrokeWeight = 1;
                layoutBorderSize = 1;
                layoutTextShadowOffset = -1;
                layoutInnerPadding = 7;
                layoutOuterPadding = 11;
                slidingContentOverlayClass = spark.skins.mobile160.assets.ToggleSwitch_contentShadow;
                break;
            }
        }
        
        layoutCornerEllipseSize = layoutThumbHeight;
        selectedLabel = resourceManager.getString("components","toggleSwitchSelectedLabel");
        unselectedLabel =  resourceManager.getString("components","toggleSwitchUnselectedLabel");
    }
    
    //----------------------------------------------------------------------------------------------
    //
    //  Variables
    //
    //----------------------------------------------------------------------------------------------
    
    /**
     *  The width to draw the thumb skin part.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutThumbWidth:Number;
    
    /**
     *  The height to draw the thumb skin part.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutThumbHeight:Number;
    
    /**
     *  The corner radius of the thumb and track.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutCornerEllipseSize:Number;
    
    /**
     *  The stroke weight outlining the graphics of the skin.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutStrokeWeight:Number;
    
    /**
     *  The size of the border surrounding the component.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutBorderSize:Number;
    
    /**
     *  The padding between the labels and the thumb.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutInnerPadding:Number;
    
    /**
     *  The padding between the labels and the edge of the track.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutOuterPadding:Number;
    
    /**
     *  The offset between a label and its shadow.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var layoutTextShadowOffset:Number;
    
    /**
     *  The label for the selected side of the component.
     *  Exposed for styling purposes only.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public var selectedLabelDisplay:LabelDisplayComponent;
    
    /**
     *  The label for the unselected side of the component.
     *  Exposed for styling purposes only.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public var unselectedLabelDisplay:LabelDisplayComponent;
    
    /**
     *  The content clipped by the track that slides to match the thumb's
     *  position. 
     *  Contents include a background and the (un)selected labels.
     *  The sliding content is stacked, from back to front, as background,
     *  shadow, foreground.
     */
    private var slidingContentBackground:SpriteVisualElement;
    private var slidingContentForeground:UIComponent;
    private var slidingContentOverlayClass:Class;
    private var slidingContentOverlay:DisplayObject;
    
    /**
     *  The contents inside the skin, not including the outline
     *  stroke
     */
    private var contents:UIComponent;
    
    /**
     *  The thumb erase overlay erases pixels behind the thumb. The thumb
     *  content contains the thumb graphics, and sits above the overlay.
     */
    private var thumbEraseOverlay:Sprite;
    private var thumbContent:Sprite;
    
    //----------------------------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //----------------------------------------------------------------------------------------------
    
    /**
     *  The thumb skin part.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public var thumb:IVisualElement;
    
    /**
     *  The track skin part.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public var track:IVisualElement;
    
    //----------------------------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //----------------------------------------------------------------------------------------------
    
    //----------------------------------
    //  currentState
    //----------------------------------
    /**
     *  @private
     */
    override public function set currentState(value:String):void 
    {
        var isDown:Boolean = currentState && currentState.indexOf("down") >=0;
        
        super.currentState = value;
        
        if (isDown != currentState.indexOf("down") >= 0) 
        {
            invalidateDisplayList();
        }
    }
    
    //----------------------------------------------------------------------------------------------
    //
    //  Properties
    //
    //----------------------------------------------------------------------------------------------
    
    //----------------------------------
    //  hostComponent
    //----------------------------------
    
    private var _hostComponent:ToggleSwitch;
    
    /**
     * @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public function get hostComponent():ToggleSwitch 
    {
        return _hostComponent;
    }
    
    /**
     *  @private
     */
    public function set hostComponent(value:ToggleSwitch):void 
    {
        if (_hostComponent)
            _hostComponent.removeEventListener("thumbPositionChanged", thumbPositionChanged_handler);
        _hostComponent = value;
        if (_hostComponent)
            _hostComponent.addEventListener("thumbPositionChanged", thumbPositionChanged_handler);
    }
    
    //----------------------------------
    //  selectedLabel
    //----------------------------------
    
    private var _selectedLabel:String;
    /**
     *  The text of the label showing when the component is selected.
     *  Subclasses can set or override this property to customize the selected label.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected function get selectedLabel():String 
    {
        return _selectedLabel;
    }
    
    protected function set selectedLabel(value:String):void
    {
        _selectedLabel = value;
    }
    
    //----------------------------------
    //  unselectedLabel
    //----------------------------------
    
    private var _unselectedLabel:String;
    /**
     *  The text of the label showing when the component is not selected.
     *  Subclasses can set or override this property to customize the unselected label.
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected function get unselectedLabel():String 
    {
        return _unselectedLabel;
    }
    
    protected function set unselectedLabel(value:String):void
    {
        _unselectedLabel = value;
    }
    
    //----------------------------------------------------------------------------------------------
    //
    //  Overridden Methods
    //
    //----------------------------------------------------------------------------------------------
    
    /**
     *  @private
     *  Redraw the graphics of the skin as necessary
     */
    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.drawBackground(unscaledWidth, unscaledHeight);
        
        // calculate skin dimensions - outer stroke
        var calculatedContentWidth:Number = Math.max(unscaledWidth - 2 * layoutBorderSize, 
            getElementPreferredWidth(thumb));
        var calculatedContentHeight:Number = Math.max(unscaledHeight - 2 * layoutBorderSize, 
            getElementPreferredHeight(thumb));
        
        drawSlidingContent(calculatedContentWidth, calculatedContentHeight);
        drawTrack(calculatedContentWidth, calculatedContentHeight);
        drawThumb(calculatedContentWidth, calculatedContentHeight);
        drawMask(calculatedContentWidth, calculatedContentHeight);
        
        // simulate outer stroke using a larger filled rounded rect
        graphics.beginFill(0xffffff, 0.3);
        graphics.drawRoundRect(0, (calculatedContentHeight - layoutThumbHeight) / 2, 
            calculatedContentWidth + 2 * layoutBorderSize, 
            layoutThumbHeight + 2 * layoutBorderSize, 
            layoutCornerEllipseSize + layoutBorderSize);
        graphics.endFill();
    }
    
    /**
     *  @private
     *  Resize and reposition as necessary
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void 
    {
        super.layoutContents(unscaledWidth, unscaledHeight);
        
        // calculate skin dimensions - outer stroke
        var calculatedContentWidth:Number = Math.max(unscaledWidth - 2 * layoutBorderSize, 
            getElementPreferredWidth(thumb));
        var calculatedContentHeight:Number = Math.max(unscaledHeight - 2 * layoutBorderSize, 
            getElementPreferredHeight(thumb));
        
        setElementSize(contents, calculatedContentWidth, layoutThumbHeight);
        setElementPosition(contents, layoutBorderSize, 
            layoutBorderSize + (calculatedContentHeight - layoutThumbHeight) / 2);
        
        layoutTrack(calculatedContentWidth, layoutThumbHeight);
        layoutThumb(calculatedContentWidth, layoutThumbHeight);
        // Sliding content must be positioned after the track & thumb have been sized
        layoutSlidingContent(calculatedContentWidth, layoutThumbHeight);
        layoutMask(calculatedContentWidth, layoutThumbHeight);
    }
    
    /**
     *  @private
     */
    override protected function measure():void 
    {
        // The skin must be at least as large as the thumb + outer stroke
        measuredMinWidth = layoutThumbWidth + 2 * layoutBorderSize;
        measuredMinHeight = layoutThumbWidth + 2 * layoutBorderSize;
        
        // The preferred size will display all label text
        var labelWidth:Number = Math.max(getElementPreferredWidth(selectedLabelDisplay), 
            getElementPreferredWidth(unselectedLabelDisplay));
        
        measuredWidth = layoutThumbWidth + labelWidth + layoutInnerPadding + 
            layoutOuterPadding + 2 * layoutBorderSize;
        measuredHeight = layoutThumbHeight + 2 * layoutBorderSize;
    }
    
    /**
     *  @private
     */
    override protected function commitCurrentState():void 
    {
        if (currentState && currentState.indexOf("disabled") >= 0) 
        { 
            alpha = 0.5;
            selectedLabelDisplay.showShadow(false);
            unselectedLabelDisplay.showShadow(false);
        }
        else
        {
            alpha = 1.0;
            selectedLabelDisplay.showShadow(true);
            unselectedLabelDisplay.showShadow(true);
        }
    }
    
    /**
     *  @private
     */
    override protected function createChildren():void 
    {
        super.createChildren();
        
        contents = new UIComponent();
        contents.blendMode = BlendMode.LAYER;
        addChild(contents);
        
        // SlidingContent: background, overlay, labels
        slidingContentBackground = new SpriteVisualElement();
        contents.addChild(slidingContentBackground);
        
        slidingContentOverlay = new slidingContentOverlayClass();
        contents.addChild(slidingContentOverlay);
        
        slidingContentForeground = new UIComponent();
        contents.addChild(slidingContentForeground);
        
        selectedLabelDisplay = new LabelDisplayComponent();
        selectedLabelDisplay.id = "selectedLabelDisplay";
        selectedLabelDisplay.text = selectedLabel;
        selectedLabelDisplay.shadowYOffset = layoutTextShadowOffset;
        slidingContentForeground.addChild(selectedLabelDisplay);
        
        unselectedLabelDisplay = new LabelDisplayComponent();
        unselectedLabelDisplay.id = "unselectedLabelDisplay";
        unselectedLabelDisplay.text = unselectedLabel;
        unselectedLabelDisplay.shadowYOffset = layoutTextShadowOffset;
        slidingContentForeground.addChild(unselectedLabelDisplay);
        
        // Track
        track = new SpriteVisualElement();
        contents.addChild(SpriteVisualElement(track));
        
        // Thumb
        thumb = new SpriteVisualElement();
        contents.addChild(SpriteVisualElement(thumb));
        
        thumbEraseOverlay = new Sprite();
        thumbEraseOverlay.blendMode = BlendMode.ERASE;
        SpriteVisualElement(thumb).addChild(thumbEraseOverlay);
        thumbContent = new Sprite();
        SpriteVisualElement(thumb).addChild(thumbContent);
        
        // Content clipping mask
        var contentMask:Sprite = new SpriteVisualElement();
        contents.mask = contentMask;
        contents.addChild(contentMask);
    }
    
    //----------------------------------------------------------------------------------------------
    //
    //  Methods
    //
    //----------------------------------------------------------------------------------------------
    
    /**
     *  Draw the sliding content background
     *  SlidingContent's x origin matches the thumb's x origin, meaning some of
     *  the background is drawn to the left, and some to the right.
     */
    private function drawSlidingContent(skinWidth:Number, skinHeight:Number):void 
    {
        slidingContentBackground.graphics.clear();
        
        // selected side of the sliding content
        slidingContentBackground.graphics.beginFill(getStyle("accentColor"));
        slidingContentBackground.graphics.drawRect(layoutThumbWidth - skinWidth, 0, skinWidth - layoutThumbWidth / 2, 
            layoutThumbHeight);
        slidingContentBackground.graphics.endFill();
        
        // unselected side of the sliding content
        slidingContentBackground.graphics.beginFill(ColorUtil.adjustBrightness2(getStyle("chromeColor"), -25));
        slidingContentBackground.graphics.drawRect(layoutThumbWidth / 2, 0, skinWidth - layoutThumbWidth / 2, 
            layoutThumbHeight);
        slidingContentBackground.graphics.endFill();
    }
    
    /**
     *  Lay out SlidingContent and its children. Because we only need the x,y
     *  coordinate of SlidingContent, we can ignore its size.
     *  The origin of SlidingContent overlaps the origin of the thumb, and the
     *  positioning is handled by thumbPositionChanged_handler.
     */
    private function layoutSlidingContent(skinWidth:Number, skinHeight:Number):void 
    {
        var visibleTrackWidth:Number = skinWidth - layoutThumbWidth;
        var labelWidth:Number = visibleTrackWidth - layoutInnerPadding - layoutOuterPadding;
        
        setElementSize(selectedLabelDisplay, labelWidth, layoutThumbHeight);
        setElementPosition(selectedLabelDisplay, -visibleTrackWidth + layoutOuterPadding, 0);
        
        setElementSize(unselectedLabelDisplay, labelWidth, layoutThumbHeight);
        setElementPosition(unselectedLabelDisplay, layoutThumbWidth + layoutInnerPadding, 0);
        
        setElementSize(slidingContentOverlay, skinWidth, layoutThumbHeight);
        setElementPosition(slidingContentOverlay, 0, (skinHeight - layoutThumbHeight) / 2);
        
        moveSlidingContent();
    }
    
    /**
     *  Draw the track and its shadow
     */
    private function drawTrack(skinWidth:Number, skinHeight:Number):void 
    {
        var graphics:Graphics = SpriteVisualElement(track).graphics;
        graphics.clear();
        graphics.lineStyle(layoutStrokeWeight, 0, .3);
        graphics.drawRoundRect(layoutStrokeWeight / 2, layoutStrokeWeight / 2, 
            skinWidth - layoutStrokeWeight, 
            (layoutThumbHeight - layoutStrokeWeight), (layoutCornerEllipseSize - layoutStrokeWeight / 2));
        graphics.lineStyle();
    }
    
    /**
     * Resize and reposition the track
     */
    private function layoutTrack(skinWidth:Number, skinHeight:Number):void 
    {
        setElementSize(track, skinWidth, layoutThumbHeight);
        setElementPosition(track, 0, (skinHeight - layoutThumbHeight) / 2);
    }
    
    /**
     * Draw the thumb. The thumb has an outer border, inner gradient, and
     * inner highlight stroke.
     */
    private function drawThumb(skinWidth:Number, skinHeight:Number):void 
    {
        var graphics:Graphics = thumbContent.graphics;
        var colors:Array = [];
        var alphas:Array = [];
        var ratios:Array = [];
        var baseColor:Number = getStyle("chromeColor");
        
        if (currentState && currentState.indexOf("down") >= 0)
            baseColor = ColorUtil.adjustBrightness(baseColor, -60);
        
        graphics.clear();
        
        // Thumb outline
        colors[0] = ColorUtil.adjustBrightness2(baseColor, -70);
        colors[1] = ColorUtil.adjustBrightness2(baseColor, -55);
        
        alphas[0] = 1;
        alphas[1] = 1;
        
        ratios[0] = 0;
        ratios[1] = 255;
        
        colorMatrix.createGradientBox(layoutThumbWidth, layoutThumbHeight, Math.PI / 2);
        graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, colorMatrix);
        graphics.drawRoundRect(0, 0, layoutThumbWidth, layoutThumbHeight, layoutCornerEllipseSize);
        graphics.endFill();
        
        // Base gradient fill, one stroke weight inside outline
        colors[0] = ColorUtil.adjustBrightness2(baseColor, -30);
        colors[1] = baseColor;
        colors[2] = ColorUtil.adjustBrightness2(baseColor, 20);
        
        alphas[2] = 1;
        
        ratios[0] = 0;
        ratios[1] = .7 * 255;
        ratios[2] = 255;
        
        colorMatrix.createGradientBox(layoutThumbWidth - layoutStrokeWeight * 2, 
            layoutThumbHeight - layoutStrokeWeight * 2, Math.PI / 2);
        graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, colorMatrix);
        graphics.drawRoundRect(layoutStrokeWeight, layoutStrokeWeight, 
            layoutThumbWidth - layoutStrokeWeight * 2, 
            layoutThumbHeight - layoutStrokeWeight * 2, layoutCornerEllipseSize - layoutStrokeWeight * 2);
        graphics.endFill();
        
        // Thumb highlight, one stroke weight inside outline
        colors[0] = 0xffffff;
        colors[1] = 0xffffff;
        colors[2] = 0x0;
        
        alphas[0] = .9;
        alphas[1] = 0;
        alphas[2] = .2;
        
        ratios[0] = .33 * 255;
        ratios[1] = .5 * 255;
        ratios[2] = 255;
        
        colorMatrix.createGradientBox(layoutThumbWidth - layoutStrokeWeight * 3, 
            layoutThumbHeight - layoutStrokeWeight * 3, Math.PI / 2);
        graphics.lineStyle(layoutStrokeWeight);
        graphics.lineGradientStyle(GradientType.LINEAR, colors, alphas, ratios, colorMatrix);
        graphics.drawRoundRect(layoutStrokeWeight * 1.5, layoutStrokeWeight * 1.5, 
            layoutThumbWidth - layoutStrokeWeight * 3, layoutThumbHeight - layoutStrokeWeight * 3, 
            layoutCornerEllipseSize - layoutStrokeWeight * 3);
        graphics.lineStyle();

        // Redraw the erase overlay as a silhouette of the thumb
        thumbEraseOverlay.graphics.clear();
        thumbEraseOverlay.graphics.beginFill(0);
        thumbEraseOverlay.graphics.drawRoundRect(0, 0, layoutThumbWidth, layoutThumbHeight, layoutCornerEllipseSize);
        thumbEraseOverlay.graphics.endFill();
    }
    
    /**
     *  Resize the thumb. Its position is handled by the component.
     */
    private function layoutThumb(skinWidth:Number, skinHeight:Number):void 
    {
        setElementSize(thumb, layoutThumbWidth, layoutThumbHeight);
    }
    
    /**
     *  Draw the clipping mask for the component. This is roughly the
     *  same as the track area.
     */
    private function drawMask(skinWidth:Number, skinHeight:Number):void 
    {
        var graphics:Graphics = SpriteVisualElement(contents.mask).graphics;
        graphics.clear();
        graphics.beginFill(0x0);
        graphics.drawRoundRect(0, 0, skinWidth, layoutThumbHeight, layoutCornerEllipseSize);
        graphics.endFill();
    }
    
    /**
     *  Resize and reposition the clipping mask
     */
    private function layoutMask(skinWidth:Number, skinHeight:Number):void 
    {
        setElementSize(contents.mask, skinWidth, layoutThumbHeight);
        setElementPosition(contents.mask, 0, (skinHeight - layoutThumbHeight) / 2);
    }
    
    /**
     *  Move the sliding content to line up with thumbPosition.
     *  This version assumes the thumb and track share the same coordinate system.
     */
    private function moveSlidingContent():void 
    {
        if (!hostComponent)
            return;
        var x:Number = (track.getLayoutBoundsWidth() - thumb.getLayoutBoundsWidth()) * 
            hostComponent.thumbPosition + track.getLayoutBoundsX();
        var y:Number = thumb.getLayoutBoundsY();
        setElementPosition(slidingContentBackground, x, y);
        setElementPosition(slidingContentForeground, x, y);
    }
    
    //----------------------------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //----------------------------------------------------------------------------------------------
    
    /**
     *  When the thumb position changes, reposition the sliding content. 
     */
    private function thumbPositionChanged_handler(event:Event):void 
    {
        moveSlidingContent();
    }
}
}

import flash.events.Event;

import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.FlexEvent;

import spark.components.supportClasses.StyleableTextField;
import spark.core.IDisplayText;

use namespace mx_internal;

/**
 *  @private
 *  Component combining two labels to create the effect of text and its drop
 *  shadow. The component can be used with advanced style selectors and the
 *  styles "color", "textShadowColor", and "textShadowAlpha". Based off of
 *  ActionBar.TitleDisplayComponent. These two should eventually be factored.
 */
class LabelDisplayComponent extends UIComponent implements IDisplayText
{
    public var shadowYOffset:Number = 0;
    private var labelChanged:Boolean = false;
    private var labelDisplay:StyleableTextField;
    private var labelDisplayShadow:StyleableTextField;
    private var _text:String;
    
    public function LabelDisplayComponent() 
    {
        super();
        _text = "";
    }
    
    override public function get baselinePosition():Number 
    {
        return labelDisplay.baselinePosition;
    }
    
    override protected function createChildren():void 
    {
        super.createChildren();
        
        labelDisplay = StyleableTextField(createInFontContext(StyleableTextField));
        labelDisplay.styleName = this;
        labelDisplay.editable = false;
        labelDisplay.selectable = false;
        labelDisplay.multiline = false;
        labelDisplay.wordWrap = false;
        labelDisplay.addEventListener(FlexEvent.VALUE_COMMIT,
            labelDisplay_valueCommitHandler);
        
        labelDisplayShadow = StyleableTextField(createInFontContext(StyleableTextField));
        labelDisplayShadow.styleName = this;
        labelDisplayShadow.colorName = "textShadowColor";
        labelDisplayShadow.editable = false;
        labelDisplayShadow.selectable = false;
        labelDisplayShadow.multiline = false;
        labelDisplayShadow.wordWrap = false;
        
        addChild(labelDisplayShadow);
        addChild(labelDisplay);
    }
    
    override protected function commitProperties():void 
    {
        super.commitProperties();
        
        if (labelChanged)
        {
            labelDisplay.text = text;
            invalidateSize();
            invalidateDisplayList();
            labelChanged = false;
        }
    }
    
    override protected function measure():void 
    {
        if (labelDisplay.isTruncated)
            labelDisplay.text = text;
        labelDisplay.commitStyles();
        measuredWidth = labelDisplay.getPreferredBoundsWidth();
        measuredHeight = labelDisplay.getPreferredBoundsHeight();
    }
    
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
    {
        if (labelDisplay.isTruncated)
            labelDisplay.text = text;
        labelDisplay.commitStyles();
        
        var labelHeight:Number = labelDisplay.getPreferredBoundsHeight();
        var labelY:Number = (unscaledHeight - labelHeight) / 2;
        
        var labelWidth:Number = Math.min(unscaledWidth, labelDisplay.getPreferredBoundsWidth());
        var labelX:Number = (unscaledWidth - labelWidth) / 2;
        
        labelDisplay.setLayoutBoundsSize(labelWidth, labelHeight);
        labelDisplay.setLayoutBoundsPosition(labelX, labelY);
        
        labelDisplay.truncateToFit();
        
        labelDisplayShadow.commitStyles();
        labelDisplayShadow.setLayoutBoundsSize(labelWidth, labelHeight);
        labelDisplayShadow.setLayoutBoundsPosition(labelX, labelY + shadowYOffset);
        
        labelDisplayShadow.alpha = getStyle("textShadowAlpha");
        
        // unless the label was truncated, labelDisplayShadow.text was set in
        // the value commit handler
        if (labelDisplay.isTruncated)
            labelDisplayShadow.text = labelDisplay.text;
    }
    
    private function labelDisplay_valueCommitHandler(event:Event):void 
    {
        labelDisplayShadow.text = labelDisplay.text;
    }
    
    public function get text():String 
    {
        return _text;
    }
    
    public function set text(value:String):void 
    {
        _text = value;
        labelChanged = true;
        invalidateProperties();
    }
    
    public function get isTruncated():Boolean 
    {
        return labelDisplay.isTruncated;
    }
    
    public function showShadow(value:Boolean):void 
    {
        labelDisplayShadow.visible = value;
    }
}