////////////////////////////////////////////////////////////////////////////////
//
//  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.GradientType;
import flash.events.Event;
import flash.text.TextFormatAlign;

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

import spark.components.ActionBar;
import spark.components.Group;
import spark.components.supportClasses.StyleableTextField;
import spark.core.SpriteVisualElement;
import spark.layouts.HorizontalAlign;
import spark.layouts.HorizontalLayout;
import spark.layouts.VerticalAlign;
import spark.skins.mobile.supportClasses.MobileSkin;
import spark.skins.mobile160.assets.ActionBarBackground;
import spark.skins.mobile240.assets.ActionBarBackground;
import spark.skins.mobile320.assets.ActionBarBackground;
import spark.skins.mobile480.assets.ActionBarBackground;

use namespace mx_internal;

/**
 *  The default skin class for the Spark ActionBar component in mobile
 *  applications.
 *  
 *  @see spark.components.ActionBar
 *  @see spark.skins.mobile.TransparentNavigationButtonSkin
 *  @see spark.skins.mobile.BeveledBackButtonSkin
 *  @see spark.skins.mobile.TransparentActionButtonSkin
 *  @see spark.skins.mobile.BeveledActionButtonSkin
 *  
 *  @langversion 3.0
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class ActionBarSkin extends MobileSkin
{
    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    mx_internal static const ACTIONBAR_CHROME_COLOR_RATIOS:Array = [0, 80];
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function ActionBarSkin()
    {
        super();
        
        switch (applicationDPI)
        {
			case DPIClassification.DPI_480:
			{
				// Note provisional may need changes
				borderSize = 2;
				layoutShadowHeight = 9;
				layoutContentGroupHeight = 130;
				layoutTitleGroupHorizontalPadding = 40;
				
				borderClass = spark.skins.mobile240.assets.ActionBarBackground;
				
				break;
			}
            case DPIClassification.DPI_320:
            {
                borderSize = 2;
                layoutShadowHeight = 6;
                layoutContentGroupHeight = 86;
                layoutTitleGroupHorizontalPadding = 26;
                
                borderClass = spark.skins.mobile320.assets.ActionBarBackground;
                
                break;
            }
            case DPIClassification.DPI_240:
            {
                borderSize = 1;
                layoutShadowHeight = 3;
                layoutContentGroupHeight = 65;
                layoutTitleGroupHorizontalPadding = 20;
                
                borderClass = spark.skins.mobile240.assets.ActionBarBackground;
                
                break;
            }
            default:
            {
                // default DPI_160
                borderSize = 1;
                layoutShadowHeight = 3;
                layoutContentGroupHeight = 43;
                layoutTitleGroupHorizontalPadding = 13;
                
                borderClass = spark.skins.mobile160.assets.ActionBarBackground;
                
                break;
            }
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Graphics variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  FXG Class reference for the ActionBar background border graphic.
     *
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var borderClass:Class;
    
    //--------------------------------------------------------------------------
    //
    //  Layout variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private var borderSize:uint;
    
    /**
     *  Height of shadow embedded in borderClass graphic.
     *
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var layoutShadowHeight:uint;
    
    /**
     *  Default height for navigationGroup, titleGroup and actionGroup.
     *
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var layoutContentGroupHeight:uint;
    
    /**
     *  Default horizontal padding for the titleGroup and titleDisplay.
     *
     *  @langversion 3.0
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var layoutTitleGroupHorizontalPadding:uint;
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    /** 
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:ActionBar;
    
    /**
     *  @private
     */
    private var _navigationVisible:Boolean = false;
    
    /**
     *  @private
     */
    private var _titleContentVisible:Boolean = false;
    
    /**
     *  @private
     */
    private var _actionVisible:Boolean = false;
    
    /**
     *  @private
     */
    private var border:SpriteVisualElement;
    
    //--------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @copy spark.components.ActionBar#navigationGroup
     */
    public var navigationGroup:Group;
    
    /**
     *  @copy spark.components.ActionBar#titleGroup
     */
    public var titleGroup:Group;
    
    /**
     *  @copy spark.components.ActionBar#actionGroup
     */
    public var actionGroup:Group;
    
    /**
     *  @copy spark.components.ActionBar#titleDisplay
     * 
     *  @private
     *  Wraps a StyleableTextField in a UIComponent to be compatible with
     *  ViewTransition effects.
     */
    public var titleDisplay:TitleDisplayComponent;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        if (borderClass)
        {
            border = new borderClass();
            addChild(border);
        }
        
        navigationGroup = new Group();
        var hLayout:HorizontalLayout = new HorizontalLayout();
        hLayout.horizontalAlign = HorizontalAlign.LEFT;
        hLayout.verticalAlign = VerticalAlign.MIDDLE;
        hLayout.gap = 0;
        hLayout.paddingLeft = hLayout.paddingTop = hLayout.paddingRight = 
            hLayout.paddingBottom = 0;
        navigationGroup.layout = hLayout;
        navigationGroup.id = "navigationGroup";
        
        titleGroup = new Group();
        hLayout = new HorizontalLayout();
        hLayout.horizontalAlign = HorizontalAlign.LEFT;
        hLayout.verticalAlign = VerticalAlign.MIDDLE;
        hLayout.gap = 0;
        hLayout.paddingLeft = hLayout.paddingRight = layoutTitleGroupHorizontalPadding; 
        hLayout.paddingTop = hLayout.paddingBottom = 0;
        titleGroup.layout = hLayout;
        titleGroup.id = "titleGroup";
        
        actionGroup = new Group();
        hLayout = new HorizontalLayout();
        hLayout.horizontalAlign = HorizontalAlign.RIGHT;
        hLayout.verticalAlign = VerticalAlign.MIDDLE;
        hLayout.gap = 0;
        hLayout.paddingLeft = hLayout.paddingTop = hLayout.paddingRight = 
            hLayout.paddingBottom = 0;
        actionGroup.layout = hLayout;
        actionGroup.id = "actionGroup";
        
        titleDisplay = new TitleDisplayComponent();
        titleDisplay.id = "titleDisplay";
        
        // initialize titleAlign style (center is managed explicitly in layoutContents)
        var titleAlign:String = getStyle("titleAlign");
        titleAlign = (titleAlign == "center") ? TextFormatAlign.LEFT : titleAlign;
        titleDisplay.setStyle("textAlign", titleAlign);
        
        addChild(navigationGroup);
        addChild(titleGroup);
        addChild(actionGroup);
        addChild(titleDisplay);
    }

    /**
     *  @private
     */
    override protected function measure():void
    {
        var titleWidth:Number = 0;
        var titleHeight:Number = 0;
        
        if (_titleContentVisible)
        {
            titleWidth = titleGroup.getPreferredBoundsWidth();
            titleHeight = titleGroup.getPreferredBoundsHeight();
        }
        else
        {
            // use titleLayout for paddingLeft and paddingRight
            var layoutObject:Object = hostComponent.titleLayout;
            titleWidth = ((layoutObject.paddingLeft) ? Number(layoutObject.paddingLeft) : 0)
                + ((layoutObject.paddingRight) ? Number(layoutObject.paddingRight) : 0)
                + titleDisplay.getPreferredBoundsWidth();
            
            titleHeight = titleDisplay.getPreferredBoundsHeight();
        }
        
        measuredWidth =
            getStyle("paddingLeft")
            + navigationGroup.getPreferredBoundsWidth()
            + titleWidth
            + actionGroup.getPreferredBoundsWidth()
            + getStyle("paddingRight");
        
        // measuredHeight is contentGroupHeight, 2x border on top and bottom
        measuredHeight =
            getStyle("paddingTop")
            + Math.max(layoutContentGroupHeight,
                navigationGroup.getPreferredBoundsHeight(), 
                actionGroup.getPreferredBoundsHeight(),
                titleHeight)
            + getStyle("paddingBottom");
    }
    
    /**
     *  @private
     */
    override protected function commitCurrentState():void
    {
        super.commitCurrentState();
        
        _titleContentVisible = currentState.indexOf("titleContent") >= 0;
        _navigationVisible = currentState.indexOf("Navigation") >= 0;
        _actionVisible = currentState.indexOf("Action") >= 0;
        
        invalidateSize();
        invalidateDisplayList();
    }
    
    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        if (titleDisplay)
        {
            var allStyles:Boolean = !styleProp || styleProp == "styleName";
            
            if (allStyles || (styleProp == "titleAlign"))
            {
                var titleAlign:String = getStyle("titleAlign");
                
                if (titleAlign == "center")
                { 
                    // If the title align is set to center, the alignment is set to LEFT
                    // so that the skin can manually center the component in layoutContents
                    titleDisplay.setStyle("textAlign", TextFormatAlign.LEFT);
                }
                else
                {
                    titleDisplay.setStyle("textAlign", titleAlign);
                }
            }
        }
        
        super.styleChanged(styleProp);
    }
    
    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);
        
        var navigationGroupWidth:Number = 0;
        
        var paddingLeft:Number   = getStyle("paddingLeft"); 
        var paddingRight:Number  = getStyle("paddingRight");
        var paddingTop:Number    = getStyle("paddingTop");
        var paddingBottom:Number = getStyle("paddingBottom");
        
        var titleCompX:Number = paddingLeft;
        var titleCompWidth:Number = 0;
        
        var actionGroupX:Number = unscaledWidth;
        var actionGroupWidth:Number = 0;
        
        // remove top and bottom padding from content group height
        var contentGroupsHeight:Number = Math.max(0, unscaledHeight - paddingTop - paddingBottom);
        
        if (border)
        {
            // FXG uses scale-9, drop shadow is drawn outside the bounds
            setElementSize(border, unscaledWidth, unscaledHeight + layoutShadowHeight);
        }
        
        // position groups, overlap of navigation and action groups is allowed
        // when overlap occurs, titleDisplay/titleGroup is not visible
        if (_navigationVisible)
        {
            navigationGroupWidth = navigationGroup.getPreferredBoundsWidth();
            titleCompX += navigationGroupWidth;
            
            setElementSize(navigationGroup, navigationGroupWidth, contentGroupsHeight);
            setElementPosition(navigationGroup, paddingLeft, paddingTop);
        }
        
        if (_actionVisible)
        {
            // actionGroup x position can be negative
            actionGroupWidth = actionGroup.getPreferredBoundsWidth();
            actionGroupX = unscaledWidth - actionGroupWidth - paddingRight;
            
            setElementSize(actionGroup, actionGroupWidth, contentGroupsHeight);
            setElementPosition(actionGroup, actionGroupX, paddingTop);
        }
        
        // titleGroup or titleDisplay is given remaining width after navigation
        // and action groups preferred widths
        titleCompWidth = unscaledWidth - navigationGroupWidth - actionGroupWidth
            - paddingLeft - paddingRight;
        
        if (titleCompWidth <= 0)
        {
            titleDisplay.visible = false;
            titleGroup.visible = false;
        }
        else if (_titleContentVisible)
        {
            titleDisplay.visible = false;
            titleGroup.visible = true;
            
            // use titleGroup for titleContent
            setElementSize(titleGroup, titleCompWidth, contentGroupsHeight);
            setElementPosition(titleGroup, titleCompX, paddingTop);
        }
        else
        {
            // use titleDisplay for title text label
            titleGroup.visible = false;
            
            // use titleLayout for paddingLeft and paddingRight
            var layoutObject:Object = hostComponent.titleLayout;
            var titlePaddingLeft:Number = (layoutObject.paddingLeft) ? Number(layoutObject.paddingLeft) : 0;
            var titlePaddingRight:Number = (layoutObject.paddingRight) ? Number(layoutObject.paddingRight) : 0;
            
            // align titleDisplay to the absolute center
            var titleAlign:String = getStyle("titleAlign");
            
            // check for available width after padding
            if ((titleCompWidth - titlePaddingLeft - titlePaddingRight) <= 0)
            {
                titleCompX = 0;
                titleCompWidth = 0;
            }
            else if (titleAlign == "center")
            { 
                // use LEFT instead of CENTER
                titleCompWidth = titleDisplay.getExplicitOrMeasuredWidth();
                
                // use x position of titleDisplay to implement CENTER
                titleCompX = Math.round((unscaledWidth - titleCompWidth) / 2); 
                
                var navigationOverlap:Number = navigationGroupWidth + titlePaddingLeft - titleCompX;
                var actionOverlap:Number = (titleCompX + titleCompWidth + titlePaddingRight) - actionGroupX;
                
                // shrink and/or move titleDisplay width if there is any
                // overlap after centering
                if ((navigationOverlap > 0) && (actionOverlap > 0))
                {
                    // remaining width
                    titleCompX = navigationGroupWidth + titlePaddingLeft;
                    titleCompWidth = unscaledWidth - navigationGroupWidth - actionGroupWidth - titlePaddingLeft - titlePaddingRight;
                }
                else if ((navigationOverlap > 0) || (actionOverlap > 0))
                {
                    if (navigationOverlap > 0)
                    {
                        // nudge to the right
                        titleCompX += navigationOverlap;
                    }
                    else if (actionOverlap > 0)
                    {
                        // nudge to the left
                        titleCompX -= actionOverlap;
                        
                        // force left padding
                        if (titleCompX < (navigationGroupWidth + titlePaddingLeft))
                            titleCompX = navigationGroupWidth + titlePaddingLeft;
                    }
                    
                    // recompute action overlap and force right padding
                    actionOverlap = (titleCompX + titleCompWidth + titlePaddingRight) - actionGroupX;
                    
                    if (actionOverlap > 0)
                        titleCompWidth -= actionOverlap;
                }
            }
            else
            {
                // implement padding by adjusting width and position
                titleCompX += titlePaddingLeft;
                titleCompWidth = titleCompWidth - titlePaddingLeft - titlePaddingRight;
            }
            
            // check for negative width
            titleCompWidth = (titleCompWidth < 0) ? 0 : titleCompWidth;
            
            setElementSize(titleDisplay, titleCompWidth, contentGroupsHeight);
            setElementPosition(titleDisplay, titleCompX, paddingTop);
            
            titleDisplay.visible = true;
        }
    }
    
    /**
     *  @private
     */
    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.drawBackground(unscaledWidth, unscaledHeight);

        var chromeColor:uint = getStyle("chromeColor");
        var backgroundAlphaValue:Number = getStyle("backgroundAlpha");
        var colors:Array = [];
        
        // apply alpha to chromeColor fill only
        var backgroundAlphas:Array = [backgroundAlphaValue, backgroundAlphaValue];
        
        // exclude top and bottom 1px borders
        colorMatrix.createGradientBox(unscaledWidth, unscaledHeight - (borderSize * 2), Math.PI / 2, 0, 0);
        
        colors[0] = ColorUtil.adjustBrightness2(chromeColor, 20);
        colors[1] = chromeColor;
        
        graphics.beginGradientFill(GradientType.LINEAR, colors, backgroundAlphas, ACTIONBAR_CHROME_COLOR_RATIOS, colorMatrix);
        graphics.drawRect(0, borderSize, unscaledWidth, unscaledHeight - (borderSize * 2));
        graphics.endFill();
    }
    
}
}
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 that holds StyleableTextFields to produce a drop shadow effect.
 *  Combines label and shadow into a single component to allow transitions to
 *  target them both.
 */
