////////////////////////////////////////////////////////////////////////////////
//
//  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.GradientType;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;

import mx.core.DPIClassification;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.EffectEvent;
import mx.events.FlexEvent;
import mx.utils.ColorUtil;

import spark.components.ArrowDirection;
import spark.components.Callout;
import spark.components.ContentBackgroundAppearance;
import spark.components.Group;
import spark.core.SpriteVisualElement;
import spark.effects.Fade;
import spark.primitives.RectangularDropShadow;
import spark.skins.mobile.supportClasses.CalloutArrow;
import spark.skins.mobile.supportClasses.MobileSkin;
import spark.skins.mobile120.assets.CalloutContentBackground;
import spark.skins.mobile160.assets.CalloutContentBackground;
import spark.skins.mobile240.assets.CalloutContentBackground;
import spark.skins.mobile320.assets.CalloutContentBackground;
import spark.skins.mobile480.assets.CalloutContentBackground;
import spark.skins.mobile640.assets.CalloutContentBackground;

use namespace mx_internal;

/**
 *  The default skin class for the Spark Callout component in mobile
 *  applications.
 * 
 *  <p>The <code>contentGroup</code> lies above a <code>backgroundColor</code> fill
 *  which frames the <code>contentGroup</code>. The position and size of the frame 
 *  adjust based on the host component <code>arrowDirection</code>, leaving
 *  space for the <code>arrow</code> to appear on the outside edge of the
 *  frame.</p>
 * 
 *  <p>The <code>arrow</code> skin part is not positioned by the skin. Instead,
 *  the Callout component positions the arrow relative to the owner in
 *  <code>updateSkinDisplayList()</code>. This method assumes that Callout skin
 *  and the <code>arrow</code> use the same coordinate space.</p>
 *  
 *  @see spark.components.Callout
 *  
 *  @langversion 3.0
 *  @playerversion AIR 3
 *  @productversion Flex 4.6
 */ 
public class CalloutSkin extends MobileSkin
{
    mx_internal static const BACKGROUND_GRADIENT_BRIGHTNESS_TOP:int = 15;
    
