// Copyright 2015 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_H_
#define CC_ANIMATION_ANIMATION_H_

#include <vector>

#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cc/animation/animation_curve.h"
#include "cc/animation/animation_export.h"
#include "cc/animation/element_animations.h"
#include "cc/animation/keyframe_model.h"
#include "cc/trees/element_id.h"

namespace cc {

class AnimationDelegate;
class AnimationEvents;
class AnimationHost;
class AnimationTimeline;
class KeyframeEffect;
struct AnimationEvent;

// An Animation is responsible for managing animating properties for a set of
// targets. Each target is represented by a KeyframeEffect and can be animating
// multiple properties on that target; see the KeyframeEffect class.
//
// A particular Animation may not own all the KeyframeEffects for a given
// target. Animation is only a grouping mechanism for related effects, and the
// grouping relationship is defined by the client. It is also the client's
// responsibility to deal with any conflicts that arise from animating the same
// property of the same target across multiple Animations.
//
// Each Animation has a copy on the impl thread, and will take care of
// synchronizing to/from the impl thread when requested.
class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
 public:
  static scoped_refptr<Animation> Create(int id);
  virtual scoped_refptr<Animation> CreateImplInstance() const;

  int id() const { return id_; }
  typedef size_t KeyframeEffectId;
  ElementId element_id_of_keyframe_effect(
      KeyframeEffectId keyframe_effect_id) const;
  bool IsElementAttached(ElementId id) const;

  // Parent AnimationHost. Animation can be detached from AnimationTimeline.
  AnimationHost* animation_host() { return animation_host_; }
  const AnimationHost* animation_host() const { return animation_host_; }
  void SetAnimationHost(AnimationHost* animation_host);
  bool has_animation_host() const { return !!animation_host_; }

  // Parent AnimationTimeline.
  AnimationTimeline* animation_timeline() { return animation_timeline_; }
  const AnimationTimeline* animation_timeline() const {
    return animation_timeline_;
  }
  virtual void SetAnimationTimeline(AnimationTimeline* timeline);

  // TODO(smcgruer): If/once ScrollTimeline is supported on normal Animations,
  // we will need to move the promotion logic from WorkletAnimation to here.
  virtual void PromoteScrollTimelinePendingToActive() {}

  bool has_element_animations() const;
  scoped_refptr<ElementAnimations> element_animations(
      KeyframeEffectId keyframe_effect_id) const;

  void set_animation_delegate(AnimationDelegate* delegate) {
    animation_delegate_ = delegate;
  }

  void AttachElementForKeyframeEffect(ElementId element_id,
                                      KeyframeEffectId keyframe_effect_id);
  void DetachElementForKeyframeEffect(ElementId element_id,
                                      KeyframeEffectId keyframe_effect_id);
  virtual void DetachElement();

  void AddKeyframeModelForKeyframeEffect(
      std::unique_ptr<KeyframeModel> keyframe_model,
      KeyframeEffectId keyframe_effect_id);
  void PauseKeyframeModelForKeyframeEffect(int keyframe_model_id,
                                           double time_offset,
                                           KeyframeEffectId keyframe_effect_id);
  void RemoveKeyframeModelForKeyframeEffect(
      int keyframe_model_id,
      KeyframeEffectId keyframe_effect_id);
  void AbortKeyframeModelForKeyframeEffect(int keyframe_model_id,
                                           KeyframeEffectId keyframe_effect_id);
  void AbortKeyframeModelsWithProperty(TargetProperty::Type target_property,
                                       bool needs_completion);

  virtual void PushPropertiesTo(Animation* animation_impl);

  void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
  virtual void Tick(base::TimeTicks monotonic_time);

  void AddToTicking();
  void RemoveFromTicking();

  // AnimationDelegate routing.
  void NotifyKeyframeModelStarted(const AnimationEvent& event);
  void NotifyKeyframeModelFinished(const AnimationEvent& event);
  void NotifyKeyframeModelAborted(const AnimationEvent& event);
  void NotifyKeyframeModelTakeover(const AnimationEvent& event);
  size_t TickingKeyframeModelsCount() const;

  void SetNeedsPushProperties();

  // Make KeyframeModels affect active elements if and only if they affect
  // pending elements. Any KeyframeModels that no longer affect any elements
  // are deleted.
  void ActivateKeyframeEffects();

  // Returns the keyframe model animating the given property that is either
  // running, or is next to run, if such a keyframe model exists.
  KeyframeModel* GetKeyframeModelForKeyframeEffect(
      TargetProperty::Type target_property,
      KeyframeEffectId keyframe_effect_id) const;

  std::string ToString() const;

  void SetNeedsCommit();

  virtual bool IsWorkletAnimation() const;
  void AddKeyframeEffect(std::unique_ptr<KeyframeEffect>);

  KeyframeEffect* GetKeyframeEffectById(
      KeyframeEffectId keyframe_effect_id) const;
  KeyframeEffectId NextKeyframeEffectId() { return keyframe_effects_.size(); }

 private:
  friend class base::RefCounted<Animation>;

  void RegisterKeyframeEffect(ElementId element_id,
                              KeyframeEffectId keyframe_effect_id);
  void UnregisterKeyframeEffect(ElementId element_id,
                                KeyframeEffectId keyframe_effect_id);
  void RegisterKeyframeEffects();
  void UnregisterKeyframeEffects();

  void PushAttachedKeyframeEffectsToImplThread(Animation* animation_impl) const;
  void PushPropertiesToImplThread(Animation* animation_impl);

 protected:
  explicit Animation(int id);
  virtual ~Animation();

  AnimationHost* animation_host_;
  AnimationTimeline* animation_timeline_;
  AnimationDelegate* animation_delegate_;

  int id_;

  using ElementToKeyframeEffectIdMap =
      std::unordered_map<ElementId,
                         std::unordered_set<KeyframeEffectId>,
                         ElementIdHash>;
  using KeyframeEffects = std::vector<std::unique_ptr<KeyframeEffect>>;

  // It is possible for a keyframe_effect to be in keyframe_effects_ but not in
  // element_to_keyframe_effect_id_map_ but the reverse is not possible.
  ElementToKeyframeEffectIdMap element_to_keyframe_effect_id_map_;
  KeyframeEffects keyframe_effects_;

  int ticking_keyframe_effects_count;

  DISALLOW_COPY_AND_ASSIGN(Animation);
};

}  // namespace cc

#endif  // CC_ANIMATION_ANIMATION_H_