class TitleDisplayComponent extends UIComponent implements IDisplayText
{
    private var titleDisplay:StyleableTextField;
    private var titleDisplayShadow:StyleableTextField;
    private var title:String;
    private var titleChanged:Boolean;
    
    public function TitleDisplayComponent()
    {
        super();
        title = "";
    }
    
    override public function get baselinePosition():Number
    {
        return titleDisplay.baselinePosition;
    }
    
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
        
        titleDisplay = StyleableTextField(createInFontContext(StyleableTextField));
        titleDisplay.styleName = this;
        titleDisplay.editable = false;
        titleDisplay.selectable = false;
        titleDisplay.multiline = false;
        titleDisplay.wordWrap = false;
        titleDisplay.addEventListener(FlexEvent.VALUE_COMMIT,
            titleDisplay_valueCommitHandler);
        
        titleDisplayShadow =
            StyleableTextField(createInFontContext(StyleableTextField));
        titleDisplayShadow.styleName = this;
        titleDisplayShadow.colorName = "textShadowColor";
        titleDisplayShadow.editable = false;
        titleDisplayShadow.selectable = false;
        titleDisplayShadow.multiline = false;
        titleDisplayShadow.wordWrap = false;
        
        addChild(titleDisplayShadow);
        addChild(titleDisplay);
    }
    
    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        if (titleChanged)
        {
            titleDisplay.text = title;
            
            invalidateSize();
            invalidateDisplayList();
            
            titleChanged = false;
        }
    }
    
    /**
     *  @private
     */
    override protected function measure():void
    {
        // reset text if it was truncated before.
        if (titleDisplay.isTruncated)
            titleDisplay.text = title;
        
        measuredWidth = titleDisplay.getPreferredBoundsWidth();
        
        // tightTextHeight
        measuredHeight = titleDisplay.getPreferredBoundsHeight();
    }
    
    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        
        // reset text if it was truncated before.
        if (titleDisplay.isTruncated)
            titleDisplay.text = title;
        titleDisplay.commitStyles();
        
        // use preferred height, setLayoutBoundsSize will accommodate for tight
        // text adjustment
        var tightHeight:Number = titleDisplay.getPreferredBoundsHeight();
        var tightY:Number = (unscaledHeight - tightHeight) / 2;
        
        titleDisplay.setLayoutBoundsSize(unscaledWidth, tightHeight);
        titleDisplay.setLayoutBoundsPosition(0, (unscaledHeight - tightHeight) / 2);
        
        // now truncate the text
        titleDisplay.truncateToFit();
        
        titleDisplayShadow.commitStyles();
        titleDisplayShadow.setLayoutBoundsSize(unscaledWidth, tightHeight);
        titleDisplayShadow.setLayoutBoundsPosition(0, tightY + 1);
        
        titleDisplayShadow.alpha = getStyle("textShadowAlpha");
        
        // if labelDisplay is truncated, then push it down here as well.
        // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
        if (titleDisplay.isTruncated)
            titleDisplayShadow.text = titleDisplay.text;
    }
    
    /**
     *  @private 
     */ 
    private function titleDisplay_valueCommitHandler(event:Event):void 
    {
        titleDisplayShadow.text = titleDisplay.text;
    }
    
    public function get text():String
    {
        return title;
    }
    
    public function set text(value:String):void
    {
        title = value;
        titleChanged = true;
        
        invalidateProperties();
    }
    
    public function get isTruncated():Boolean
    {
        return titleDisplay.isTruncated;
    }
}