// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_COMPOSITOR_LAYER_ANIMATION_ELEMENT_H_
#define UI_COMPOSITOR_LAYER_ANIMATION_ELEMENT_H_

#include <set>

#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "cc/animation/animation.h"
#include "cc/animation/animation_events.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/compositor_export.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/transform.h"

namespace ui {

class InterpolatedTransform;
class LayerAnimationDelegate;

// LayerAnimationElements represent one segment of an animation between two
// keyframes. They know how to update a LayerAnimationDelegate given a value
// between 0 and 1 (0 for initial, and 1 for final).
class COMPOSITOR_EXPORT LayerAnimationElement {
 public:
  enum AnimatableProperty {
    UNKNOWN = 0,
    TRANSFORM = (1 << 0),
    BOUNDS = (1 << 1),
    OPACITY = (1 << 2),
    VISIBILITY = (1 << 3),
    BRIGHTNESS = (1 << 4),
    GRAYSCALE = (1 << 5),
    COLOR = (1 << 6),

    // Used when iterating over properties.
    FIRST_PROPERTY = TRANSFORM,
    SENTINEL = (1 << 7)
  };

  static AnimatableProperty ToAnimatableProperty(
      cc::Animation::TargetProperty property);

  struct COMPOSITOR_EXPORT TargetValue {
    TargetValue();
    // Initializes the target value to match the delegate. NULL may be supplied.
    explicit TargetValue(const LayerAnimationDelegate* delegate);

    gfx::Rect bounds;
    gfx::Transform transform;
    float opacity;
    bool visibility;
    float brightness;
    float grayscale;
    SkColor color;
  };

  typedef uint32 AnimatableProperties;

  LayerAnimationElement(AnimatableProperties properties,
                        base::TimeDelta duration);

  virtual ~LayerAnimationElement();

  // Creates an element that transitions to the given transform. The caller owns
  // the return value.
  static LayerAnimationElement* CreateTransformElement(
      const gfx::Transform& transform,
      base::TimeDelta duration);

  // Creates an element that counters a transition to the given transform.
  // This element maintains the invariant uninverted_transition->at(t) *
  // this->at(t) == base_transform * this->at(t_start) for any t. The caller
  // owns the return value.
  static LayerAnimationElement* CreateInverseTransformElement(
      const gfx::Transform& base_transform,
      const LayerAnimationElement* uninverted_transition);


  // Duplicates elements as created by CreateInverseTransformElement.
  static LayerAnimationElement* CloneInverseTransformElement(
      const LayerAnimationElement* other);

  // Creates an element that transitions to another in a way determined by an
  // interpolated transform. The element accepts ownership of the interpolated
  // transform. NB: at every step, the interpolated transform clobbers the
  // existing transform. That is, it does not interpolate between the existing
  // transform and the last value the interpolated transform will assume. It is
  // therefore important that the value of the interpolated at time 0 matches
  // the current transform.
  static LayerAnimationElement* CreateInterpolatedTransformElement(
      InterpolatedTransform* interpolated_transform,
      base::TimeDelta duration);

  // Creates an element that transitions to the given bounds. The caller owns
  // the return value.
  static LayerAnimationElement* CreateBoundsElement(
      const gfx::Rect& bounds,
      base::TimeDelta duration);

  // Creates an element that transitions to the given opacity. The caller owns
  // the return value.
  static LayerAnimationElement* CreateOpacityElement(
      float opacity,
      base::TimeDelta duration);

  // Creates an element that sets visibily following a delay. The caller owns
  // the return value.
  static LayerAnimationElement* CreateVisibilityElement(
      bool visibility,
      base::TimeDelta duration);

  // Creates an element that transitions to the given brightness.
  // The caller owns the return value.
  static LayerAnimationElement* CreateBrightnessElement(
      float brightness,
      base::TimeDelta duration);

  // Creates an element that transitions to the given grayscale value.
  // The caller owns the return value.
  static LayerAnimationElement* CreateGrayscaleElement(
      float grayscale,
      base::TimeDelta duration);

  // Creates an element that pauses the given properties. The caller owns the
  // return value.
  static LayerAnimationElement* CreatePauseElement(
      AnimatableProperties properties,
      base::TimeDelta duration);

