////////////////////////////////////////////////////////////////////////////////
//
//  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.controls.menuClasses
{

import flash.display.DisplayObject;
import flash.utils.getDefinitionByName;
import mx.controls.Menu;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.listClasses.ListData;
import mx.core.IDataRenderer;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IFontContextComponent;
import mx.core.IUITextField;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.FlexEvent;

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the <code>data</code> property changes.
 *
 *  <p>When you use a component as an item renderer,
 *  the <code>data</code> property contains the data to display.
 *  You can listen for this event and update the component
 *  when the <code>data</code> property changes.</p>
 *
 *  @eventType mx.events.FlexEvent.DATA_CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="dataChange", type="mx.events.FlexEvent")]

//--------------------------------------
//  Styles
//--------------------------------------

/**
 *  Text color of the menu item label.
 *  
 *  The default value for the Halo theme is <code>0x0B333C</code>.
 *  The default value for the Spark theme is <code>0x000000</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="color", type="uint", format="Color", inherit="yes")]

/**
 *  Color of the menu item if it is disabled.
 *  
 *  @default 0xAAB3B3
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="disabledColor", type="uint", format="Color", inherit="yes")]

/**
 *  The MenuItemRenderer class defines the default item renderer
 *  for menu items in any menu control.
 * 
 *  By default, the item renderer draws the text associated
 *  with each menu item, the separator characters, and icons.
 *
 *  <p>You can override the default item renderer
 *  by creating a custom item renderer.</p>
 *
 *  @see mx.controls.Menu
 *  @see mx.controls.MenuBar
 *  @see mx.core.IDataRenderer
 *  @see mx.controls.listClasses.IDropInListItemRenderer
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class MenuItemRenderer extends UIComponent
							  implements IDataRenderer, IListItemRenderer,
							  IMenuItemRenderer, IDropInListItemRenderer,
							  IFontContextComponent
{
	include "../../core/Version.as";

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

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

    //--------------------------------------------------------------------------
    //
    //  Overridden properties: UIComponent
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  baselinePosition
    //----------------------------------

    /**
     *  @private
     *  The baselinePosition of a MenuItemRenderer is calculated
     *  for its label.
     */
    override public function get baselinePosition():Number
    {
		if (!validateBaselinePosition())
			return NaN;

		return label.y + label.baselinePosition;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
	//  branchIcon
    //----------------------------------

	/**
	 *  The internal IFlexDisplayObject that displays the branch icon
	 *  in this renderer.
	 *  
	 *  @default null 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	protected var branchIcon:IFlexDisplayObject;

    //----------------------------------
	//  data
    //----------------------------------

	/**
	 *  @private
	 *  Storage for the data property.
	 */
	private var _data:Object;

	[Bindable("dataChange")]

	/**
	 *  The implementation of the <code>data</code> property
	 *  as defined by the IDataRenderer interface.
	 *
	 *  @see mx.core.IDataRenderer
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get data():Object
	{
		return _data;
	}

	/**
	 *  @private
	 */
	public function set data(value:Object):void
	{
		_data = value;

		invalidateProperties();
		invalidateSize();

		dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
	}

    //----------------------------------
    //  fontContext
    //----------------------------------
    
    /**
     *  @private
     */
    public function get fontContext():IFlexModuleFactory
    {
        return moduleFactory;
    }

    /**
     *  @private
     */
    public function set fontContext(moduleFactory:IFlexModuleFactory):void
    {
        this.moduleFactory = moduleFactory;
    }
    
    //----------------------------------
	//  icon
    //----------------------------------
    
    // using getter/setter so we can have backwards-compatibility.  If someone
    // subclassed and referred to icon, and they wanted to refer to the
    // checkbox/radio button or a separator, it is now moved into typeIcon
    // and separatorIcon

	/**
	 *  @private
	 *  Storage for the icon property.
	 */
	private var _icon:IFlexDisplayObject;

	/**
	 *  The internal IFlexDisplayObject that displays the icon in this renderer.
	 *  
	 *  @default null 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	protected function get icon():IFlexDisplayObject
	{
		return _icon;
	}

	/**
	 *  @private
	 */
	protected function set icon(value:IFlexDisplayObject):void
	{
		_icon = value;
	}

    //----------------------------------
	//  label
    //----------------------------------

	/**
	 *  The internal UITextField that displays the text in this renderer.
	 * 
	 *  @default null 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	protected var label:IUITextField;

    //----------------------------------
	//  listData
    //----------------------------------

	/**
	 *  @private
	 *  Storage for the listData property.
	 */
	private var _listData:ListData;

	[Bindable("dataChange")]

	/**
	 *  The implementation of the <code>listData</code> property
	 *  as defined by the IDropInListItemRenderer interface.
	 *
	 *  @see mx.controls.listClasses.IDropInListItemRenderer
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get listData():BaseListData
	{
		return _listData;
	}

	/**
	 *  @private
	 */
	public function set listData(value:BaseListData):void
	{
		_listData = ListData(value);

		invalidateProperties();
	}

    //----------------------------------
	//  menu
    //----------------------------------

	/**
	 *  @private
	 *  Storage for the menu property.
	 */
	private var _menu:Menu;

	/**
	 *  Contains a reference to the associated Menu control.
	 * 
	 *  @default null 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get menu():Menu
	{
		return _menu;
	}

	/**
	 *  @private
	 */
	public function set menu(value:Menu):void
	{
		_menu = value;
	}
	
	//----------------------------------
	//  separatorIcon
    //----------------------------------

	/**
	 *  The internal IFlexDisplayObject that displays the separator icon in this renderer
	 *  
	 *  @default null 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	protected var separatorIcon:IFlexDisplayObject;
	
	//----------------------------------
	//  typeIcon
    //----------------------------------

	/**
	 *  The internal IFlexDisplayObject that displays the type icon in this renderer for
	 *  check and radio buttons.
	 *  
	 *  @default null 
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	protected var typeIcon:IFlexDisplayObject;

	//--------------------------------------------------------------------------
	//
	//  Overridden methods: UIComponent
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	override protected function createChildren():void
	{
        super.createChildren();

		createLabel(-1);
	}

	/**
	 *  @private
	 */
	override protected function commitProperties():void
	{
		super.commitProperties();

        // if the font changed and we already created the label, we will need to 
        // destory it so it can be re-created, possibly in a different swf context.
        if (hasFontContextChanged() && label != null)
        {
        	var index:int = getChildIndex(DisplayObject(label));
            removeLabel();
 			createLabel(index);
        }

		var iconClass:Class;
		var typeIconClass:Class;
		var separatorIconClass:Class;
		var branchIconClass:Class;

		// Remove any existing icon/type/separator/branch icons.
		// These will be recreated below if needed.
		if (_icon)
		{
			removeChild(DisplayObject(_icon));
			_icon = null;
		}
		if (typeIcon)
		{
			removeChild(DisplayObject(typeIcon));
			typeIcon = null;
		}
		if (separatorIcon)
		{
			removeChild(DisplayObject(separatorIcon));
			separatorIcon = null;
		}
		if (branchIcon)
		{
			removeChild(DisplayObject(branchIcon));
			branchIcon = null;
		}

		if (_data)
		{
			var dataDescriptor:IMenuDataDescriptor =
				Menu(_listData.owner).dataDescriptor;
			
			var isEnabled:Boolean = dataDescriptor.isEnabled(_data);
			var type:String = dataDescriptor.getType(_data);

			// Separator
			if (type.toLowerCase() == "separator")
			{
				label.text = "";
				label.visible = false;
				separatorIconClass = getStyle("separatorSkin");
				separatorIcon = new separatorIconClass();
				addChild(DisplayObject(separatorIcon));
				return;
			}
			else
			{
				label.visible = true;
			}

			// Icon
			if (_listData.icon)
			{
				var listDataIcon:Object = _listData.icon;
				if (listDataIcon is Class)
				{
					iconClass = Class(listDataIcon);
				}
				else if (listDataIcon is String)
				{
					iconClass =
						Class(getDefinitionByName(String(listDataIcon)));
				}

				_icon = new iconClass();

				addChild(DisplayObject(_icon));
			}	

			// Label
			label.text = _listData.label;

			label.enabled = isEnabled;

			// Check/radio icon
			if (dataDescriptor.isToggled(_data))
			{
				var typeVal:String = dataDescriptor.getType(_data);
				if (typeVal)
				{
					typeVal = typeVal.toLowerCase();
					if (typeVal == "radio")
					{
						typeIconClass = getStyle(isEnabled ?
											 "radioIcon" :
											 "radioDisabledIcon");
					}
					else if (typeVal == "check")
					{
						typeIconClass = getStyle(isEnabled ?
											 "checkIcon" :
											 "checkDisabledIcon");
					}

					if (typeIconClass)
					{
						typeIcon = new typeIconClass();
						addChild(DisplayObject(typeIcon));
					}
				}
			}

			// Branch icon
			if (dataDescriptor.isBranch(_data))
			{
				branchIconClass = getStyle(isEnabled ?
										   "branchIcon" :
										   "branchDisabledIcon");

				if (branchIconClass)
				{
					branchIcon = new branchIconClass();
					addChild(DisplayObject(branchIcon));
				}
			}
		}
		else
		{
			label.text = " ";
		}
		
		// Invalidate layout here to ensure icons are positioned correctly.
		invalidateDisplayList();
	}

	/**
	 *  @private
	 */
	override protected function measure():void
	{
		super.measure();
		
		if (separatorIcon)
		{
			measuredWidth = separatorIcon.measuredWidth;
			measuredHeight = separatorIcon.measuredHeight;
			return;
		}
		
		if (_listData)
		{
			// need to determine the left/right margin needed
			// depends on whether there's an icon, a typeIcon, and/or a branchIcon
			var iconWidth:Number = MenuListData(_listData).maxMeasuredIconWidth;
			var typeIconWidth:Number = MenuListData(_listData).maxMeasuredTypeIconWidth;
			var branchIconWidth:Number = MenuListData(_listData).maxMeasuredBranchIconWidth;
			var useTwoColumns:Boolean = MenuListData(_listData).useTwoColumns;
			
			var leftMargin:Number = Math.max(getStyle("leftIconGap"), 
										useTwoColumns ? iconWidth + typeIconWidth : 
														Math.max(iconWidth, typeIconWidth));
			var rightMargin:Number = Math.max(getStyle("rightIconGap"), branchIconWidth);
	
			if (isNaN(explicitWidth))
			{
				measuredWidth = label.measuredWidth + leftMargin + rightMargin + 7;
			}
			else
			{
				label.width = explicitWidth - leftMargin - rightMargin;
			}
		
			measuredHeight = label.measuredHeight;
			
			// need to determine the height needed
			if (_icon && _icon.measuredHeight > measuredHeight)
				measuredHeight = _icon.measuredHeight;
				
			if (typeIcon && typeIcon.measuredHeight > measuredHeight)
				measuredHeight = typeIcon.measuredHeight;
				
			if (branchIcon && branchIcon.measuredHeight > measuredHeight)
				measuredHeight = branchIcon.measuredHeight;
		}
	}

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

		if (_listData)
		{
			if (Menu(_listData.owner).dataDescriptor.
				getType(_data).toLowerCase() == "separator")
			{
				if (separatorIcon)
				{
					separatorIcon.x = 2;
					separatorIcon.y = (unscaledHeight - separatorIcon.measuredHeight) / 2;
					separatorIcon.setActualSize(unscaledWidth - 4, separatorIcon.measuredHeight);
				}
				return;
			}
			
			var iconWidth:Number = MenuListData(_listData).maxMeasuredIconWidth;
			var typeIconWidth:Number = MenuListData(_listData).maxMeasuredTypeIconWidth;
			var branchIconWidth:Number = MenuListData(_listData).maxMeasuredBranchIconWidth;
			var useTwoColumns:Boolean = MenuListData(_listData).useTwoColumns;
			
			var leftMargin:Number = Math.max(getStyle("leftIconGap"), 
									useTwoColumns ? iconWidth + typeIconWidth : 
													Math.max(iconWidth, typeIconWidth));
			var rightMargin:Number = Math.max(getStyle("rightIconGap"), branchIconWidth);
			
			// check to see if laying out in two columns or not
			if (useTwoColumns)
			{				
				// if in two columns, center the two columns
				// center the respective icons (if present) in their own column
				var left:Number = (leftMargin - (iconWidth + typeIconWidth))/2
				
				if (_icon)
				{
					_icon.x = left + (iconWidth - _icon.measuredWidth)/2;
					_icon.setActualSize(_icon.measuredWidth, _icon.measuredHeight);
				}
				
				if (typeIcon)
				{
					typeIcon.x = left + iconWidth + (typeIconWidth - typeIcon.measuredWidth)/2;
					typeIcon.setActualSize(typeIcon.measuredWidth, typeIcon.measuredHeight);
				}
			}
			else
			{
				// if in one column mode, just center the one item in the left icon gap
				if (_icon)
				{
					_icon.x = (leftMargin - _icon.measuredWidth)/2;
					_icon.setActualSize(_icon.measuredWidth, _icon.measuredHeight);
				}
				
				if (typeIcon)
				{
					typeIcon.x = (leftMargin - typeIcon.measuredWidth)/2;
					typeIcon.setActualSize(typeIcon.measuredWidth, typeIcon.measuredHeight);
				}
			}
			
			if (branchIcon)
			{
				branchIcon.x = unscaledWidth - rightMargin + 
							   (rightMargin - branchIcon.measuredWidth)/2;
				branchIcon.setActualSize(branchIcon.measuredWidth,
										 branchIcon.measuredHeight);
			}

			label.x = leftMargin;		
			label.setActualSize(unscaledWidth - leftMargin - rightMargin,
								label.getExplicitOrMeasuredHeight());

			if (_listData && !Menu(_listData.owner).showDataTips)
			{
				label.text = _listData.label;
				if (label.truncateToFit())
					toolTip = _listData.label;
				else
					toolTip = null;
			}

			var verticalAlign:String = getStyle("verticalAlign");
			if (verticalAlign == "top")
			{
				label.y = 0;
				if (_icon)
					_icon.y = 0;
				if (typeIcon)
					typeIcon.y = 0;
				if (branchIcon)
					branchIcon.y = 0;
			}
			else if (verticalAlign == "bottom")
			{
				label.y = unscaledHeight - label.height + 2; // 2 for gutter
				if (_icon)
					_icon.y = unscaledHeight - _icon.height;
				if (typeIcon)
					typeIcon.y = unscaledHeight - typeIcon.height;
				if (branchIcon)
					branchIcon.y = unscaledHeight - branchIcon.height;
			}
			else
			{
				label.y = (unscaledHeight - label.height) / 2;
				if (_icon)
					_icon.y = (unscaledHeight - _icon.height) / 2;
				if (typeIcon)
					typeIcon.y = (unscaledHeight - typeIcon.height) / 2;
				if (branchIcon)
					branchIcon.y = (unscaledHeight - branchIcon.height) / 2;
			}

			var labelColor:Number;

			if (data && parent)
			{
				if (!enabled)
				{
					labelColor = getStyle("disabledColor");
				}
				else if (Menu(listData.owner).isItemHighlighted(listData.uid))
				{
					labelColor = getStyle("textRollOverColor");
				}
				else if (Menu(listData.owner).isItemSelected(listData.uid))
				{
					labelColor = getStyle("textSelectedColor");
				}
				else
				{
					labelColor = getStyle("color");
				}

				label.setColor(labelColor);
			}
		}
	}

	/**
	 *  @private
	 */
	override public function styleChanged(styleProp:String):void
	{
		super.styleChanged(styleProp);

		if (!styleProp ||
			styleProp == "styleName" ||
			(styleProp.toLowerCase().indexOf("icon") != -1))
		{
			// If any icons change, invalidate everything.
			// We could be smarter about this if it causes
			// performance problems.
			invalidateSize();
			invalidateDisplayList();
		}
	}

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

    /**
     *  @private
     *  Creates the title text field and adds it as a child of this component.
     * 
     *  @param childIndex The index of where to add the child.
	 *  If -1, the text field is appended to the end of the list.
     */
    mx_internal function createLabel(childIndex:int):void
    {
        if (!label)
        {
            label = IUITextField(createInFontContext(UITextField));
            
			label.styleName = this;

            if (childIndex == -1)
                addChild(DisplayObject(label));
            else 
                addChildAt(DisplayObject(label), childIndex);
        }
    }

    /**
     *  @private
     *  Removes the title text field from this component.
     */
    mx_internal function removeLabel():void
    {
        if (label)
        {
            removeChild(DisplayObject(label));
            label = null;
        }
    }

    /**
     *  @private
     */
    mx_internal function getLabel():IUITextField
    {
        return label;
    }

    /**
     *  The width of the icon
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get measuredIconWidth():Number
    {
    	var horizontalGap:Number = getStyle("horizontalGap");
    	return _icon ? _icon.measuredWidth + horizontalGap : 0;
    }
    
    /**
     *  The width of the type icon (radio/check)
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get measuredTypeIconWidth():Number
    {
    	var horizontalGap:Number = getStyle("horizontalGap");
 
    	if (typeIcon)
    		return typeIcon.measuredWidth + horizontalGap;
    	
    	// even if there's no type icon, get what it's width would be...
    	if (_data)
    	{	
    		var typeIconClass:Class;
    		var dataDescriptor:IMenuDataDescriptor =
				Menu(_listData.owner).dataDescriptor;
			var isEnabled:Boolean = dataDescriptor.isEnabled(_data);
    		var typeVal:String = dataDescriptor.getType(_data);
			if (typeVal)
			{
				typeVal = typeVal.toLowerCase();
				if (typeVal == "radio")
				{
					typeIconClass = getStyle(isEnabled ?
										 "radioIcon" :
										 "radioDisabledIcon");
				}
				else if (typeVal == "check")
				{
					typeIconClass = getStyle(isEnabled ?
										 "checkIcon" :
										 "checkDisabledIcon");
				}

				if (typeIconClass)
				{
					typeIcon = new typeIconClass();
					var typeIconWidth:Number = typeIcon.measuredWidth;
					typeIcon = null;
					return typeIconWidth + horizontalGap;
				}
			}
    	}
    	
    	return 0;
    }
    
    /**
     *  The width of the branch icon
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get measuredBranchIconWidth():Number
    {
    	var horizontalGap:Number = getStyle("horizontalGap");
        return branchIcon ? branchIcon.measuredWidth + horizontalGap : 0;
    }
}

}
