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

import mx.events.PropertyChangeEvent;

[ExcludeClass]

/**
 *  @private
 *  Bindability information for children (properties or methods)
 *  of a given class, based on the describeType() structure for that class.
 */
public class BindabilityInfo
{
    include "../core/Version.as";

	//--------------------------------------------------------------------------
	//
	//  Class constants
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  Name of [Bindable] metadata.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static const BINDABLE:String = "Bindable";
	
	/**
	 *  Name of [Managed] metadata.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static const MANAGED:String = "Managed";
	
	/**
	 *  Name of [ChangeEvent] metadata.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static const CHANGE_EVENT:String = "ChangeEvent";
	
	/**
	 *  Name of [NonCommittingChangeEvent] metadata.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static const NON_COMMITTING_CHANGE_EVENT:String =
		"NonCommittingChangeEvent";

	/**
	 *  Name of describeType() <accessor> element.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static const ACCESSOR:String = "accessor";
	
	/**
	 *  Name of describeType() <method> element.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public static const METHOD:String = "method";

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

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

		this.typeDescription = typeDescription;
	}

	//--------------------------------------------------------------------------
	//
	//  Variables
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private var typeDescription:XML;
	
	/**
	 *  @private
	 *  event name -> true
	 */
	private var classChangeEvents:Object;
	
	/**
	 *  @private
	 *  child name -> { event name -> true }
	 */
	private var childChangeEvents:Object = {};	

	//--------------------------------------------------------------------------
	//
	//  Variables
	//
	//--------------------------------------------------------------------------

	/**
	 *  Object containing { eventName: true } for each change event
	 *  (class- or child-level) that applies to the specified child.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getChangeEvents(childName:String):Object
	{
		var changeEvents:Object = childChangeEvents[childName];

		if (!changeEvents)
		{
			// Seed with class-level events.
			changeEvents = copyProps(getClassChangeEvents(), {});

			// Get child-specific events.
			var childDesc:XMLList =
				typeDescription.accessor.(@name == childName) +
				typeDescription.method.(@name == childName);
			
			var numChildren:int = childDesc.length();

			if (numChildren == 0)
			{
				// we've been asked for events on an unknown property
				if (!typeDescription.@dynamic)
				{
					trace("warning: no describeType entry for '" +
						  childName + "' on non-dynamic type '" +
						  typeDescription.@name + "'");
				}
			}
			else
			{
				if (numChildren > 1)
				{
					trace("warning: multiple describeType entries for '" +
						  childName + "' on type '" + typeDescription.@name +
						  "':\n" + childDesc);
				}

				addBindabilityEvents(childDesc.metadata, changeEvents);
			}

			childChangeEvents[childName] = changeEvents;
		}

		return changeEvents;
	}

	/**
	 *  @private
	 *  Build or return cached class change events object.
	 */
	private function getClassChangeEvents():Object
	{
		if (!classChangeEvents)
		{
			classChangeEvents = {};

			addBindabilityEvents(typeDescription.metadata, classChangeEvents);

			// Class-level [Managed] means all properties
			// dispatch propertyChange.
			if (typeDescription.metadata.(@name == MANAGED).length() > 0)
			{
				classChangeEvents[PropertyChangeEvent.PROPERTY_CHANGE] = true;
			}
		}

		return classChangeEvents;
	}

	/**
	 *  @private
	 */
	private function addBindabilityEvents(metadata:XMLList,
										  eventListObj:Object):void
	{
		addChangeEvents(metadata.(@name == BINDABLE), eventListObj, true);
		addChangeEvents(metadata.(@name == CHANGE_EVENT), eventListObj, true);
		addChangeEvents(metadata.(@name == NON_COMMITTING_CHANGE_EVENT),
						eventListObj, false);
	}

	/**
	 *  @private
	 *  Transfer change events from a list of change-event-carrying metadata
	 *  to an event list object.
	 *  Note: metadata's first arg value is assumed to be change event name.
	 */
	private function addChangeEvents(metadata:XMLList, eventListObj:Object, isCommit:Boolean):void
	{
		for each (var md:XML in metadata)
		{
			var arg:XMLList = md.arg;
			if (arg.length() > 0)
			{
				var eventName:String = arg[0].@value;
				eventListObj[eventName] = isCommit;
			}
			else
			{
				trace("warning: unconverted Bindable metadata in class '" +
					  typeDescription.@name + "'");
			}
		}
	}

	/**
	 *  @private
	 *  Copy properties from one object to another.
	 */
	private function copyProps(from:Object, to:Object):Object
	{
		for (var propName:String in from)
		{
			to[propName] = from[propName];
		}

		return to;
	}
}

}
