////////////////////////////////////////////////////////////////////////////////
//
//  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.ios7
{
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.ios7.assets.ActionBarBackground;
import spark.skins.mobile.supportClasses.MobileSkin;

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();
		
		borderClass = spark.skins.ios7.assets.ActionBarBackground;
        
        switch (applicationDPI)
        {
			
			case DPIClassification.DPI_640:
			{
				borderSize = 2;
				layoutContentGroupHeight = 172;
				layoutTitleGroupHorizontalPadding = 52;
				
				break;
			}
			case DPIClassification.DPI_480:
			{
				borderSize = 2;
				layoutContentGroupHeight = 130;
				layoutTitleGroupHorizontalPadding = 40;
				
				
				break;
			}
            case DPIClassification.DPI_320:
            {
                borderSize = 2;
                layoutContentGroupHeight = 86;
                layoutTitleGroupHorizontalPadding = 26;
                
                break;
            }
            case DPIClassification.DPI_240:
            {
                borderSize = 1;
                layoutContentGroupHeight = 65;
                layoutTitleGroupHorizontalPadding = 20;
                
                break;
            }
			case DPIClassification.DPI_120:
			{
				borderSize = 1;
				layoutContentGroupHeight = 32;
				layoutTitleGroupHorizontalPadding = 10;
				
				break;
			}	
            default:
            {
                // default DPI_160
                borderSize = 1;
                layoutContentGroupHeight = 43;
                layoutTitleGroupHorizontalPadding = 13;
                
                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;
    
    /**
     *  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);
        }
        
        // 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;
    }
}