// 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_OBSERVER_H_
#define UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_

#include <map>
#include <set>

#include "base/compiler_specific.h"
#include "ui/compositor/compositor_export.h"
#include "ui/compositor/layer_animation_element.h"

namespace ui {

namespace test {
class LayerAnimationObserverTestApi;
}  // namespace test

class LayerAnimationSequence;
class ScopedLayerAnimationSettings;
class ImplicitAnimationObserver;

// LayerAnimationObservers are notified when animations complete.
class COMPOSITOR_EXPORT LayerAnimationObserver  {
 public:
  // Called when the |sequence| starts.
  virtual void OnLayerAnimationStarted(LayerAnimationSequence* sequence);

  // Called when the |sequence| ends. Not called if |sequence| is aborted.
  virtual void OnLayerAnimationEnded(
      LayerAnimationSequence* sequence) = 0;

  // Called if |sequence| is aborted for any reason. Should never do anything
  // that may cause another animation to be started.
  virtual void OnLayerAnimationAborted(
      LayerAnimationSequence* sequence) = 0;

  // Called when the animation is scheduled.
  virtual void OnLayerAnimationScheduled(
      LayerAnimationSequence* sequence) = 0;

 protected:
  typedef std::set<LayerAnimationSequence*> AttachedSequences;

  LayerAnimationObserver();
  virtual ~LayerAnimationObserver();

  // If the LayerAnimator is destroyed during an animation, the animations are
  // aborted. The resulting NotifyAborted notifications will NOT be sent to
  // this observer if this function returns false. An observer who wants to
  // receive the NotifyAborted notifications during destruction can override
  // this function to return true.
  //
  // *** IMPORTANT ***: If a class overrides this function to return true and
  // that class is a direct or indirect owner of the LayerAnimationSequence
  // being observed, then the class must explicitly remove itself as an
  // observer during destruction of the LayerAnimationObserver! This is to
  // ensure that a partially destroyed observer isn't notified with an
  // OnLayerAnimationAborted() call when the LayerAnimator is destroyed.
  //
  // This opt-in pattern is used because it is common for a class to be the
  // observer of a LayerAnimationSequence that it owns indirectly because it
  // owns the Layer which owns the LayerAnimator which owns the
  // LayerAnimationSequence.
  virtual bool RequiresNotificationWhenAnimatorDestroyed() const;

  // Called when |this| is added to |sequence|'s observer list.
  virtual void OnAttachedToSequence(LayerAnimationSequence* sequence);

  // Called when |this| is removed to |sequence|'s observer list.
  virtual void OnDetachedFromSequence(LayerAnimationSequence* sequence);

  // Detaches this observer from all sequences it is currently observing.
  void StopObserving();

  const AttachedSequences& attached_sequences() const {
    return attached_sequences_;
  }

 private:
  friend class LayerAnimationSequence;
  friend class test::LayerAnimationObserverTestApi;

  // Called when |this| is added to |sequence|'s observer list.
  void AttachedToSequence(LayerAnimationSequence* sequence);

  // Called when |this| is removed to |sequence|'s observer list.
  // This will only result in notifications if |send_notification| is true.
  void DetachedFromSequence(LayerAnimationSequence* sequence,
                            bool send_notification);

  AttachedSequences attached_sequences_;
};

// An implicit animation observer is intended to be used in conjunction with a
// ScopedLayerAnimationSettings object in order to receive a notification when
// all implicit animations complete.
// TODO(bruthig): Unify the ImplicitAnimationObserver with the
// CallbackLayerAnimationObserver. (See www.crbug.com/542825).
class COMPOSITOR_EXPORT ImplicitAnimationObserver
    : public LayerAnimationObserver {
 public:
  ImplicitAnimationObserver();
  ~ImplicitAnimationObserver() override;

  // Called when the first animation sequence has started.
  virtual void OnImplicitAnimationsScheduled() {}

  virtual void OnImplicitAnimationsCompleted() = 0;

 protected:
  // Deactivates the observer and clears the collection of animations it is
  // waiting for.
  void StopObservingImplicitAnimations();

  // Returns whether animation for |property| was aborted.
  // Note that if the property wasn't animated, then it couldn't have been
  // aborted, so this will return false for that property.
  bool WasAnimationAbortedForProperty(
      LayerAnimationElement::AnimatableProperty property) const;

  // Returns whether animation for |property| was completed successfully.
  // Note that if the property wasn't animated, then it couldn't have been
  // completed, so this will return false for that property.
  bool WasAnimationCompletedForProperty(
      LayerAnimationElement::AnimatableProperty property) const;

 private:
  enum AnimationStatus {
    ANIMATION_STATUS_UNKNOWN,
    ANIMATION_STATUS_COMPLETED,
    ANIMATION_STATUS_ABORTED,
  };

  friend class ScopedLayerAnimationSettings;

  // LayerAnimationObserver implementation
  void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override;
  void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override;
  void OnLayerAnimationScheduled(LayerAnimationSequence* sequence) override;
  void OnAttachedToSequence(LayerAnimationSequence* sequence) override;
  void OnDetachedFromSequence(LayerAnimationSequence* sequence) override;

  // OnImplicitAnimationsCompleted is not fired unless the observer is active.
  bool active() const { return active_; }
  void SetActive(bool active);

  void CheckCompleted();

  void UpdatePropertyAnimationStatus(LayerAnimationSequence* sequence,
                                     AnimationStatus status);
  AnimationStatus AnimationStatusForProperty(
      LayerAnimationElement::AnimatableProperty property) const;

  bool active_;

  // Set to true in the destructor (if non-NULL). Used to detect deletion while
  // calling out.
  bool* destroyed_;

  typedef std::map<LayerAnimationElement::AnimatableProperty,
                   AnimationStatus> PropertyAnimationStatusMap;
  PropertyAnimationStatusMap property_animation_status_;

  // True if OnLayerAnimationScheduled() has been called at least once.
  bool first_sequence_scheduled_;
};

}  // namespace ui

#endif  // UI_COMPOSITOR_LAYER_ANIMATION_OBSERVER_H_