    mx_internal static const BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM:int = -60;
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor. 
     * 
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    public function CalloutSkin()
    {
        super();
        
        dropShadowAlpha = 0.7;
        
        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{
				// Note provisional may need changes  
				backgroundCornerRadius = 32;
				contentBackgroundInsetClass = spark.skins.mobile640.assets.CalloutContentBackground;
				backgroundGradientHeight = 440;
				frameThickness = 32;
				arrowWidth = 208;
				arrowHeight = 104;
				contentCornerRadius = 20;
				dropShadowBlurX = 64;
				dropShadowBlurY = 64;
				dropShadowDistance = 12;
				highlightWeight = 2;
				
				break;
			}
			case DPIClassification.DPI_480:
			{
				// Note provisional may need changes
				backgroundCornerRadius = 24;
				contentBackgroundInsetClass = spark.skins.mobile480.assets.CalloutContentBackground;
				backgroundGradientHeight = 330;
				frameThickness = 24;
				arrowWidth = 156;
				arrowHeight = 78;
				contentCornerRadius = 14;
				dropShadowBlurX = 48;
				dropShadowBlurY = 48;
				dropShadowDistance = 8;
				highlightWeight = 2;
				
				break;
			}
            case DPIClassification.DPI_320:
            {
                backgroundCornerRadius = 16;
                contentBackgroundInsetClass = spark.skins.mobile320.assets.CalloutContentBackground;
                backgroundGradientHeight = 220;
                frameThickness = 16;
                arrowWidth = 104;
                arrowHeight = 52;
                contentCornerRadius = 10;
                dropShadowBlurX = 32;
                dropShadowBlurY = 32;
                dropShadowDistance = 6;
                highlightWeight = 2;
                
                break;
            }
            case DPIClassification.DPI_240:
            {
                backgroundCornerRadius = 12;
                contentBackgroundInsetClass = spark.skins.mobile240.assets.CalloutContentBackground;
                backgroundGradientHeight = 165;
                frameThickness = 12;
                arrowWidth = 78;
                arrowHeight = 39;
                contentCornerRadius = 7;
                dropShadowBlurX = 24;
                dropShadowBlurY = 24;
                dropShadowDistance = 4;
                highlightWeight = 1;
                
                break;
            }
			case DPIClassification.DPI_120:
			{
				backgroundCornerRadius = 6;
				contentBackgroundInsetClass = spark.skins.mobile120.assets.CalloutContentBackground;
				backgroundGradientHeight = 83;
				frameThickness = 24;
				arrowWidth = 156;
				arrowHeight = 39;
				contentCornerRadius = 7;
				dropShadowBlurX = 24;
				dropShadowBlurY = 24;
				dropShadowDistance = 4;
				highlightWeight = 1;
				
				break;
			}
            default:
            {
                // default DPI_160
                backgroundCornerRadius = 8;
                contentBackgroundInsetClass = spark.skins.mobile160.assets.CalloutContentBackground;
                backgroundGradientHeight = 110;
                frameThickness = 8;
                arrowWidth = 52;
                arrowHeight = 26;
                contentCornerRadius = 5;
                dropShadowBlurX = 16;
                dropShadowBlurY = 16;
                dropShadowDistance = 3;
                highlightWeight = 1;
                
                break;
            }
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    /** 
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:Callout;
    
    /**
     *  Enables a RectangularDropShadow behind the <code>backgroundColor</code> frame.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var dropShadowVisible:Boolean = true;
    
    /**
     *  Enables a vertical linear gradient in the <code>backgroundColor</code> frame. This
     *  gradient fill is drawn across both the arrow and the frame. By default,
     *  the gradient brightens the background color by 15% and darkens it by 60%.
     * 
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var useBackgroundGradient:Boolean = true;
    
    /**
     *  Corner radius used for the <code>contentBackgroundColor</code> fill.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var contentCornerRadius:uint;
    
    /**
     *  A class reference to an FXG class that is layered underneath the
     *  <code>contentGroup</code>. The instance of this class is sized to match the
     *  <code>contentGroup</code>.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var contentBackgroundInsetClass:Class;
    
    /**
     *  Corner radius of the <code>backgroundColor</code> "frame".
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var backgroundCornerRadius:Number;
    
    /**
     *  The thickness of the <code>backgroundColor</code> "frame" that surrounds the
     *  <code>contentGroup</code>.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var frameThickness:Number;
    
    /**
     *  Color of the border stroke around the <code>backgroundColor</code> "frame".
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var borderColor:Number = 0;
    
    /**
     *  Thickness of the border stroke around the <code>backgroundColor</code>
     *  "frame".
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var borderThickness:Number = NaN;
    
    /**
     *  Width of the arrow in vertical directions. This property also controls
     *  the height of the arrow in horizontal directions.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var arrowWidth:Number;
    
    /**
     *  Height of the arrow in vertical directions. This property also controls
     *  the width of the arrow in horizontal directions.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 3
     *  @productversion Flex 4.6
     */
    protected var arrowHeight:Number;
    
    /**
     *  @private
     *  Instance of the contentBackgroundClass
     */
    mx_internal var contentBackgroundGraphic:SpriteVisualElement;
    
    /**
     *  @private
     *  Tracks changes to the skin state to support the fade out tranisition 
     *  when closed;
     */
    mx_internal var isOpen:Boolean;
    
    private var backgroundGradientHeight:Number;
    
    private var contentMask:Sprite;
    
    private var backgroundFill:SpriteVisualElement;
    
    private var dropShadow:RectangularDropShadow;
    
    private var dropShadowBlurX:Number;
    
    private var dropShadowBlurY:Number;
    
    private var dropShadowDistance:Number;
    
    private var dropShadowAlpha:Number;
    
    private var fade:Fade;
    
    private var highlightWeight:Number;
    
    //--------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @copy spark.components.SkinnableContainer#contentGroup
     */
    public var contentGroup:Group;
    
    /**
     * @copy spark.components.Callout#arrow
     */
    public var arrow:UIComponent;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------
    
    /**
     * @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
        
        if (dropShadowVisible)
        {
            dropShadow = new RectangularDropShadow();
            dropShadow.angle = 90;
            dropShadow.distance = dropShadowDistance;
            dropShadow.blurX = dropShadowBlurX;
            dropShadow.blurY = dropShadowBlurY;
            dropShadow.tlRadius = dropShadow.trRadius = dropShadow.blRadius = 
                dropShadow.brRadius = backgroundCornerRadius;
            dropShadow.mouseEnabled = false;
            dropShadow.alpha = dropShadowAlpha;
            addChild(dropShadow);
        }
        
        // background fill placed above the drop shadow
        backgroundFill = new SpriteVisualElement();
        addChild(backgroundFill);
        
        // arrow
        if (!arrow)
        {
            arrow = new CalloutArrow();
            arrow.id = "arrow";
            arrow.styleName = this;
            addChild(arrow);
        }
        
        // contentGroup
        if (!contentGroup)
        {
            contentGroup = new Group();
            contentGroup.id = "contentGroup";
            addChild(contentGroup);
        }
    }
    
    /**
     * @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        // add or remove the contentBackgroundGraphic
        var contentBackgroundAppearance:String = getStyle("contentBackgroundAppearance");
        
        if (contentBackgroundAppearance == ContentBackgroundAppearance.INSET)
        {
            // create the contentBackgroundGraphic
            if (!contentBackgroundGraphic && contentBackgroundInsetClass)
            {
                contentBackgroundGraphic = new contentBackgroundInsetClass() as SpriteVisualElement;
                
                // with the current skin structure, contentBackgroundGraphic is
                // always the last child
                addChild(contentBackgroundGraphic);
            }
        }
        else if (contentBackgroundGraphic)
        {
            // if already created, remove the graphic for "flat" and "none"
            removeChild(contentBackgroundGraphic);
            contentBackgroundGraphic = null;
        }
        
        // always invalidate to accomodate arrow direction changes
        invalidateSize();
        invalidateDisplayList();
    }
    
    /**
     * @private
     */
    override protected function measure():void
    {
        super.measure();
        
        var borderWeight:Number = isNaN(borderThickness) ? 0 : borderThickness;
        var frameAdjustment:Number = (frameThickness + borderWeight) * 2;
        
        var arrowMeasuredWidth:Number;
        var arrowMeasuredHeight:Number;
        
        // pad the arrow so that the edges are within the background corner radius
        if (isArrowHorizontal)
        {
            arrowMeasuredWidth = arrowHeight;
            arrowMeasuredHeight = arrowWidth + (backgroundCornerRadius * 2);
        }
        else if (isArrowVertical)
        {
            arrowMeasuredWidth = arrowWidth + (backgroundCornerRadius * 2);
            arrowMeasuredHeight = arrowHeight;
        }
        
        // count the contentGroup size and frame size
        measuredMinWidth = contentGroup.measuredMinWidth + frameAdjustment;
        measuredMinHeight = contentGroup.measuredMinHeight + frameAdjustment;
        
        measuredWidth = contentGroup.getPreferredBoundsWidth() + frameAdjustment;
        measuredHeight = contentGroup.getPreferredBoundsHeight() + frameAdjustment;
        
        // add the arrow size based on the arrowDirection
        if (isArrowHorizontal)
        {
            measuredMinWidth += arrowMeasuredWidth;
            measuredMinHeight = Math.max(measuredMinHeight, arrowMeasuredHeight);
            
            measuredWidth += arrowMeasuredWidth;
            measuredHeight = Math.max(measuredHeight, arrowMeasuredHeight);
        }
        else if (isArrowVertical)
        {
            measuredMinWidth += Math.max(measuredMinWidth, arrowMeasuredWidth);
            measuredMinHeight += arrowMeasuredHeight;
            
            measuredWidth = Math.max(measuredWidth, arrowMeasuredWidth);
            measuredHeight += arrowMeasuredHeight;
        }
    }
    
    /**
     *  @private
     *  SkinnaablePopUpContainer skins must dispatch a 
     *  FlexEvent.STATE_CHANGE_COMPLETE event for the component to properly
     *  update the skin state.
     */
    override protected function commitCurrentState():void
    {
        super.commitCurrentState();
        
        var isNormal:Boolean = (currentState == "normal");
        var isDisabled:Boolean = (currentState == "disabled")
        
        // play a fade out if the callout was previously open
        if (!(isNormal || isDisabled) && isOpen)
        {
            if (!fade)
            {
                fade = new Fade();
                fade.target = this;
                fade.duration = 200;
                fade.alphaTo = 0;
            }
            
            // BlendMode.LAYER while fading out
            blendMode = BlendMode.LAYER;
            
            // play a short fade effect
            fade.addEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
            fade.play();
            
            isOpen = false;
        }
        else
        {
            isOpen = isNormal || isDisabled;
            
            // handle re-opening the Callout while fading out
            if (fade && fade.isPlaying)
            {
                // Do not dispatch a state change complete.
                // SkinnablePopUpContainer handles state interruptions.
                fade.removeEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
                fade.stop();
            }
            
            if (isDisabled)
            {
                // BlendMode.LAYER to allow CalloutArrow BlendMode.ERASE
                blendMode = BlendMode.LAYER;
                
                alpha = 0.5;
            }
            else
            {
                // BlendMode.NORMAL for non-animated state transitions
                blendMode = BlendMode.NORMAL;
                
                if (isNormal)
                    alpha = 1;
                else
                    alpha = 0;
            }
            
            stateChangeComplete();
        }
    }
    
    /**
     * @private
     */
    override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.drawBackground(unscaledWidth, unscaledHeight);
        
        var frameEllipseSize:Number = backgroundCornerRadius * 2;
        
        // account for borderThickness center stroke alignment
        var showBorder:Boolean = !isNaN(borderThickness);
        var borderWeight:Number = showBorder ? borderThickness : 0;
        
        // contentBackgroundGraphic already accounts for the arrow position
        // use it's positioning instead of recalculating based on unscaledWidth
        // and unscaledHeight
        var frameX:Number = Math.floor(contentGroup.getLayoutBoundsX() - frameThickness) - (borderWeight / 2);
        var frameY:Number = Math.floor(contentGroup.getLayoutBoundsY() - frameThickness) - (borderWeight / 2);
        var frameWidth:Number = contentGroup.getLayoutBoundsWidth() + (frameThickness * 2) + borderWeight;
        var frameHeight:Number = contentGroup.getLayoutBoundsHeight() + (frameThickness * 2) + borderWeight;
        
        var backgroundColor:Number = getStyle("backgroundColor");
        var backgroundAlpha:Number = getStyle("backgroundAlpha");
        
        var bgFill:Graphics = backgroundFill.graphics;
        bgFill.clear();
        
        if (showBorder)
            bgFill.lineStyle(borderThickness, borderColor, 1, true);
        
        if (useBackgroundGradient)
        {
            // top color is brighter if arrowDirection == ArrowDirection.UP
            var backgroundColorTop:Number = ColorUtil.adjustBrightness2(backgroundColor, 
                BACKGROUND_GRADIENT_BRIGHTNESS_TOP);
            var backgroundColorBottom:Number = ColorUtil.adjustBrightness2(backgroundColor, 
                BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM);
            
            // max gradient height = backgroundGradientHeight
            colorMatrix.createGradientBox(unscaledWidth, backgroundGradientHeight,
                Math.PI / 2, 0, 0);
            
            bgFill.beginGradientFill(GradientType.LINEAR,
                [backgroundColorTop, backgroundColorBottom],
                [backgroundAlpha, backgroundAlpha],
                [0, 255],
                colorMatrix);
        }
        else
        {
            bgFill.beginFill(backgroundColor, backgroundAlpha);
        }
        
        bgFill.drawRoundRect(frameX, frameY, frameWidth,
            frameHeight, frameEllipseSize, frameEllipseSize);
        bgFill.endFill();
        
        // draw content background styles
        var contentBackgroundAppearance:String = getStyle("contentBackgroundAppearance");
        
        if (contentBackgroundAppearance != ContentBackgroundAppearance.NONE)
        {
            var contentEllipseSize:Number = contentCornerRadius * 2;
            var contentBackgroundAlpha:Number = getStyle("contentBackgroundAlpha");
            var contentWidth:Number = contentGroup.getLayoutBoundsWidth();
            var contentHeight:Number = contentGroup.getLayoutBoundsHeight();
            
            // all appearance values except for "none" use a mask
            if (!contentMask)
                contentMask = new SpriteVisualElement();
            
            contentGroup.mask = contentMask;
            
            // draw contentMask in contentGroup coordinate space
            var maskGraphics:Graphics = contentMask.graphics;
            maskGraphics.clear();
            maskGraphics.beginFill(0, 1);
            maskGraphics.drawRoundRect(0, 0, contentWidth, contentHeight,
                contentEllipseSize, contentEllipseSize);
            maskGraphics.endFill();
            
            // reset line style to none
            if (showBorder)
                bgFill.lineStyle(NaN);
            
            // draw the contentBackgroundColor
            bgFill.beginFill(getStyle("contentBackgroundColor"),
                contentBackgroundAlpha);
            bgFill.drawRoundRect(contentGroup.getLayoutBoundsX(),
                contentGroup.getLayoutBoundsY(),
                contentWidth, contentHeight, contentEllipseSize, contentEllipseSize);
            bgFill.endFill();
            
            if (contentBackgroundGraphic)
                contentBackgroundGraphic.alpha = contentBackgroundAlpha;
        }
        else // if (contentBackgroundAppearance == CalloutContentBackgroundAppearance.NONE))
        {
            // remove the mask
            if (contentMask)
            {
                contentGroup.mask = null;
                contentMask = null;
            }
        }
        
        // draw highlight in the callout when the arrow is hidden
        if (useBackgroundGradient && !isArrowHorizontal && !isArrowVertical)
        {
            // highlight width spans the callout width minus the corner radius
            var highlightWidth:Number = frameWidth - frameEllipseSize;
            var highlightX:Number = frameX + backgroundCornerRadius;
            var highlightOffset:Number = (highlightWeight * 1.5);
            
            // straight line across the top
            bgFill.lineStyle(highlightWeight, 0xFFFFFF, 0.2 * backgroundAlpha);
            bgFill.moveTo(highlightX, highlightOffset);
            bgFill.lineTo(highlightX + highlightWidth, highlightOffset);
        }
    }
    