  // Creates an element that transitions to the given color. The caller owns the
  // return value.
  static LayerAnimationElement* CreateColorElement(
      SkColor color,
      base::TimeDelta duration);

  // Sets the start time for the animation. This must be called before the first
  // call to {Start, IsFinished}. Once the animation is finished, this must
  // be called again in order to restart the animation.
  void set_requested_start_time(base::TimeTicks start_time) {
    requested_start_time_ = start_time;
  }
  base::TimeTicks requested_start_time() const { return requested_start_time_; }

  // Sets the actual start time for the animation, taking into account any
  // queueing delays.
  void set_effective_start_time(base::TimeTicks start_time) {
    effective_start_time_ = start_time;
  }
  base::TimeTicks effective_start_time() const { return effective_start_time_; }

  // This must be called before the first call to Progress. If starting the
  // animation involves dispatching to another thread, then this will proceed
  // with that dispatch, ultimately resulting in the animation getting an
  // effective start time (the time the animation starts on the other thread).
  void Start(LayerAnimationDelegate* delegate, int animation_group_id);

  // Returns true if the animation has started but hasn't finished.
  bool Started() { return !first_frame_; }

  // Updates the delegate to the appropriate value for |now|. Returns true
  // if a redraw is required.
  bool Progress(base::TimeTicks now, LayerAnimationDelegate* delegate);

  // If calling Progress now, with the given time, will finish the animation,
  // returns true and sets |end_duration| to the actual duration for this
  // animation, incuding any queueing delays.
  bool IsFinished(base::TimeTicks time, base::TimeDelta* total_duration);

  // Updates the delegate to the end of the animation. Returns true if a
  // redraw is required.
  bool ProgressToEnd(LayerAnimationDelegate* delegate);

  // Called if the animation is not allowed to complete. This may be called
  // before OnStarted or Progress.
  void Abort(LayerAnimationDelegate* delegate);

  // Assigns the target value to |target|.
  void GetTargetValue(TargetValue* target) const;

  // The properties that the element modifies.
  AnimatableProperties properties() const { return properties_; }

  // Whether this element animates on the compositor thread.
  virtual bool IsThreaded() const;

  gfx::Tween::Type tween_type() const { return tween_type_; }
  void set_tween_type(gfx::Tween::Type tween_type) { tween_type_ = tween_type; }

  // Each LayerAnimationElement has a unique animation_id. Elements belonging
  // to sequences that are supposed to start together have the same
  // animation_group_id.
  int animation_id() const { return animation_id_; }
  int animation_group_id() const { return animation_group_id_; }
  void set_animation_group_id(int id) { animation_group_id_ = id; }

  base::TimeDelta duration() const { return duration_; }

  // The fraction of the animation that has been completed after the last
  // call made to {Progress, ProgressToEnd}.
  double last_progressed_fraction() const { return last_progressed_fraction_; }

 protected:
  // Called once each time the animation element is run before any call to
  // OnProgress.
  virtual void OnStart(LayerAnimationDelegate* delegate) = 0;
  virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) = 0;
  virtual void OnGetTarget(TargetValue* target) const = 0;
  virtual void OnAbort(LayerAnimationDelegate* delegate) = 0;

  // Actually start the animation, dispatching to another thread if needed.
  virtual void RequestEffectiveStart(LayerAnimationDelegate* delegate);

  LayerAnimationElement(const LayerAnimationElement& element);

 private:
  // For debugging purposes, we sometimes alter the duration we actually use.
  // For example, during tests we often set duration = 0, and it is sometimes
  // useful to slow animations down to see them more clearly.
  base::TimeDelta GetEffectiveDuration(const base::TimeDelta& delta);

  bool first_frame_;
  const AnimatableProperties properties_;
  base::TimeTicks requested_start_time_;

  // When the animation actually started, taking into account queueing delays.
  base::TimeTicks effective_start_time_;
  const base::TimeDelta duration_;
  gfx::Tween::Type tween_type_;

  const int animation_id_;
  int animation_group_id_;

  double last_progressed_fraction_;

  base::WeakPtrFactory<LayerAnimationElement> weak_ptr_factory_;

  DISALLOW_ASSIGN(LayerAnimationElement);
};

}  // namespace ui

#endif  // UI_COMPOSITOR_LAYER_ANIMATION_ELEMENT_H_
