// 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/basictypes.h"
#include "base/compiler_specific.h"
#include "ui/compositor/compositor_export.h"
#include "ui/compositor/layer_animation_element.h"

namespace ui {

class LayerAnimationSequence;
class ScopedLayerAnimationSettings;
class ImplicitAnimationObserver;

// LayerAnimationObservers are notified when animations complete.
class COMPOSITOR_EXPORT LayerAnimationObserver  {
 public:
  // 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 animator 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. NOTE: IF YOU override THIS
  // FUNCTION TO RETURN TRUE, YOU MUST REMEMBER TO REMOVE YOURSELF AS AN
  // OBSERVER WHEN YOU ARE DESTROYED.
  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;

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