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

import mx.effects.effectClasses.ResizeInstance;

[Alternative(replacement="spark.effects.Resize", since="4.0")]

/**
 *  The Resize effect changes the width, height, or both dimensions
 *  of a component over a specified time interval. 
 *  
 *  <p>If you specify only two of the three values of the
 *  <code>widthFrom</code>, <code>widthTo</code>, and
 *  <code>widthBy</code> properties, Flex calculates the third.
 *  If you specify all three, Flex ignores the <code>widthBy</code> value.
 *  If you specify only the <code>widthBy</code> or the
 *  <code>widthTo</code> value, the <code>widthFrom</code> property
 *  is set to be the object's current width.
 *  The same is true for <code>heightFrom</code>, <code>heightTo</code>,
 *  and <code>heightBy</code> property values.</p>
 *  
 *  <p>If you specify a Resize effect for a resize trigger,
 *  and if you do not set the six From, To, and By properties,
 *  Flex sets them to create a smooth transition
 *  between the object's old size and its new size.</p>
 *  
 *  @mxml
 *
 *  <p>The <code>&lt;mx:Resize&gt;</code> tag
 *  inherits all of the tag attributes of its superclass, 
 *  and adds the following tab attributes:</p>
 *  
 *  <pre>
 *  &lt;mx:Resize
 *    id="ID"
 *    widthFrom="val"
 *    heightFrom="val"
 *    widthTo="val"
 *    heightTo="val"
 *    widthBy="val"
 *    heightBy="val"
 *    hideChildrenTargets=""
 *  /&gt;
 *  </pre>
 *  
 *  @includeExample examples/ResizeEffectExample.mxml
 *
 *  @see mx.effects.effectClasses.ResizeInstance
 *  @see mx.effects.Tween
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class Resize extends TweenEffect
{
    include "../core/Version.as";

	//--------------------------------------------------------------------------
	//
	//  Class constants
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private static var AFFECTED_PROPERTIES:Array =
	[
		"width", "height",
		"explicitWidth", "explicitHeight",
		"percentWidth", "percentHeight"
	];

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

	/**
	 *  Constructor.
	 *
	 *  @param target The Object to animate with this effect.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function Resize(target:Object = null)
	{
		super(target);

		instanceClass = ResizeInstance;
	}
	
	//--------------------------------------------------------------------------
	//
	//  Properties
	//
	//--------------------------------------------------------------------------
 
 	//----------------------------------
	//  heightBy
	//----------------------------------

	[Inspectable(category="General", defaultValue="NaN")]

	/** 
	 *  Number of pixels by which to modify the height of the component.
	 *  Values may be negative.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var heightBy:Number;
	
 	//----------------------------------
	//  heightFrom
	//----------------------------------

	[Inspectable(category="General", defaultValue="NaN")]

	/** 
	 *  Initial height, in pixels.
	 *  If omitted, Flex uses the current height.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var heightFrom:Number;

 	//----------------------------------
	//  heightTo
	//----------------------------------

	[Inspectable(category="General", defaultValue="NaN")]

	/** 
	 *  Final height, in pixels.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var heightTo:Number;
	
 	//----------------------------------
	//  hideChildrenTargets
	//----------------------------------

	/**
	 *  An Array of Panel containers.
	 *  The children of these Panel containers are hidden while the Resize
	 *  effect plays.
	 *
	 *  <p>You use data binding syntax to set this property in MXML, 
	 *  as the following example shows, where panelOne and panelTwo 
	 *  are the names of two Panel containers in your application:</p>
	 *
	 *  <pre>&lt;mx:Resize id="e" heightFrom="100" heightTo="400"
	 *	hideChildrenTargets="{[panelOne, panelTwo]}" /&gt;</pre>		
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var hideChildrenTargets:Array /* of Panel */;
		
 	//----------------------------------
	//  widthBy
	//----------------------------------

	[Inspectable(category="General", defaultValue="NaN")]

	/** 
	 *  Number of pixels by which to modify the width of the component.
	 *  Values may be negative.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var widthBy:Number;

 	//----------------------------------
	//  widthFrom
	//----------------------------------

	[Inspectable(category="General", defaultValue="NaN")]

	/** 
	 *  Initial width, in pixels.
	 *  If omitted, Flex uses the current width.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var widthFrom:Number;
	
 	//----------------------------------
	//  widthTo
	//----------------------------------

	[Inspectable(category="General", defaultValue="NaN")]

	/** 
	 *  Final width, in pixels.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var widthTo:Number;
	
	//--------------------------------------------------------------------------
	//
	//  Overridden methods
	//
	//--------------------------------------------------------------------------
 
	/**
	 *  @private
	 */
	override public function getAffectedProperties():Array /* of String */
	{
		return AFFECTED_PROPERTIES;
	}	

	/**
	 *  @private
	 */
	override protected function initInstance(instance:IEffectInstance):void
	{
		super.initInstance(instance);
		
		var resizeInstance:ResizeInstance = ResizeInstance(instance);

		if (!isNaN(widthFrom))
			resizeInstance.widthFrom = widthFrom;
		if (!isNaN(widthTo))
			resizeInstance.widthTo = widthTo;
		if (!isNaN(widthBy))
			resizeInstance.widthBy = widthBy;
		if (!isNaN(heightFrom))
			resizeInstance.heightFrom = heightFrom;
		if (!isNaN(heightTo))
			resizeInstance.heightTo = heightTo;
		if (!isNaN(heightBy))
			resizeInstance.heightBy = heightBy;
		resizeInstance.hideChildrenTargets = hideChildrenTargets;
	}
}

}
