////////////////////////////////////////////////////////////////////////////////
//
//  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 flash.events.Event;
import flash.events.IEventDispatcher;

/**
 *  The IEffect interface defines the base 
 *  interface of all Flex effects.
 *  The IEffectInstance interface defines the base interface for all effect
 *  instance subclasses.
 *
 *  @see mx.effects.IEffectInstance
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public interface IEffect extends IAbstractEffect
{
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  className
    //----------------------------------

    /**
     *  The name of the effect class, such as <code>"Fade"</code>.
     *
     *  <p>This is a short, or unqualified, class name
     *  that does not include the package name.
     *  If you need the qualified name, use the 
     *  <code>getQualifiedClassName()</code> method
     *  in the flash.utils package.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get className():String;

    //----------------------------------
    //  customFilter
    //----------------------------------

    /**
     *  Specifies a custom filter object, of type EffectTargetFilter,
     *  used by the effect to determine the targets
     *  on which to play the effect. 
     *  
     *  <p>Target filtering is only performed if you call the
     *  <code>captureStartValues()</code> method before playing the effect.
     *  Flex automatically calls the <code>captureStartValues()</code> method
     *  when the effect is part of a transition.</p>
     *  
     *  <p>Use the <code>filter</code> property for simple filtering.
     *  If the <code>customFilter</code> property is non-null,
     *  the <code>filter</code> property is ignored.</p>
     *
     *  @default null
     *
     *  @see mx.effects.EffectTargetFilter
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get customFilter():EffectTargetFilter;
    
    /**
     *  @private
     */
    function set customFilter(value:EffectTargetFilter):void;

    //----------------------------------
    //  duration
    //----------------------------------

    /** 
     *  Duration of the effect in milliseconds. 
     *
     *  <p>In a Parallel or Sequence effect, the <code>duration</code>
     *  property sets the duration of each effect.
     *  For example, if a Sequence effect has its <code>duration</code>
     *  property set to 3000, each effect in the Sequence takes 3000 ms
     *  to play.</p>
     *
     *  <p>For a repeated effect, the <code>duration</code> property
     *  specifies  the duration of a single instance of the effect. 
     *  Therefore, if an effect has a <code>duration</code> property
     *  set to 2000, and a <code>repeatCount</code> property set to 3, 
     *  the effect takes a total of 6000 ms (6 seconds) to play.</p>
     *
     *  @default 500
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get duration():Number;
    
    /**
     *  @private
     */
    function set duration(value:Number):void;

    //----------------------------------
    //  effectTargetHost
    //----------------------------------

    /**
     *  A property that lets you access the target list-based control
     *  of a data effect. 
     *  This property enables an instance of an effect class to communicate
     *  with the list-based control on which the effect is playing. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get effectTargetHost():IEffectTargetHost;
    
    /**
     *  @private
     */
    function set effectTargetHost(value:IEffectTargetHost):void;

    //----------------------------------
    //  filter
    //----------------------------------

    /**
     *  Specifies an algorithm for filtering targets for an effect. 
     *  A value of <code>null</code> specifies no filtering.
     *  
     *  <p>Target filtering is only performed if you call the
     *  <code>captureStartValues()</code> method before playing the effect.
     *  Flex automatically calls the <code>captureStartValues()</code> method
     *  when the effect is part of a transition, or part of a data effect
     *  for a list-based control.</p>
     *  
     *  <p>Use this property for simple filtering.
     *  Use the <code>customFilter</code> property for more complex filtering. 
     *  If the <code>customFilter</code> property has a non-null value, 
     *  this property is ignored.</p> 
     *
     *  <p>You can use the following values for the <code>filter</code>
     *  property:</p>
     *
     *  <ul>
     *    <li>A value of <code>"add"</code> plays the effect on any targets 
     *      that are added as a child to a container.</li>
     *    <li>A value of <code>"addItem"</code> plays the effect
     *      on the item renderer for any list items added to a List
     *      or TileList control.</li>
     *    <li>A value of <code>"hide"</code> plays the effect on any targets
     *      whose visible property changed from <code>true</code> to
     *      <code>false</code>.</li>
     *    <li>A value of <code>"move"</code> plays the effect on any targets
     *      that changed their <code>x</code> or <code>y</code>
     *      properties.</li>
     *    <li>A value of <code>"remove"</code> plays the effect on any targets
     *      that are removed as a child of a container.</li>
     *    <li>A value of <code>"removeItem"</code> plays the effect
     *      on the item renderer for any list items removed from a List
     *      or TileList control.</li>
     *    <li>A value of <code>"replacedItem"</code> plays the effect
     *      on the item renderer for any list items replaced in a List
     *      or TileList control by a new item.</li>
     *    <li>A value of <code>"replacementItem"</code> plays the effect
     *      on the item renderer for any list items added to a List
     *      or TileList control that replaces an existing item.</li>
     *    <li>A value of <code>"resize"</code> plays the effect
     *      on any targets that changed their <code>width</code>
     *      or <code>height</code> properties.</li>
     *    <li>A value of <code>"show"</code> plays the effect
     *      on any targets whose visible property changed
     *      from <code>false</code> to <code>true</code>.</li>
     *    <li>A value of <code>""</code> specifies no filtering.</li>
     *  </ul>
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get filter():String;
    
    /**
     *  @private
     */
    function set filter(value:String):void;

    //----------------------------------
    //  hideFocusRing
    //----------------------------------

    /**
     *  Determines whether the effect should hide the focus ring
     *  when starting the effect.
     *  The effect target is responsible for the hiding the focus ring. 
     *  Subclasses of the UIComponent class hide the focus ring automatically. 
     *  If the effect target is not a subclass of the UIComponent class,
     *  add functionality to it to hide the focus ring.
     *
     *  <p>Set this property to <code>true</code>
     *  to hide the focus ring during the effect.</p>
     *  
     *  <p>For subclasses of Effect, the default value is <code>false</code>. 
     *  For subclasses of MaskEffect, the default value is <code>true</code>.
     *  </p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get hideFocusRing():Boolean;
    
    /**
     *  @private
     */
    function set hideFocusRing(value:Boolean):void;

    //----------------------------------
    //  isPlaying
    //----------------------------------

    /**
     *  A read-only flag which is true if any instances of the effect
     *  are currently playing, and false if none are.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get isPlaying():Boolean;

    //----------------------------------
    //  perElementOffset
    //----------------------------------

    /**
     *  Additional delay, in milliseconds, for effect targets
     *  after the first target of the effect.
     *  This value is added to the value
     *  of the <code>startDelay</code> property.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    function get perElementOffset():Number;
    
    /**
     *  @private
     */
    function set perElementOffset(value:Number):void;

    //----------------------------------
    //  relevantProperties
    //----------------------------------

    /**
     *  An Array of property names to use when performing filtering. 
     *  This property is used internally and should not be set by 
     *  effect users. 
     *
     *  <p>The default value is equal to the Array returned by 
     *  the <code>getAffectedProperties()</code> method.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get relevantProperties():Array /* of String */;

    /**
     *  @private
     */
    function set relevantProperties(values:Array /* of String */):void;
    
    //----------------------------------
    //  relevantStyles
    //----------------------------------

    /**
     *  An Array of style names to use when performing filtering. 
     *  This property is used internally and should not be set by 
     *  effect users. 
     *
     *  <p>The default value is equal to the Array returned by 
     *  the <code>getAffectedProperties()</code> method.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get relevantStyles():Array /* of String */;
    
    /**
     *  @private
     */
    function set relevantStyles(values:Array /* of String */):void;
    
    
    //----------------------------------
    //  target
    //----------------------------------

    /** 
     *  The object to which this effect is applied.
     *  When an effect is triggered by an effect trigger, 
     *  the <code>target</code> property is automatically set to be 
     *  the object that triggers the effect.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get target():Object;
    
    /**
     *  @private
     */
    function set target(value:Object):void;

    //----------------------------------
    //  targets
    //----------------------------------

    /**
     *  An Array of objects that are targets for the effect.
     *  When the effect is playing, it performs the effect on each target
     *  in parallel. 
     *  Setting the <code>target</code> property replaces all objects
     *  in this Array. 
     *  When the <code>targets</code> property is set, the <code>target</code>
     *  property returns the first item in this Array. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get targets():Array;
    
    /**
     *  @private
     */
    function set targets(value:Array):void;

    //----------------------------------
    //  triggerEvent
    //----------------------------------

    /**
     *  The Event object passed to this Effect 
     *  by the EffectManager when an effect is triggered,
     *  or <code>null</code> if the effect is not being
     *  played by the EffectManager.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get triggerEvent():Event;
    
    /**
     *  @private
     */
    function set triggerEvent(value:Event):void;

    //----------------------------------
    //  playheadTime
    //----------------------------------

    /**
     *  Current time position of the effect.
     *  This property has a value between 0 and the total duration, 
     *  which includes the Effect's <code>startDelay</code>, 
     *  <code>repeatCount</code>, and <code>repeatDelay</code>.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function get playheadTime():Number;
    
    /**
     * @private
     */
    function set playheadTime(value:Number):void;

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

    /**
     *  Returns an Array of Strings, where each String is the name
     *  of a property changed by this effect.
     *  For example, the Move effect returns an Array that contains
     *  <code>"x"</code> and <code>"y"</code>.
     *
     *  <p>Every subclass of Effect must implement this method.
     *  The EffectManager uses this method 
     *  to ensure that no two effects are trying to animate
     *  the same property of the same object at the same time.</p>
     *
     *  @return An Array of Strings specifying the names of the 
     *  properties modified by this effect.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function getAffectedProperties():Array /* of String */;

    /**
     *  Takes an Array of target objects and invokes the 
     *  <code>createInstance()</code> method on each target. 
     *
     *  @param targets Array of objects to animate with this effect.
     *
     *  @return Array of effect instance objects, one per target,
     *  for the effect.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function createInstances(targets:Array = null):Array /* of EffectInstance */;

    /**
     *  Creates a single effect instance and initializes it.
     *  Use this method instead of the <code>play()</code> method
     *  to manipulate the effect instance properties
     *  before the effect instance plays. 
     *  
     *  <p>The effect instance is created with the type 
     *  specified in the <code>instanceClass</code> property.
     *  It is then initialized using the <code>initInstance()</code> method. 
     *  If the instance was created by the EffectManager 
     *  (when the effect is triggered by an effect trigger), 
     *  the effect is further initialized by a call to the 
     *  <code>EffectInstance.initEffect()</code> method.</p>
     * 
     *  <p>Calling the <code>createInstance()</code> method 
     *  does not play the effect.
     *  Call the <code>startEffect()</code> method
     *  on the returned effect instance. </p>
     *
     *  <p>This function is automatically called by the 
     *  <code>Effect.play()</code> method. </p>
     *
     *  @param target Object to animate with this effect.
     *
     *  @return The effect instance object for the effect.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function createInstance(target:Object = null):IEffectInstance;

    /**
     *  Removes event listeners from an instance
     *  and removes it from the list of instances.
     *
     *  @param instance The effect instance.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function deleteInstance(instance:IEffectInstance):void;

    /**
     *  Begins playing the effect.
     *  You typically call the <code>end()</code> method 
     *  before you call the <code>play()</code> method
     *  to ensure that any previous instance of the effect
     *  has ended before you start a new one.
     *
     *  <p>All subclasses must implement this method.</p>
     *
     *  @param targets Array of target objects on which to play this effect.
     *  If this parameter is specified, then the effect's <code>targets</code>
     *  property is not used.
     *
     *  @param playReversedFromEnd If <code>true</code>,
     *  play the effect backwards.
     *
     *  @return Array of EffectInstance objects, one per target,
     *  for the effect.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    function play(targets:Array = null,
                  playReversedFromEnd:Boolean = false):
                  Array /* of EffectInstance */;

    /**
     *  Pauses the effect until you call the <code>resume()</code> method.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function pause():void;

    /**
     *  Stops the effect, leaving the effect targets in their current state.
     *  Unlike a call to the <code>pause()</code> method, 
     *  you cannot call the <code>resume()</code> method after calling 
     *  the <code>stop()</code> method. 
     *  However, you can call the <code>play()</code> method to restart the effect.
     *
     *  <p>The effect instance dispatches an <code>effectEnd</code> event
     *  when you call this method as part of ending the effect.</p>
     * 
     *  <p>For mask effects, the mask is not removed automatically
     *  when the effect is stopped.
     *  Running further mask effects on the same target(s)
     *  without first removing the mask can produce unexpected results.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function stop():void;

    /**
     *  Resumes the effect after it has been paused 
     *  by a call to the <code>pause()</code> method. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function resume():void;

    /**
     *  Plays the effect in reverse, if the effect is currently playing,
     *  starting from the current position of the effect.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function reverse():void;

    /**
     *  Interrupts an effect that is currently playing,
     *  and jumps immediately to the end of the effect.
     *  Calling this method invokes the <code>EffectInstance.end()</code>
     *  method.
     *
     *  <p>The effect instance dispatches an <code>effectEnd</code> event
     *  when you call this method as part of ending the effect.</p>
     *
     *  <p>If you pass an effect instance as an argument, 
     *  just that instance is interrupted.
     *  If no argument is passed in, all effect instances currently
     *  spawned from the effect are interrupted.</p>
     *
     *  @param effectInstance EffectInstance to terminate.
     *
     *  @see mx.effects.EffectInstance#end()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function end(effectInstance:IEffectInstance = null):void;

    /**
     *  Captures the current values of the relevant properties
     *  on the effect's targets. 
     *  Flex automatically calls the <code>captureStartValues()</code>
     *  method when the effect is part of a transition.
     *  
     *  <p>Use this function when you want the effect to figure out the start 
     *  and end values of the effect.
     *  The proper usage of this function is to use it
     *  in the following steps:</p>
     *  
     *  <ol>
     *    <li>Call the <code>captureStartValues()</code> method. 
     *      The effect captures the starting effect values.</li>
     *    <li>Make changes to your effect targets, such as
     *      adding/removing children, altering properties,
     *      changing location, or changing dimensions.</li>
     *    <li>Call the <code>play()</code> method.  
     *      The effect captures the end values.
     *      This function populates the
     *      <code>EffectInstance.propertyChanges</code> property
     *      for each effect instance created by this effect. 
     *      Effect developers can use the <code>propertyChanges</code> property 
     *      to retrieve the start and end values for their effect.</li>
     *  </ol>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function captureStartValues():void;
    
    /**
     *  Captures the current values of the relevant properties
     *  of an additional set of targets
     * 
     *  <p>Flex uses this function when a data change
     *  effect is run.</p>
     * 
     *  @param targets Array of targets for which values are captured
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function captureMoreStartValues(targets:Array):void;

    /**
     *  Captures the current values of the relevant properties
     *  on the effect's targets and saves them as end values.
     *  
     *  <p>Flex automatically calls the <code>captureEndValues()</code> method
     *  when the effect is part of a data change effect.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    function captureEndValues():void;
}

}
