////////////////////////////////////////////////////////////////////////////////
//
//  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.utils.getQualifiedClassName;
import flash.utils.describeType;
import mx.containers.BoxDirection;
import mx.core.IButton;
import mx.core.UIComponent;
import mx.skins.Border;
import mx.styles.StyleManager;
import mx.utils.ColorUtil;

/**
 *  The skin for all the states of the ButtonBarButtons in a ButtonBar.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class ButtonBarButtonSkin extends Border
{
	include "../../core/Version.as";

	//--------------------------------------------------------------------------
	//
	//  Class variables
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private static var cache:Object = {}; 
	
	//--------------------------------------------------------------------------
	//
	//  Class methods
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 *  Several colors used for drawing are calculated from the base colors
	 *  of the component (themeColor, borderColor and fillColors).
	 *  Since these calculations can be a bit expensive,
	 *  we calculate once per color set and cache the results.
	 */
	private static function calcDerivedStyles(themeColor:uint,
											  fillColor0:uint,
											  fillColor1:uint):Object
	{
		var key:String = HaloColors.getCacheKey(themeColor,
												fillColor0, fillColor1); 
				
		if (!cache[key])
		{
			var o:Object = cache[key] = {};
			
			// Cross-component styles.
			HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1);
			
			// Button-specific styles.
			o.innerEdgeColor1 = ColorUtil.adjustBrightness2(fillColor0, -10);
			o.innerEdgeColor2 = ColorUtil.adjustBrightness2(fillColor1, -25);
		}
		
		return cache[key];
	}
	
	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------

	/**
	 *  Constructor.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function ButtonBarButtonSkin()
	{
		super();
	}
	
	//--------------------------------------------------------------------------
	//
	//  Overridden properties
	//
	//--------------------------------------------------------------------------

	//----------------------------------
	//  measuredWidth
	//----------------------------------
	
	/**
	 *  @private
	 */
	override public function get measuredWidth():Number
	{
		return UIComponent.DEFAULT_MEASURED_MIN_WIDTH;
	}
	
	//----------------------------------
	//  measuredHeight
	//----------------------------------

	/**
	 *  @private
	 */
	override public function get measuredHeight():Number
	{
		return UIComponent.DEFAULT_MEASURED_MIN_HEIGHT;
	}

	//--------------------------------------------------------------------------
	//
	//  Overridden methods
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 */
	override protected function updateDisplayList(w:Number, h:Number):void
	{
		super.updateDisplayList(w, h);

		// User-defined styles.
		var borderColor:uint = getStyle("borderColor");
		var cornerRadius:Number = getStyle("cornerRadius");
		var fillAlphas:Array = getStyle("fillAlphas");
		var fillColors:Array = getStyle("fillColors");

        if (styleName is UIComponent)
            styleName.styleManager.getColorNames(fillColors);
        else
            StyleManager.getStyleManager(null).getColorNames(fillColors);

        var highlightAlphas:Array = getStyle("highlightAlphas");		
		var themeColor:uint = getStyle("themeColor");

		// Derivative styles.
		var derStyles:Object = calcDerivedStyles(themeColor, fillColors[0],
												 fillColors[1]);

		var borderColorDrk1:Number =
			ColorUtil.adjustBrightness2(borderColor, -50);
		
		var themeColorDrk1:Number =
			ColorUtil.adjustBrightness2(themeColor, -25);

		var emph:Boolean = false;
		
		if (parent is IButton)
			emph = (parent as IButton).emphasized;

		var tmp:Number;

		var bar:Object = parent && parent.parent && isButtonBar(parent.parent) ? parent.parent : null;
		var horizontal:Boolean = true;
		var pos:int = 0;

		if (bar)
		{
			if (bar.direction == BoxDirection.VERTICAL)
				horizontal = false;

			// first: -1, middle: 0, last: 1
			var index:int = bar.getChildIndex(parent);
			pos = (index == 0 ? -1 : (index == bar.numChildren - 1 ? 1 : 0));
		}

		var radius:Object = getCornerRadius(pos, horizontal, cornerRadius);
		var cr:Object = getCornerRadius(pos, horizontal, cornerRadius);
		var cr1:Object = getCornerRadius(pos, horizontal, cornerRadius - 1);
		var cr2:Object = getCornerRadius(pos, horizontal, cornerRadius - 2);
		var cr3:Object = getCornerRadius(pos, horizontal, cornerRadius - 3);
		
		graphics.clear();

		switch (name)
		{			
			case "selectedUpSkin":
			case "selectedOverSkin":
			{
				// button border/edge
				drawRoundRect(
					0, 0, w, h, cr,
					[ themeColor, themeColorDrk1 ], 1,
					verticalGradientMatrix(0, 0, w, h ),
					GradientType.LINEAR, null, 
					{ x: 2, y: 2, w: w - 4, h: h - 4, r: cr2 }); 
										
				// button fill
				drawRoundRect(
					1, 1, w - 2, h - 2, cr1,
					[ fillColors[1], fillColors[1] ],
					[ fillAlphas[0], fillAlphas[1] ],
					verticalGradientMatrix(0, 0, w - 2, h - 2)); 

				break;
			}

			case "upSkin":
			{
   				var upFillColors:Array = [ fillColors[0], fillColors[1] ];
   				var upFillAlphas:Array = [ fillAlphas[0], fillAlphas[1] ];
			
				if (emph)
				{
					// button border/edge
					drawRoundRect(
						0, 0, w, h, cr,
						[ themeColor, themeColorDrk1 ], 1,
						verticalGradientMatrix(0, 0, w, h ),
						GradientType.LINEAR, null, 
						{ x: 2, y: 2, w: w - 4, h: h - 4, r: cr2 }); 

					// button fill
					drawRoundRect(
						2, 2, w - 4, h - 4, cr2,
						upFillColors, upFillAlphas,
						verticalGradientMatrix(1, 1, w - 2, h - 2)); 

					// top highlight
					if (!(radius is Number))
						{ radius.bl = radius.br = 0;}
					drawRoundRect(
						2, 2, w - 4, (h - 4) / 2, radius,
						[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
						verticalGradientMatrix(2, 2, w - 2, (h - 4) / 2));
				}
				else
				{
					// button border/edge
					drawRoundRect(
						0, 0, w, h, cr,
						[ borderColor, borderColorDrk1 ], 1,
						verticalGradientMatrix(0, 0, w, h ),
						GradientType.LINEAR, null, 
						{ x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); 

					// button fill
					drawRoundRect(
						1, 1, w - 2, h - 2, cr1,
						upFillColors, upFillAlphas,
						verticalGradientMatrix(1, 1, w - 2, h - 2));
						
					// top highlight
					if (!(radius is Number))
						{ radius.bl = radius.br = 0;}
					drawRoundRect(
						1, 1, w - 2, (h - 2) / 2, radius,
						[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
						verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); 
				}
				break;
			}
						
			case "overSkin":
			{
				var overFillColors:Array;
				if (fillColors.length > 2)
					overFillColors = [ fillColors[2], fillColors[3] ];
				else
					overFillColors = [ fillColors[0], fillColors[1] ];

				var overFillAlphas:Array;
				if (fillAlphas.length > 2)
					overFillAlphas = [ fillAlphas[2], fillAlphas[3] ];
  				else
					overFillAlphas = [ fillAlphas[0], fillAlphas[1] ];

				// button border/edge
				drawRoundRect(
					0, 0, w, h, cr,
					[ themeColor, derStyles.themeColDrk1 ], 1,
					verticalGradientMatrix(0, 0, w, h),
					GradientType.LINEAR, null, 
					{ x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 }); 
					
				// button fill
				drawRoundRect(
					1, 1, w - 2, h - 2, cr1,
					overFillColors, overFillAlphas,
					verticalGradientMatrix(0, 0, w - 2, h - 2)); 
				
				// top highlight
				if (!(radius is Number))
					{ radius.bl = radius.br = 0;}
				drawRoundRect(
					1, 1, w - 2, (h - 2) / 2, radius,
					[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
					verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2));
				break;
			}
								
			case "downSkin":
			case "selectedDownSkin":
			{
				// button border/edge
				drawRoundRect(
					0, 0, w, h, cr,
					[ themeColor, derStyles.themeColDrk1 ], 1,
					verticalGradientMatrix(0, 0, w, h)); 
					
				// button fill
				drawRoundRect(
					1, 1, w - 2, h - 2, cr1,
					[ derStyles.fillColorPress1, derStyles.fillColorPress2 ], 1,
					verticalGradientMatrix(0, 0, w - 2, h - 2)); 
								  
				// top highlight
				if (!(radius is Number))
					{ radius.bl = radius.br = 0;}
				drawRoundRect(
					1, 1, w - 2, (h - 2) / 2, radius,
					[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
					verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2)); 
				
				break;
			}
					
			case "disabledSkin":
			case "selectedDisabledSkin":
			{
                var disFillColors:Array = [ fillColors[0], fillColors[1] ];
                
                var disFillAlphas:Array =
                    [ Math.max( 0, fillAlphas[0] - 0.15),
                      Math.max( 0, fillAlphas[1] - 0.15) ];
				
				// outer edge
				drawRoundRect(
					0, 0, w, h, cr,
					[ borderColor, borderColorDrk1 ], 0.5,
					verticalGradientMatrix(0, 0, w, h ),
					GradientType.LINEAR, null, 
					{ x: 1, y: 1, w: w - 2, h: h - 2, r: cr1 } ); 	
								
				// button fill
                drawRoundRect(
                    1, 1, w - 2, h - 2, cr1,
                    disFillColors, disFillAlphas,
                    verticalGradientMatrix(0, 0, w - 2, h - 2));
				
				break;
			}
		}
	}

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

	/**
	 *  @private
	 */
	private function getCornerRadius(pos:int, horizontal:Boolean,
									 radius:Number):Object
	{
		if (pos == 0)
			return 0;
		
		radius = Math.max(0, radius);

		if (horizontal)
		{
			if (pos == -1)
				return { tl: radius, tr: 0, bl: radius, br: 0 };
			else // pos == 1
				return { tl: 0, tr: radius, bl: 0, br: radius };
		}
		else
		{
			if (pos == -1)
				return { tl: radius, tr: radius, bl: 0, br: 0 };
			else // pos == 1
				return { tl: 0, tr: 0, bl: radius, br: radius };
		}
	}

	/**
	 *  We don't use 'is' to prevent dependency issues
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	private static var bbars:Object = {};

	private static function isButtonBar(parent:Object):Boolean
	{
		var s:String = getQualifiedClassName(parent);
		if (bbars[s] == 1)
			return true;

		if (bbars[s] == 0)
			return false;

		if (s == "mx.controls::ButtonBar")
		{
			bbars[s] == 1;
			return true;
		}

		var x:XML = describeType(parent);
		var xmllist:XMLList = x.extendsClass.(@type == "mx.controls::ButtonBar");
		if (xmllist.length() == 0)
		{
			bbars[s] = 0;
			return false;
		}
		
		bbars[s] = 1;
		return true;
	}

}

}
