////////////////////////////////////////////////////////////////////////////////
//
//  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.DisplayObjectContainer;
import flash.display.GradientType;
import flash.utils.getQualifiedClassName;
import flash.utils.describeType;
import mx.core.EdgeMetrics;
import mx.core.UIComponent;
import mx.skins.Border;
import mx.styles.IStyleClient;
import mx.styles.StyleManager;
import mx.utils.ColorUtil;

/**
 *  The skin for all the states of a Tab in a TabNavigator or TabBar.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class TabSkin 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,
											  borderColor:uint,
											  falseFillColor0:uint,
											  falseFillColor1:uint,
											  fillColor0:uint,
											  fillColor1:uint):Object
	{
		var key:String = HaloColors.getCacheKey(themeColor, borderColor,
												falseFillColor0,
												falseFillColor1,
												fillColor0, fillColor1);
		
		if (!cache[key])
		{
			var o:Object = cache[key] = {};

			// Cross-component styles.
			HaloColors.addHaloColors(o, themeColor, fillColor0, fillColor1);
			
			// Tab-specific styles.
			o.borderColorDrk1 =
				ColorUtil.adjustBrightness2(borderColor, 10);
			o.falseFillColorBright1 =
				ColorUtil.adjustBrightness(falseFillColor0, 15);
			o.falseFillColorBright2 =
				ColorUtil.adjustBrightness(falseFillColor1, 15);
		}
		
		return cache[key];
	}

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

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

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

	/**
	 *  @private
	 *  Storage for the borderMetrics property.
	 */
	private var _borderMetrics:EdgeMetrics = new EdgeMetrics(1, 1, 1, 1);

	/**
	 *  @private
	 */
	override public function get borderMetrics():EdgeMetrics
	{
		return _borderMetrics;
	}

	//----------------------------------
	//  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 backgroundAlpha:Number = getStyle("backgroundAlpha");		
		var backgroundColor:Number = getStyle("backgroundColor");
		var borderColor:uint = getStyle("borderColor");
		var cornerRadius:Number = getStyle("cornerRadius");
		var fillAlphas:Array = getStyle("fillAlphas");
		var fillColors:Array = getStyle("fillColors");
        styleManager.getColorNames(fillColors);
		var highlightAlphas:Array = getStyle("highlightAlphas");		
		var themeColor:uint = getStyle("themeColor");
		
		// Placehold styles stub.
		var falseFillColors:Array = []; /* of Number*/ // added style prop
		falseFillColors[0] = ColorUtil.adjustBrightness2(fillColors[0], -5);
		falseFillColors[1] = ColorUtil.adjustBrightness2(fillColors[1], -5);
		
		// Derivative styles.
		var derStyles:Object = calcDerivedStyles(themeColor, borderColor,
												 falseFillColors[0],
												 falseFillColors[1],
												 fillColors[0], fillColors[1]);
		
		var parentedByTabNavigator:Boolean = parent != null &&
												parent.parent != null &&
												parent.parent.parent != null &&
												isTabNavigator(parent.parent.parent);
		
		var tabOffset:Number = 1;
		if (parentedByTabNavigator)
			tabOffset = Object(parent.parent.parent).borderMetrics.top;
		
		var drawBottomLine:Boolean =
			parentedByTabNavigator &&
			IStyleClient(parent.parent.parent).getStyle("borderStyle") != "none" &&
			tabOffset >= 0;

		var cornerRadius2:Number = Math.max(cornerRadius - 2, 0);
		var cr:Object = { tl: cornerRadius, tr: cornerRadius, bl: 0, br: 0 };
		var cr2:Object = { tl: cornerRadius2, tr: cornerRadius2, bl: 0, br: 0 };

		graphics.clear();
		
		switch (name)
		{
			case "upSkin":
			{
   				var upFillColors:Array =
					[ falseFillColors[0], falseFillColors[1] ];
   				
				var upFillAlphas:Array = [ fillAlphas[0], fillAlphas[1] ];

				// outer edge
				drawRoundRect(
					0, 0, w, h - 1, cr,
					[ derStyles.borderColorDrk1, borderColor], 1,
					verticalGradientMatrix(0, 0, w, h),
					GradientType.LINEAR, null, 
					{ x: 1, y: 1, w: w - 2, h: h - 2, r: cr2 }); 

				// tab fill
				drawRoundRect(
					1, 1, w - 2, h - 2, cr2,
					upFillColors, upFillAlphas,
					verticalGradientMatrix(0, 2, w - 2, h - 6));
			
				// tab highlight
				drawRoundRect(
					1, 1, w - 2, (h - 2) / 2, cr2,
					[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
					verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2));

				// tab bottom line
				if (drawBottomLine)
				{
					drawRoundRect(
						0, h - tabOffset, w, tabOffset, 0,
						borderColor, fillAlphas[1]);
				}
				
				// tab shadow	
				drawRoundRect(
					0, h - 2, w, 1, 0,
					0x000000, 0.09);
				
				// tab shadow
				drawRoundRect(
					0, h - 3, w, 1, 0,
					0x000000, 0.03);
	
				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] ];

				// outer edge
				drawRoundRect(
					0, 0, w, h - 1, cr,
					[ themeColor, derStyles.themeColDrk2 ], 1,
					verticalGradientMatrix(0, 0, w, h - 6),
					GradientType.LINEAR, null, 
					{ x: 1, y: 1, w: w - 2, h: h - 2, r: cr2 });
				
				// tab fill
				drawRoundRect(
					1, 1, w - 2, h - 2, cr2,
					[ derStyles.falseFillColorBright1,
					  derStyles.falseFillColorBright2 ], overFillAlphas,
					verticalGradientMatrix(2, 2, w - 2, h - 2));
			
				// tab highlight
				drawRoundRect(
					1, 1, w - 2, (h - 2) / 2, cr2,
					[ 0xFFFFFF, 0xFFFFFF ], highlightAlphas,
					verticalGradientMatrix(1, 1, w - 2, (h - 2) / 2));

				// tab bottom line
				if (drawBottomLine)
				{
					drawRoundRect(
						0, h - tabOffset, w, tabOffset, 0,
						borderColor, fillAlphas[1]);
				}
				
				// tab shadow	
				drawRoundRect(
					0, h - 2, w, 1, 0,
					0x000000, 0.09);
				
				// tab shadow
				drawRoundRect(
					0, h - 3, w, 1, 0,
					0x000000, 0.03);
				
				break;
			}

			case "disabledSkin":
			{
   				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 - 1, cr,
					[ derStyles.borderColorDrk1, borderColor], 0.5,
					verticalGradientMatrix(0, 0, w, h - 6));
				
				// tab fill
				drawRoundRect(
					1, 1, w - 2, h - 2, cr2,
					disFillColors, disFillAlphas,
					verticalGradientMatrix(0, 2, w - 2, h - 2));
				
				// tab bottom line
				if (drawBottomLine)
				{
					drawRoundRect(
						0, h - tabOffset, w, tabOffset, 0,
						borderColor, fillAlphas[1]);
				}
				
				// tab shadow	
				drawRoundRect(
					0, h - 2, w, 1, 0,
					0x000000, 0.09);
				
				// tab shadow
				drawRoundRect(
					0, h - 3, w, 1, 0,
					0x000000, 0.03);
				
				break;
			}
			
			case "downSkin":
			case "selectedUpSkin":
			case "selectedDownSkin":
			case "selectedOverSkin":
			case "selectedDisabledSkin":
			{
				if (isNaN(backgroundColor))
				{
					// Walk the parent chain until we find a background color
					var p:DisplayObjectContainer = parent;
					
					while (p)
					{
						if (p is IStyleClient)
							backgroundColor = IStyleClient(p).getStyle("backgroundColor");
						
						if (!isNaN(backgroundColor))
							break;
							
						p = p.parent;
					}
					
					// Still no backgroundColor? Use white.
					if (isNaN(backgroundColor))
						backgroundColor = 0xFFFFFF;
				}
				
 				// outer edge
				drawRoundRect(
					0, 0, w, h - 1, cr,
					[ derStyles.borderColorDrk1, borderColor], 1,
					verticalGradientMatrix(0, 0, w, h - 2),
					GradientType.LINEAR, null, 
					{ x: 1, y: 1, w: w - 2, h: h - 2, r: cr2 });
			
				// tab fill color
				drawRoundRect(
					1, 1, w - 2, h - 2, cr2,
					backgroundColor, backgroundAlpha);
				
				// tab bottom line
				if (drawBottomLine)
				{
					drawRoundRect(
						1, h - tabOffset, w - 2, tabOffset, 0,
						backgroundColor, backgroundAlpha);
				}
				
				break;
			}
		}
	}

	private static var tabnavs:Object = {};

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

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

		if (s == "mx.containers::TabNavigator")
		{
			tabnavs[s] == 1;
			return true;
		}

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

}
