// Copyright 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 CC_ANIMATION_LAYER_ANIMATION_CONTROLLER_H_
#define CC_ANIMATION_LAYER_ANIMATION_CONTROLLER_H_

#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "cc/animation/animation_events.h"
#include "cc/animation/layer_animation_event_observer.h"
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/transform.h"

namespace gfx {
class BoxF;
class Transform;
}

namespace cc {

class Animation;
class AnimationDelegate;
class AnimationRegistrar;
class FilterOperations;
class KeyframeValueList;
class LayerAnimationValueObserver;
class LayerAnimationValueProvider;

class CC_EXPORT LayerAnimationController
    : public base::RefCounted<LayerAnimationController> {
 public:
  static scoped_refptr<LayerAnimationController> Create(int id);

  int id() const { return id_; }

  void AddAnimation(scoped_ptr<Animation> animation);
  void PauseAnimation(int animation_id, base::TimeDelta time_offset);
  void RemoveAnimation(int animation_id);
  void RemoveAnimation(int animation_id,
                       Animation::TargetProperty target_property);
  void AbortAnimations(Animation::TargetProperty target_property);

  // Ensures that the list of active animations on the main thread and the impl
  // thread are kept in sync. This function does not take ownership of the impl
  // thread controller. This method is virtual for testing.
  virtual void PushAnimationUpdatesTo(
      LayerAnimationController* controller_impl);

  void Animate(base::TimeTicks monotonic_time);
  void AccumulatePropertyUpdates(base::TimeTicks monotonic_time,
                                 AnimationEventsVector* events);

  void UpdateState(bool start_ready_animations,
                   AnimationEventsVector* events);

  // Make animations affect active observers if and only if they affect
  // pending observers. Any animations that no longer affect any observers
  // are deleted.
  void ActivateAnimations();

  // Returns the active animation in the given group, animating the given
  // property, if such an animation exists.
  Animation* GetAnimation(int group_id,
                          Animation::TargetProperty target_property) const;

  // Returns the active animation animating the given property that is either
  // running, or is next to run, if such an animation exists.
  Animation* GetAnimation(Animation::TargetProperty target_property) const;

  // Returns true if there are any animations that have neither finished nor
  // aborted.
  bool HasActiveAnimation() const;

  // Returns true if there are any animations at all to process.
  bool has_any_animation() const { return !animations_.empty(); }

  // Returns true if there is an animation currently animating the given
  // property, or if there is an animation scheduled to animate this property in
  // the future.
  bool IsAnimatingProperty(Animation::TargetProperty target_property) const;

  void SetAnimationRegistrar(AnimationRegistrar* registrar);
  AnimationRegistrar* animation_registrar() { return registrar_; }

  void NotifyAnimationStarted(const AnimationEvent& event);
  void NotifyAnimationFinished(const AnimationEvent& event);
  void NotifyAnimationAborted(const AnimationEvent& event);
  void NotifyAnimationPropertyUpdate(const AnimationEvent& event);

  void AddValueObserver(LayerAnimationValueObserver* observer);
  void RemoveValueObserver(LayerAnimationValueObserver* observer);

  void AddEventObserver(LayerAnimationEventObserver* observer);
  void RemoveEventObserver(LayerAnimationEventObserver* observer);

  void set_value_provider(LayerAnimationValueProvider* provider) {
    value_provider_ = provider;
  }

  void remove_value_provider(LayerAnimationValueProvider* provider) {
    if (value_provider_ == provider)
      value_provider_ = nullptr;
  }

  void set_layer_animation_delegate(AnimationDelegate* delegate) {
    layer_animation_delegate_ = delegate;
  }

  void remove_layer_animation_delegate(AnimationDelegate* delegate) {
    if (layer_animation_delegate_ == delegate)
      layer_animation_delegate_ = nullptr;
  }

  bool HasFilterAnimationThatInflatesBounds() const;
  bool HasTransformAnimationThatInflatesBounds() const;
  bool HasAnimationThatInflatesBounds() const {
    return HasTransformAnimationThatInflatesBounds() ||
           HasFilterAnimationThatInflatesBounds();
  }

  bool FilterAnimationBoundsForBox(const gfx::BoxF& box,
                                   gfx::BoxF* bounds) const;
  bool TransformAnimationBoundsForBox(const gfx::BoxF& box,
                                      gfx::BoxF* bounds) const;

  bool HasAnimationThatAffectsScale() const;

  bool HasOnlyTranslationTransforms() const;

  // Sets |max_scale| to the maximum scale along any dimension at any
  // destination in active animations. Returns false if the maximum scale cannot
  // be computed.
  bool MaximumTargetScale(float* max_scale) const;

  bool needs_to_start_animations_for_testing() {
    return needs_to_start_animations_;
  }

 protected:
  friend class base::RefCounted<LayerAnimationController>;

  explicit LayerAnimationController(int id);
  virtual ~LayerAnimationController();

 private:
  typedef base::hash_set<int> TargetProperties;

  void PushNewAnimationsToImplThread(
      LayerAnimationController* controller_impl) const;
  void RemoveAnimationsCompletedOnMainThread(
      LayerAnimationController* controller_impl) const;
  void PushPropertiesToImplThread(
      LayerAnimationController* controller_impl) const;

  void StartAnimations(base::TimeTicks monotonic_time);
  void PromoteStartedAnimations(base::TimeTicks monotonic_time,
                                AnimationEventsVector* events);
  void MarkFinishedAnimations(base::TimeTicks monotonic_time);
  void MarkAnimationsForDeletion(base::TimeTicks monotonic_time,
                                 AnimationEventsVector* events);
  void PurgeAnimationsMarkedForDeletion();

  void TickAnimations(base::TimeTicks monotonic_time);

  enum UpdateActivationType {
    NormalActivation,
    ForceActivation
  };
  void UpdateActivation(UpdateActivationType type);

  void NotifyObserversOpacityAnimated(float opacity,
                                      bool notify_active_observers,
                                      bool notify_pending_observers);
  void NotifyObserversTransformAnimated(const gfx::Transform& transform,
                                        bool notify_active_observers,
                                        bool notify_pending_observers);
  void NotifyObserversFilterAnimated(const FilterOperations& filter,
                                     bool notify_active_observers,
                                     bool notify_pending_observers);
  void NotifyObserversScrollOffsetAnimated(
      const gfx::ScrollOffset& scroll_offset,
      bool notify_active_observers,
      bool notify_pending_observers);

  void NotifyObserversAnimationWaitingForDeletion();

  bool HasValueObserver();
  bool HasActiveValueObserver();

  AnimationRegistrar* registrar_;
  int id_;
  ScopedPtrVector<Animation> animations_;

  // This is used to ensure that we don't spam the registrar.
  bool is_active_;

  base::TimeTicks last_tick_time_;

  ObserverList<LayerAnimationValueObserver> value_observers_;
  ObserverList<LayerAnimationEventObserver> event_observers_;

  LayerAnimationValueProvider* value_provider_;

  AnimationDelegate* layer_animation_delegate_;

  // Only try to start animations when new animations are added or when the
  // previous attempt at starting animations failed to start all animations.
  bool needs_to_start_animations_;

  DISALLOW_COPY_AND_ASSIGN(LayerAnimationController);
};

}  // namespace cc

#endif  // CC_ANIMATION_LAYER_ANIMATION_CONTROLLER_H_
