// Copyright 2017 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_ANIMATION_TICKER_H_
#define CC_ANIMATION_ANIMATION_TICKER_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cc/animation/animation_events.h"
#include "cc/animation/animation_export.h"
#include "cc/animation/element_animations.h"
#include "cc/trees/element_id.h"
#include "cc/trees/mutator_host_client.h"
#include "cc/trees/target_property.h"
#include "ui/gfx/geometry/box_f.h"
#include "ui/gfx/geometry/scroll_offset.h"

#include <memory>
#include <vector>

namespace cc {

class Animation;
class AnimationPlayer;
struct PropertyAnimationState;

// An AnimationTicker owns a group of Animations for a single target (identified
// by a ElementId). It is responsible for managing the animations' running
// states (starting, running, paused, etc), as well as ticking the animations
// when it is requested to produce new outputs for a given time.
//
// Note that a single AnimationTicker may not own all the animations for a given
// target. AnimationTicker is only a grouping mechanism for related animations.
// The commonality between animations on the same target is found via
// ElementAnimations - there is only one ElementAnimations for a given target.
class CC_ANIMATION_EXPORT AnimationTicker {
 public:
  class AnimationTimeProvider {
   public:
    virtual base::TimeTicks GetTimeForAnimation(const Animation&) const = 0;
  };

  explicit AnimationTicker(AnimationPlayer* animation_player);
  ~AnimationTicker();

  // ElementAnimations object where this controller is listed.
  scoped_refptr<ElementAnimations> element_animations() const {
    return element_animations_;
  }

  bool has_bound_element_animations() const { return !!element_animations_; }

  bool has_attached_element() const { return !!element_id_; }

  ElementId element_id() const { return element_id_; }

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

  // When a scroll animation is removed on the main thread, its compositor
  // thread counterpart continues producing scroll deltas until activation.
  // These scroll deltas need to be cleared at activation, so that the active
  // element's scroll offset matches the offset provided by the main thread
  // rather than a combination of this offset and scroll deltas produced by the
  // removed animation. This is to provide the illusion of synchronicity to JS
  // that simultaneously removes an animation and sets the scroll offset.
  bool scroll_offset_animation_was_interrupted() const {
    return scroll_offset_animation_was_interrupted_;
  }

  bool needs_push_properties() const { return needs_push_properties_; }
  void SetNeedsPushProperties();

  void BindElementAnimations(ElementAnimations* element_animations);
  void UnbindElementAnimations();

  void AttachElement(ElementId element_id);
  void DetachElement();

  void Tick(base::TimeTicks monotonic_time,
            const AnimationTimeProvider* tick_provider);
  static void TickAnimation(base::TimeTicks monotonic_time,
                            Animation* animation,
                            AnimationTarget* target);
  void RemoveFromTicking();

  void UpdateState(bool start_ready_animations, AnimationEvents* events);
  void UpdateTickingState(UpdateTickingType type);

  void AddAnimation(std::unique_ptr<Animation> animation);
  void PauseAnimation(int animation_id, double time_offset);
  void RemoveAnimation(int animation_id);
  void AbortAnimation(int animation_id);
  void AbortAnimations(TargetProperty::Type target_property,
                       bool needs_completion);

  void ActivateAnimations();

  void AnimationAdded();

  // The following methods should be called to notify the AnimationTicker that
  // an animation event has been received for the same target (ElementId) as
  // this ticker. If the event matches an Animation owned by this
  // AnimationTicker the call will return true, else it will return false.
  bool NotifyAnimationStarted(const AnimationEvent& event);
  bool NotifyAnimationFinished(const AnimationEvent& event);
  void NotifyAnimationTakeover(const AnimationEvent& event);
  bool NotifyAnimationAborted(const AnimationEvent& event);

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

  bool HasNonDeletedAnimation() const;

  bool HasOnlyTranslationTransforms(ElementListType list_type) const;

  bool AnimationsPreserveAxisAlignment() const;

  // Sets |start_scale| to the maximum of starting animation scale along any
  // dimension at any destination in active animations. Returns false if the
  // starting scale cannot be computed.
  bool AnimationStartScale(ElementListType, float* start_scale) 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(ElementListType, float* max_scale) const;

  // Returns true if there is an animation that is either currently animating
  // the given property or scheduled to animate this property in the future, and
  // that affects the given tree type.
  bool IsPotentiallyAnimatingProperty(TargetProperty::Type target_property,
                                      ElementListType list_type) const;

  // Returns true if there is an animation that is currently animating the given
  // property and that affects the given tree type.
  bool IsCurrentlyAnimatingProperty(TargetProperty::Type target_property,
                                    ElementListType list_type) const;

  Animation* GetAnimation(TargetProperty::Type target_property) const;
  Animation* GetAnimationById(int animation_id) const;

  void GetPropertyAnimationState(PropertyAnimationState* pending_state,
                                 PropertyAnimationState* active_state) const;

  void MarkAbortedAnimationsForDeletion(AnimationTicker* element_ticker_impl);
  void PurgeAnimationsMarkedForDeletion(bool impl_only);
  void PushNewAnimationsToImplThread(
      AnimationTicker* element_ticker_impl) const;
  void RemoveAnimationsCompletedOnMainThread(
      AnimationTicker* element_ticker_impl) const;
  void PushPropertiesTo(AnimationTicker* animation_ticker_impl);

  std::string AnimationsToString() const;

 private:
  void StartAnimations(base::TimeTicks monotonic_time);
  void PromoteStartedAnimations(AnimationEvents* events);

  void MarkAnimationsForDeletion(base::TimeTicks, AnimationEvents* events);
  void MarkFinishedAnimations(base::TimeTicks monotonic_time);

  bool HasElementInActiveList() const;
  gfx::ScrollOffset ScrollOffsetForAnimation() const;

  std::vector<std::unique_ptr<Animation>> animations_;
  AnimationPlayer* animation_player_;
  ElementId element_id_;

  // element_animations_ is non-null if controller is attached to an element.
  scoped_refptr<ElementAnimations> element_animations_;

  // 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_;

  bool scroll_offset_animation_was_interrupted_;

  bool is_ticking_;
  base::TimeTicks last_tick_time_;

  bool needs_push_properties_;

  DISALLOW_COPY_AND_ASSIGN(AnimationTicker);
};

}  // namespace cc

#endif  // CC_ANIMATION_ANIMATION_TICKER_H_