    /**
     * @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);
        
        // pad the arrow so that the edges are within the background corner radius
        if (isArrowHorizontal)
        {
            arrow.width = arrowHeight;
            arrow.height = arrowWidth + (backgroundCornerRadius * 2);
        }
        else if (isArrowVertical)
        {
            arrow.width = arrowWidth + (backgroundCornerRadius * 2);
            arrow.height = arrowHeight;
        }
        
        setElementSize(backgroundFill, unscaledWidth, unscaledHeight);
        setElementPosition(backgroundFill, 0, 0);
        
        var frameX:Number = 0;
        var frameY:Number = 0;
        var frameWidth:Number = unscaledWidth;
        var frameHeight:Number = unscaledHeight;
        
        switch (hostComponent.arrowDirection)
        {
            case ArrowDirection.UP:
                frameY = arrow.height;
                frameHeight -= arrow.height;
                break;
            case ArrowDirection.DOWN:
                frameHeight -= arrow.height;
                break;
            case ArrowDirection.LEFT:
                frameX = arrow.width;
                frameWidth -= arrow.width;
                break;
            case ArrowDirection.RIGHT:
                frameWidth -= arrow.width;
                break;
            default:
                // no arrow, content takes all available space
                break;
        }
        
        if (dropShadow)
        {
            setElementSize(dropShadow, frameWidth, frameHeight);
            setElementPosition(dropShadow, frameX, frameY);
        }
        
        // Show frameThickness by inset of contentGroup
        var borderWeight:Number = isNaN(borderThickness) ? 0 : borderThickness;
        var contentBackgroundAdjustment:Number = frameThickness + borderWeight;
        
        var contentBackgroundX:Number = frameX + contentBackgroundAdjustment;
        var contentBackgroundY:Number = frameY + contentBackgroundAdjustment;
        
        contentBackgroundAdjustment = contentBackgroundAdjustment * 2;
        var contentBackgroundWidth:Number = frameWidth - contentBackgroundAdjustment;
        var contentBackgroundHeight:Number = frameHeight - contentBackgroundAdjustment;
        
        if (contentBackgroundGraphic)
        {
            setElementSize(contentBackgroundGraphic, contentBackgroundWidth, contentBackgroundHeight);
            setElementPosition(contentBackgroundGraphic, contentBackgroundX, contentBackgroundY);
        }
        
        setElementSize(contentGroup, contentBackgroundWidth, contentBackgroundHeight);
        setElementPosition(contentGroup, contentBackgroundX, contentBackgroundY);
        
        // mask position is in the contentGroup coordinate space
        if (contentMask)
            setElementSize(contentMask, contentBackgroundWidth, contentBackgroundHeight);
    }
    
    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);
        
        var allStyles:Boolean = !styleProp || styleProp == "styleName";
        
        if (allStyles || (styleProp == "contentBackgroundAppearance"))
            invalidateProperties();
        
        if (allStyles || (styleProp == "backgroundAlpha"))
        {
            var backgroundAlpha:Number = getStyle("backgroundAlpha");
            
            // Use BlendMode.LAYER to allow CalloutArrow to erase the dropShadow
            // when the Callout background is transparent
            blendMode = (backgroundAlpha < 1) ? BlendMode.LAYER : BlendMode.NORMAL;
        }
    }
    
    /**
     * @private
     */
    mx_internal function get isArrowHorizontal():Boolean
    {
        return (hostComponent.arrowDirection == ArrowDirection.LEFT
            || hostComponent.arrowDirection == ArrowDirection.RIGHT);
    }
    
    /**
     * @private
     */
    mx_internal function get isArrowVertical():Boolean
    {
        return (hostComponent.arrowDirection == ArrowDirection.UP
            || hostComponent.arrowDirection == ArrowDirection.DOWN);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------
    
    private function stateChangeComplete(event:Event=null):void
    {
        if (fade && event)
            fade.removeEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
        
        // SkinnablePopUpContainer relies on state changes for open and close
        dispatchEvent(new FlexEvent(FlexEvent.STATE_CHANGE_COMPLETE));
    }
}
}