////////////////////////////////////////////////////////////////////////////////
//
//  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 mx.skins.halo
{

import flash.display.GradientType;
import flash.display.Graphics;
import mx.core.IContainer;
import mx.core.EdgeMetrics;
import mx.core.IUIComponent;
import mx.core.mx_internal;
import mx.graphics.RectangularDropShadow;
import mx.skins.RectangularBorder;
import mx.styles.IStyleClient;
import mx.styles.StyleManager;
import mx.utils.ColorUtil;
import mx.graphics.GradientEntry;

use namespace mx_internal;

/**
 *  Defines the appearance of the default border for the Halo theme.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class HaloBorder extends RectangularBorder
{
    include "../../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  A look up table for the offsets.
     */
    private static var BORDER_WIDTHS:Object =
    {
        none: 0,
        solid: 1,
        inset: 2,
        outset: 2, 
        alert: 3,
        dropdown: 2,
        menuBorder: 1,
        comboNonEdit: 2
    };

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

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function HaloBorder() 
    {
        super(); 

        // 'default' is a keyword; setting it this way avoids a compiler error
        BORDER_WIDTHS["default"] = 3;
    }

    //--------------------------------------------------------------------------
    //
    //  Fields
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  A reference to the object used to cast a drop shadow.
     *  See the drawDropShadow() method for details.
     */  
    private var dropShadow:RectangularDropShadow;
    
    mx_internal var backgroundColor:Object; 
    mx_internal var backgroundAlphaName:String; 
    mx_internal var backgroundHole:Object;
    mx_internal var bRoundedCorners:Boolean;
    mx_internal var radius:Number;
    mx_internal var radiusObj:Object;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  borderMetrics
    //----------------------------------

    /**
     *  @private
     *  Internal object that contains the thickness of each edge
     *  of the border
     */
    protected var _borderMetrics:EdgeMetrics;

    /**
     *  @private
     *  Return the thickness of the border edges.
     *
     *  @return Object  top, bottom, left, right thickness in pixels
     */
    override public function get borderMetrics():EdgeMetrics
    {       
        if (_borderMetrics)
            return _borderMetrics;
            
        var borderThickness:Number;

        // Add support for "custom" style type here when we support it.
        var borderStyle:String = getStyle("borderStyle");

        if (borderStyle == "default" ||
            borderStyle == "alert")
        {
            return EdgeMetrics.EMPTY;
        }       
        
        else if (borderStyle == "controlBar" ||
                 borderStyle == "applicationControlBar")
        {
            _borderMetrics = new EdgeMetrics(1, 1, 1, 1);
        }
        
        else if (borderStyle == "solid")
        {
            borderThickness = getStyle("borderThickness");
            if (isNaN(borderThickness))
                borderThickness = 0;

            _borderMetrics = new EdgeMetrics(borderThickness,
                                              borderThickness,
                                              borderThickness,
                                              borderThickness);
                
            var borderSides:String = getStyle("borderSides");           
            if (borderSides != "left top right bottom")
            {
                // Adjust metrics based on which sides we have              
                if (borderSides.indexOf("left") == -1)
                    _borderMetrics.left = 0;
                
                if (borderSides.indexOf("top") == -1)
                    _borderMetrics.top = 0;
                
                if (borderSides.indexOf("right") == -1)
                    _borderMetrics.right = 0;
                
                if (borderSides.indexOf("bottom") == -1)
                    _borderMetrics.bottom = 0;
            }
        }
        
        else
        {
            borderThickness = BORDER_WIDTHS[borderStyle];
            if (isNaN(borderThickness))
                borderThickness = 0;
        
            _borderMetrics = new EdgeMetrics(borderThickness,
                                             borderThickness,
                                             borderThickness,
                                             borderThickness);
        }
        
        return _borderMetrics;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  If borderStyle may have changed, clear the cached border metrics.
     */
    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);
        
        if (styleProp == null ||
            styleProp == "styleName" ||
            styleProp == "borderStyle" ||
            styleProp == "borderThickness" ||
            styleProp == "borderSides")
        {
            _borderMetrics = null;
        }
    }

    /**
     *  @private
     *  Draw the border, either 3D or 2D or nothing at all.
     */
    override protected function updateDisplayList(w:Number, h:Number):void
    {   
        if (isNaN(w) || isNaN(h))
            return;
            
        super.updateDisplayList(w, h);

        // Store background color in an object,
        // so that null is distinct from black.
        backgroundColor = getBackgroundColor();
        bRoundedCorners = false;    
        backgroundAlphaName = "backgroundAlpha";
        backgroundHole = null;
        radius = 0;
        radiusObj = null;

        drawBorder(w,h);        
        drawBackground(w,h);    
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    mx_internal function drawBorder(w:Number, h:Number):void
    {
        var borderStyle:String = getStyle("borderStyle");
                
        // Other styles that we may fetch.
        var highlightAlphas:Array = getStyle("highlightAlphas");    
        
        var backgroundAlpha:Number;
                
        var borderCapColor:uint;
        var borderColor:uint;
        var borderSides:String;
        var borderThickness:Number;
        var buttonColor:uint;
        var docked:Boolean;
        var dropdownBorderColor:uint;
        var fillColors:Array;
        var footerColors:Array;
        var highlightColor:uint;
        var shadowCapColor:uint;
        var shadowColor:uint;
        var themeColor:uint;
        var translucent:Boolean;
        
        var hole:Object;
        var drawTopHighlight:Boolean = false;
        
        var borderColorDrk1:Number
        var borderColorDrk2:Number
        var borderColorLt1:Number

        var borderInnerColor:Object;

        var g:Graphics = graphics;
        g.clear();

        if (borderStyle)
        {
            switch (borderStyle)
            {
                case "none":
                {
                    break;
                }

                case "inset": // used for text input & numeric stepper
                {
                    borderColor = getStyle("borderColor");      
                    borderColorDrk1 =
                        ColorUtil.adjustBrightness2(borderColor, -40);
                    borderColorDrk2 =
                        ColorUtil.adjustBrightness2(borderColor, +25);
                    borderColorLt1 = 
                        ColorUtil.adjustBrightness2(borderColor, +40);
                        
                    borderInnerColor = backgroundColor;
                    if (borderInnerColor === null ||
                        borderInnerColor === "")
                    {
                        borderInnerColor = borderColor;
                    }
                    
                    draw3dBorder(borderColorDrk2, borderColorDrk1, borderColorLt1,
                                 Number(borderInnerColor), 
                                 Number(borderInnerColor), 
                                 Number(borderInnerColor));
                    break;
                }

                case "outset":
                {
                    borderColor = getStyle("borderColor");      
                    borderColorDrk1 =
                        ColorUtil.adjustBrightness2(borderColor, -40);
                    borderColorDrk2 =
                        ColorUtil.adjustBrightness2(borderColor, -25);
                    borderColorLt1 = 
                        ColorUtil.adjustBrightness2(borderColor, +40);
                    
                    borderInnerColor = backgroundColor;
                    if (borderInnerColor === null ||
                        borderInnerColor === "")
                    {
                        borderInnerColor = borderColor;
                    }
                    
                    draw3dBorder(borderColorDrk2, borderColorLt1, borderColorDrk1,
                                 Number(borderInnerColor), 
                                 Number(borderInnerColor), 
                                 Number(borderInnerColor));
                    break;
                }

                case "alert":
                case "default":
                {
                   break;
                }

                case "dropdown": // never used
                {
                    // The dropdownBorderColor is currently only used
                    // when displaying an error state.
                    dropdownBorderColor = getStyle("dropdownBorderColor");

                    drawDropShadow(0, 0, w, h, 4, 0, 0, 4);

                    // frame
                    drawRoundRect(
                        0, 0, w, h,
                        { tl: 4, tr: 0, br: 0, bl: 4 },
                        0x4D555E, 1);

                    // gradient
                    drawRoundRect(
                        0, 0, w, h,
                        { tl: 4, tr: 0, br: 0, bl: 4},
                        [ 0xFFFFFF, 0xFFFFFF ], [ 0.7, 0 ],
                        verticalGradientMatrix(0, 0, w, h)); 
                    
                    // button top higlight edge
                    drawRoundRect(
                        1, 1, w - 1, h - 2,
                        { tl: 3, tr: 0, br: 0, bl: 3 },
                        0xFFFFFF, 1); 
                    
                    // button face
                    drawRoundRect(
                        1, 2, w - 1, h - 3,
                        { tl: 3, tr: 0, br: 0, bl: 3 },
                        [ 0xEEEEEE, 0xFFFFFF ], 1,
                        verticalGradientMatrix(0, 0, w - 1, h - 3)); 

                    if (!isNaN(dropdownBorderColor))
                    {
                        // combo background in error state
                        drawRoundRect(
                            0, 0, w + 1, h,
                            { tl: 4, tr: 0, br: 0, bl: 4 },
                            dropdownBorderColor, 0.5);
                        
                        // button top higlight edge
                        drawRoundRect(
                            1, 1, w - 1, h - 2,
                            { tl: 3, tr: 0, br: 0, bl: 3 },
                            0xFFFFFF, 1); 
                        
                        //button face
                        drawRoundRect(
                            1, 2, w - 1, h - 3,
                            { tl: 3, tr: 0, br: 0, bl: 3 },
                            [ 0xEEEEEE, 0xFFFFFF ], 1,
                            verticalGradientMatrix(0, 0, w - 1, h - 3)); 
                    }
                    
                    // Make sure the border isn't filled in down below.
                    backgroundColor = null;
                    
                    break;
                }

                case "menuBorder":
                {
                    borderColor = getStyle("borderColor");
                    drawRoundRect(
                        0, 0, w, h, 0,
                        borderColor, 1);
                    drawDropShadow(1, 1, w - 2, h - 2, 0, 0, 0, 0);
                    break;
                }
                
                case "comboNonEdit":
                {
                    break;
                }
                
                case "controlBar":
                {
                    if (w == 0 || h == 0)
                    {
                        // If the width or height is 0, don't draw anything.
                        backgroundColor = null;
                        break;
                    }

                    footerColors = getStyle("footerColors");
                    var showChrome:Boolean = footerColors != null;
                    var borderAlpha:Number = getStyle("borderAlpha");
                        
                    if (showChrome)
                    {
                        g.lineStyle(0, footerColors.length > 0 ?
                                    footerColors[1] : footerColors[0], borderAlpha);
                        g.moveTo(0, 0);
                        g.lineTo(w, 0);
                        g.lineStyle(0, 0, 0);

                        // cornerRadius is defined on our parent container. Reach up
                        // and grab it. Yes, this is cheating...
                        if (parent && parent.parent && parent.parent is IStyleClient)
                        {
                            radius =
                                IStyleClient(parent.parent).getStyle("cornerRadius"); 
                            borderAlpha = 
                                IStyleClient(parent.parent).getStyle("borderAlpha"); 
                        }
                        
                        if (isNaN(radius))
                            radius = 0;

                        // If our parent has square bottom corners,
                        // use square corners.
                        if (IStyleClient(parent.parent).
                            getStyle("roundedBottomCorners").toString().toLowerCase() != "true")
                        {
                            radius = 0;
                        }
                        
                        drawRoundRect(
                            0, 1, w, h - 1,
                            { tl: 0, tr: 0, bl:radius, br: radius },
                            footerColors, borderAlpha,
                            verticalGradientMatrix(0, 0, w, h));

                        if (footerColors.length > 1 &&
                            footerColors[0] != footerColors[1])
                        {
                            drawRoundRect(
                                0, 1, w, h - 1,
                                { tl: 0, tr: 0, bl: radius, br: radius },
                                [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
                                verticalGradientMatrix(0, 0, w, h));

                            drawRoundRect(
                                1, 2, w - 2, h - 3,
                                { tl: 0, tr: 0, bl: radius - 1, br: radius - 1 },
                                footerColors, borderAlpha,
                                verticalGradientMatrix(0, 0, w, h));
                        }
                    }

                    // Don't draw the background color below.
                    // We've already handled it here.
                    backgroundColor = null;
                    break;
                }
                
                case "applicationControlBar":
                {
                    fillColors = getStyle("fillColors");
                    backgroundAlpha = getStyle("backgroundAlpha");
                    highlightAlphas = getStyle("highlightAlphas");
                    var fillAlphas:Array = getStyle("fillAlphas");
                    docked = getStyle("docked");

                    // background color of the bar
                    var backgroundColorNum:uint = uint(backgroundColor);

                    radius = getStyle("cornerRadius");
                    if (!radius)
                        radius = 0;

                    drawDropShadow(0, 1, w, h - 1,
                                   radius, radius, radius, radius);

                    if (backgroundColor !== null && 
                        styleManager.isValidStyleValue(backgroundColor))
                    {
                        drawRoundRect(
                            0, 1, w, h - 1, radius,
                            backgroundColorNum, backgroundAlpha,
                            verticalGradientMatrix(0, 0, w, h));
                    }

                    // surface
                    drawRoundRect(
                        0, 1, w, h - 1, radius,
                        fillColors, fillAlphas,
                        verticalGradientMatrix(0, 0, w, h));
                    
                    // highlight
                    drawRoundRect(
                        0, 1, w, (h / 2) - 1,
                        { tl: radius, tr: radius, bl: 0, br: 0 },
                        [ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
                        verticalGradientMatrix(0, 0, w, h / 2 - 1));

                    // edge
                    drawRoundRect(
                        0, 1, w, h - 1,
                        { tl: radius, tr: radius, bl: 0, br: 0 },
                        0xFFFFFF, 0.3, null,
                        GradientType.LINEAR, null, 
                        { x: 0, y: 2, w: w, h: h - 2,
                          r: { tl: radius, tr: radius, bl: 0, br: 0 } });

                    // Don't draw the background color below.
                    // We've already handled it here.
                    backgroundColor = null;

                    break;
                }

                default: // ((borderStyle == "solid") || (borderStyle == null))
                {
                    borderColor = getStyle("borderColor");      
                    borderThickness = getStyle("borderThickness");
                    borderSides = getStyle("borderSides");
                    var bHasAllSides:Boolean = true;
                    radius = getStyle("cornerRadius");
                    
                    bRoundedCorners =
                        getStyle("roundedBottomCorners").toString().toLowerCase() == "true";
                    
                    var holeRadius:Number =
                        Math.max(radius - borderThickness, 0);
                        
                    hole = { x: borderThickness,
                             y: borderThickness,
                             w: w - borderThickness * 2,
                             h: h - borderThickness * 2,
                             r: holeRadius };
                    
                    if (!bRoundedCorners)
                    {
                        radiusObj = {tl:radius, tr:radius, bl:0, br:0};
                        hole.r = {tl:holeRadius, tr:holeRadius, bl:0, br:0};
                    }
                    
                    if (borderSides != "left top right bottom")
                    {
                        // Convert the radius values from a scalar to an object
                        // because we need to adjust individual radius values
                        // if we are missing any sides.
                        hole.r = { tl: holeRadius,
                                   tr: holeRadius,
                                   bl: bRoundedCorners ? holeRadius : 0,
                                   br: bRoundedCorners ? holeRadius : 0 };
                        
                        radiusObj = { tl: radius,
                                      tr: radius,
                                      bl: bRoundedCorners ? radius : 0,
                                      br: bRoundedCorners ? radius : 0};
                        
                        borderSides = borderSides.toLowerCase();
                        
                        if (borderSides.indexOf("left") == -1)
                        {
                            hole.x = 0;
                            hole.w += borderThickness;
                            hole.r.tl = 0;
                            hole.r.bl = 0;
                            radiusObj.tl = 0;
                            radiusObj.bl = 0;
                            bHasAllSides = false;
                        }
                        
                        if (borderSides.indexOf("top") == -1)
                        {
                            hole.y = 0;
                            hole.h += borderThickness;
                            hole.r.tl = 0;
                            hole.r.tr = 0;
                            radiusObj.tl = 0;
                            radiusObj.tr = 0;
                            bHasAllSides = false;
                        }
                        
                        if (borderSides.indexOf("right") == -1)
                        {
                            hole.w += borderThickness;
                            hole.r.tr = 0;
                            hole.r.br = 0;
                            radiusObj.tr = 0;
                            radiusObj.br = 0;
                            bHasAllSides = false;
                        }
                        
                        if (borderSides.indexOf("bottom") == -1)
                        {
                            hole.h += borderThickness;
                            hole.r.bl = 0;
                            hole.r.br = 0;
                            radiusObj.bl = 0;
                            radiusObj.br = 0;
                            bHasAllSides = false;
                        }
                    }

                    if (radius == 0 && bHasAllSides)
                    {
                        drawDropShadow(0, 0, w, h, 0, 0, 0, 0);
                    
                        g.beginFill(borderColor);
                        g.drawRect(0, 0, w, h);
                        g.drawRect(borderThickness, borderThickness,
                                   w - 2 * borderThickness,
                                   h - 2 * borderThickness);
                        g.endFill();
                    }
                    else if (radiusObj)
                    {
                        drawDropShadow(0, 0, w, h, 
                                       radiusObj.tl, radiusObj.tr, 
                                       radiusObj.br, radiusObj.bl);
                    
                        drawRoundRect(
                            0, 0, w, h, radiusObj,
                            borderColor, 1,
                            null, null, null, hole);
                        
                        // Reset radius here so background drawing
                        // below is correct.
                        radiusObj.tl = Math.max(radius - borderThickness, 0);
                        radiusObj.tr = Math.max(radius - borderThickness, 0);
                        radiusObj.bl = bRoundedCorners ? Math.max(radius - borderThickness, 0) : 0;
                        radiusObj.br = bRoundedCorners ? Math.max(radius - borderThickness, 0) : 0;
                    }
                    else
                    {
                        drawDropShadow(0, 0, w, h,
                                       radius, radius, radius, radius);
                    
                        drawRoundRect(
                            0, 0, w, h, radius,
                            borderColor, 1,
                            null, null, null, hole);
                        
                        // Reset radius here so background drawing
                        // below is correct.
                        radius = Math.max(getStyle("cornerRadius") -
                                 borderThickness, 0);
                    }                                   
                }
            } // switch
        }
    }


    /**
     *  @private
     *  Draw a 3D border.
     */
    mx_internal function draw3dBorder(c1:Number, c2:Number, c3:Number,
                                  c4:Number, c5:Number, c6:Number):void
    {
        var w:Number = width;
        var h:Number = height;
        
        /*
        // temp color override to verify layout of lines
        var c1:Number = 0x919999;
        var c2:Number = 0x6F7777;
        var c3:Number = 0xD5DDDD;
        var c4:Number = 0xC4CCCC;
        var c5:Number = 0xEEEEEE;
        var c6:Number = 0xD5DDDD;
        */

        drawDropShadow(0, 0, width, height, 0, 0, 0, 0);
        
        var g:Graphics = graphics;
        
        // outside sides
        g.beginFill(c1);
        g.drawRect(0, 0, w, h);
        g.drawRect(1, 0, w - 2, h);
        g.endFill();
        
        // outside top
        g.beginFill(c2);
        g.drawRect(1, 0, w - 2, 1);
        g.endFill();
        
        // outside bottom
        g.beginFill(c3);
        g.drawRect(1, h - 1, w - 2, 1);
        g.endFill();
        
        // inside top
        g.beginFill(c4);
        g.drawRect(1, 1, w - 2, 1);
        g.endFill();
        
        // inside bottom
        g.beginFill(c5);
        g.drawRect(1, h - 2, w - 2, 1);
        g.endFill();
        
        // inside sides
        g.beginFill(c6);
        g.drawRect(1, 2, w - 2, h - 4);
        g.drawRect(2, 2, w - 4, h - 4);
        g.endFill();
    }

    /**
     *  @private
     */
    mx_internal function drawBackground(w:Number, h:Number):void
    {
        // The behavior used to be that we always create a background
        // regardless of whether we have a background color or not.
        // Now we only create a background if we have a color
        // or if the mouseShield or mouseShieldChildren styles are true.
        // Look at Container.addEventListener and Container.isBorderNeeded
        // for the mouseShield logic. JCS 6/24/05
        if ((backgroundColor !== null &&
             backgroundColor !== "") ||
            getStyle("mouseShield") ||
            getStyle("mouseShieldChildren"))
        {
            var nd:Number = Number(backgroundColor);
            var alpha:Number = 1.0;
            var bm:EdgeMetrics = getBackgroundColorMetrics();
            var g:Graphics = graphics;
            
            if (isNaN(nd) ||
                backgroundColor === "" ||
                backgroundColor === null)
            {
                alpha = 0;
                nd = 0xFFFFFF;
            }
            else
            {
                alpha = getStyle(backgroundAlphaName);
            }

            // If we have a non-zero radius, use drawRoundRect()
            // to fill in the background.
            if (radius != 0 || backgroundHole)
            {           
                var bottom:Number = bm.bottom;

                if (radiusObj)
                {
                    var topRadius:Number =
                        Math.max(radius - Math.max(bm.top, bm.left, bm.right), 0);
                    var bottomRadius:Number = bRoundedCorners ?
                        Math.max(radius - Math.max(bm.bottom, bm.left, bm.right), 0) : 0;

                    radiusObj = { tl: topRadius,
                                  tr: topRadius,
                                  bl: bottomRadius,
                                  br: bottomRadius };

                    drawRoundRect(
                        bm.left, bm.top,
                        width - (bm.left + bm.right),
                        height - (bm.top + bottom), 
                        radiusObj,
                        nd, alpha, null,
                        GradientType.LINEAR, null,
                        backgroundHole);
                }
                else
                {
                    drawRoundRect(
                        bm.left, bm.top,
                        width - (bm.left + bm.right),
                        height - (bm.top + bottom), 
                        radius,
                        nd, alpha, null,
                        GradientType.LINEAR, null,
                        backgroundHole);
                }
            }
            else
            {
                g.beginFill(nd, alpha);
                g.drawRect(bm.left, bm.top,
                           w - bm.right - bm.left, h - bm.bottom - bm.top);
                g.endFill();
            }
        }
    }

    /**
     *  @private
     *  Apply a drop shadow using a bitmap filter.
     *
     *  Bitmap filters are slow, and their slowness is proportional
     *  to the number of pixels being filtered.
     *  For a large HaloBorder, it's wasteful to create a big shadow.
     *  Instead, we'll create the shadow offscreen
     *  and stretch it to fit the HaloBorder.
     */
    mx_internal function drawDropShadow(x:Number, y:Number, 
                                    width:Number, height:Number,
                                    tlRadius:Number, trRadius:Number, 
                                    brRadius:Number, blRadius:Number):void
    {
        // Do I need a drop shadow in the first place?  If not, return
        // immediately.
        if (getStyle("dropShadowEnabled") == false || 
            getStyle("dropShadowEnabled") == "false" ||
            width == 0 || 
            height == 0)
        {
            return;
        }

        // Calculate the angle and distance for the shadow
        var distance:Number = getStyle("shadowDistance");
        var direction:String = getStyle("shadowDirection");
        var angle:Number;       
        if (getStyle("borderStyle") == "applicationControlBar")
        {
            var docked:Boolean = getStyle("docked");
            angle = docked ? 90 : getDropShadowAngle(distance, direction);
            distance = Math.abs(distance);
        }
        else
        {
            angle = getDropShadowAngle(distance, direction);
            distance = Math.abs(distance) + 2;
        }
        
        // Create a RectangularDropShadow object, set its properties,
        // and draw the shadow
        if (!dropShadow)
            dropShadow = new RectangularDropShadow();

        dropShadow.distance = distance;
        dropShadow.angle = angle;
        dropShadow.color = getStyle("dropShadowColor");
        dropShadow.alpha = 0.4;

        dropShadow.tlRadius = tlRadius;
        dropShadow.trRadius = trRadius;
        dropShadow.blRadius = blRadius;
        dropShadow.brRadius = brRadius;

        dropShadow.drawShadow(graphics, x, y, width, height);
    }

    /**
     *  @private
     *  Convert the value of the shadowDirection property
     *  into a shadow angle.
     */
    mx_internal function getDropShadowAngle(distance:Number,
                                        direction:String):Number
    {
        if (direction == "left")
            return distance >= 0 ? 135 : 225;

        else if (direction == "right")
            return distance >= 0 ? 45 : 315;
        
        else // direction == "center"
            return distance >= 0 ? 90 : 270;
    }

    /**
     *  @private
     */
    mx_internal function getBackgroundColor():Object
    {
        var p:IUIComponent = parent as IUIComponent;
        if (p && !p.enabled)
        {
            var color:Object = getStyle("backgroundDisabledColor");
            if (color !== null && styleManager.isValidStyleValue(color))
                return color;
        }

        return getStyle("backgroundColor");
    }
    
    /**
     *  @private
     */
    mx_internal function getBackgroundColorMetrics():EdgeMetrics
    {
        return borderMetrics;
    }
}

}
