////////////////////////////////////////////////////////////////////////////////
//
//  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 {

import flash.display.Graphics;
import mx.skins.ProgrammaticSkin;
import mx.styles.CSSStyleDeclaration;
import mx.styles.IStyleClient;
import mx.utils.GraphicsUtil;


public class RedFocusRect extends ProgrammaticSkin implements IStyleClient
{

	public function RedFocusRect()
	{
		super();
	}
  	

  	private var _focusColor:Number;

	public function get className():String
	{
		return "HaloFocusRect";
	}

	//----------------------------------
	//  inheritingStyles
	//----------------------------------

	/**
	 *  @private
	 */
	public function get inheritingStyles():Object
	{
		return styleName.inheritingStyles;
	}

	/**
	 *  @private
	 */
	public function set inheritingStyles(value:Object):void
	{
	}

	//----------------------------------
	//  nonInheritingStyles
	//----------------------------------

	/**
	 *  @private
	 */
	public function get nonInheritingStyles():Object
	{
		return styleName.nonInheritingStyles;
	}
	
	/**
	 *  @private
	 */
	public function set nonInheritingStyles(value:Object):void
	{
	}

	//----------------------------------
	//  styleDeclaration
	//----------------------------------

	/**
	 *  @private
	 */
	public function get styleDeclaration():CSSStyleDeclaration
	{
		return CSSStyleDeclaration(styleName);
	}
	
	/**
	 *  @private
	 */
	public function set styleDeclaration(value:CSSStyleDeclaration):void
	{
	}

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

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

		var focusBlendMode:String = getStyle("focusBlendMode");
		var focusAlpha:Number = getStyle("focusAlpha");
		var focusColor:Number = 0xFF0000;
		var cornerRadius:Number = 8;
		var focusThickness:Number = 5;
		var themeColor:Number = getStyle("themeColor");
		
		var rectColor:Number = focusColor;
		if (!rectColor)
			rectColor = themeColor;
			
		var g:Graphics = graphics;
		g.clear();
		
		if (focusBlendMode) if (focusBlendMode) blendMode = focusBlendMode;
		
		var ellipseSize:Number;
			
		// outer ring
		g.beginFill(rectColor, focusAlpha);
		ellipseSize = (cornerRadius > 0 ? cornerRadius + focusThickness : 0) * 2;
		g.drawRoundRect(0, 0, w, h, ellipseSize, ellipseSize);
		ellipseSize = cornerRadius * 2;
		g.drawRoundRect(focusThickness, focusThickness,
			w - 2 * focusThickness, h - 2 * focusThickness,
			ellipseSize, ellipseSize);
		g.endFill();
		// inner ring
		g.beginFill(rectColor, focusAlpha);
		ellipseSize = (cornerRadius > 0 ? cornerRadius + focusThickness / 2 : 0) * 2;
		g.drawRoundRect(focusThickness / 2, focusThickness / 2,
			w - focusThickness, h - focusThickness,
			ellipseSize, ellipseSize);
		ellipseSize = cornerRadius * 2;
		g.drawRoundRect(focusThickness, focusThickness,
			w - 2 * focusThickness, h - 2 * focusThickness,
			ellipseSize, ellipseSize);
		g.endFill();
	}
	
    override public function getStyle(styleProp:String):*
	{
		return styleProp == "focusColor" ?
			   _focusColor :
			   super.getStyle(styleProp);
	}

	/**
	 *  @private
	 */
    public function setStyle(styleProp:String, newValue:*):void
	{
		if (styleProp == "focusColor")
			_focusColor = newValue;
	}

	/**
	 *  @private
	 */
	public function clearStyle(styleProp:String):void
	{
		if (styleProp == "focusColor")
			_focusColor = NaN;
	}

	/**
	 *  @private
	 */
	public function getClassStyleDeclarations():Array
	{
		return [];
	}

	/**
	 *  @private
	 */
    public function notifyStyleChangeInChildren(
						styleProp:String, recursive:Boolean):void
	{
	}

	/**
	 *  @private
	 */
    public function regenerateStyleCache(recursive:Boolean):void
	{
	}

	/**
	 *  @private
	 */
    public function registerEffects(effects:Array /* of String */):void
	{
	}
}

}
