// 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 UI_GFX_ANIMATION_KEYFRAME_KEYFRAMED_ANIMATION_CURVE_H_
#define UI_GFX_ANIMATION_KEYFRAME_KEYFRAMED_ANIMATION_CURVE_H_

#include <memory>
#include <utility>
#include <vector>

#include "base/time/time.h"
#include "ui/gfx/animation/keyframe/animation_curve.h"
#include "ui/gfx/animation/keyframe/keyframe_animation_export.h"
#include "ui/gfx/animation/keyframe/timing_function.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/geometry/transform_operations.h"

namespace gfx {

class GFX_KEYFRAME_ANIMATION_EXPORT Keyframe {
 public:
  Keyframe(const Keyframe&) = delete;
  Keyframe& operator=(const Keyframe&) = delete;

  base::TimeDelta Time() const;
  const TimingFunction* timing_function() const {
    return timing_function_.get();
  }

 protected:
  Keyframe(base::TimeDelta time,
           std::unique_ptr<TimingFunction> timing_function);
  virtual ~Keyframe();

 private:
  base::TimeDelta time_;
  std::unique_ptr<TimingFunction> timing_function_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT ColorKeyframe : public Keyframe {
 public:
  static std::unique_ptr<ColorKeyframe> Create(
      base::TimeDelta time,
      SkColor value,
      std::unique_ptr<TimingFunction> timing_function);
  ~ColorKeyframe() override;

  SkColor Value() const;

  std::unique_ptr<ColorKeyframe> Clone() const;

 private:
  ColorKeyframe(base::TimeDelta time,
                SkColor value,
                std::unique_ptr<TimingFunction> timing_function);

  SkColor value_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT FloatKeyframe : public Keyframe {
 public:
  static std::unique_ptr<FloatKeyframe> Create(
      base::TimeDelta time,
      float value,
      std::unique_ptr<TimingFunction> timing_function);
  ~FloatKeyframe() override;

  float Value() const;

  std::unique_ptr<FloatKeyframe> Clone() const;

 private:
  FloatKeyframe(base::TimeDelta time,
                float value,
                std::unique_ptr<TimingFunction> timing_function);

  float value_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT TransformKeyframe : public Keyframe {
 public:
  static std::unique_ptr<TransformKeyframe> Create(
      base::TimeDelta time,
      const gfx::TransformOperations& value,
      std::unique_ptr<TimingFunction> timing_function);
  ~TransformKeyframe() override;

  const gfx::TransformOperations& Value() const;

  std::unique_ptr<TransformKeyframe> Clone() const;

 private:
  TransformKeyframe(base::TimeDelta time,
                    const gfx::TransformOperations& value,
                    std::unique_ptr<TimingFunction> timing_function);

  gfx::TransformOperations value_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT SizeKeyframe : public Keyframe {
 public:
  static std::unique_ptr<SizeKeyframe> Create(
      base::TimeDelta time,
      const gfx::SizeF& bounds,
      std::unique_ptr<TimingFunction> timing_function);
  ~SizeKeyframe() override;

  const gfx::SizeF& Value() const;

  std::unique_ptr<SizeKeyframe> Clone() const;

 private:
  SizeKeyframe(base::TimeDelta time,
               const gfx::SizeF& value,
               std::unique_ptr<TimingFunction> timing_function);

  gfx::SizeF value_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT RectKeyframe : public Keyframe {
 public:
  static std::unique_ptr<RectKeyframe> Create(
      base::TimeDelta time,
      const gfx::Rect& value,
      std::unique_ptr<TimingFunction> timing_function);
  ~RectKeyframe() override;

  const gfx::Rect& Value() const;

  std::unique_ptr<RectKeyframe> Clone() const;

 private:
  RectKeyframe(base::TimeDelta time,
               const gfx::Rect& value,
               std::unique_ptr<TimingFunction> timing_function);

  gfx::Rect value_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT KeyframedColorAnimationCurve
    : public ColorAnimationCurve {
 public:
  // It is required that the keyframes be sorted by time.
  static std::unique_ptr<KeyframedColorAnimationCurve> Create();

  KeyframedColorAnimationCurve(const KeyframedColorAnimationCurve&) = delete;
  ~KeyframedColorAnimationCurve() override;

  KeyframedColorAnimationCurve& operator=(const KeyframedColorAnimationCurve&) =
      delete;

  void AddKeyframe(std::unique_ptr<ColorKeyframe> keyframe);
  void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) {
    timing_function_ = std::move(timing_function);
  }
  double scaled_duration() const { return scaled_duration_; }
  void set_scaled_duration(double scaled_duration) {
    scaled_duration_ = scaled_duration;
  }

  // AnimationCurve implementation
  base::TimeDelta Duration() const override;
  std::unique_ptr<AnimationCurve> Clone() const override;
  base::TimeDelta TickInterval() const override;

  // BackgrounColorAnimationCurve implementation
  SkColor GetValue(base::TimeDelta t) const override;

  std::unique_ptr<AnimationCurve> Retarget(base::TimeDelta t,
                                           SkColor new_target);

  using Keyframes = std::vector<std::unique_ptr<ColorKeyframe>>;
  const Keyframes& keyframes_for_testing() const { return keyframes_; }

 private:
  KeyframedColorAnimationCurve();

  // Always sorted in order of increasing time. No two keyframes have the
  // same time.
  Keyframes keyframes_;
  std::unique_ptr<TimingFunction> timing_function_;
  double scaled_duration_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT KeyframedFloatAnimationCurve
    : public FloatAnimationCurve {
 public:
  // It is required that the keyframes be sorted by time.
  static std::unique_ptr<KeyframedFloatAnimationCurve> Create();

  KeyframedFloatAnimationCurve(const KeyframedFloatAnimationCurve&) = delete;
  ~KeyframedFloatAnimationCurve() override;

  KeyframedFloatAnimationCurve& operator=(const KeyframedFloatAnimationCurve&) =
      delete;

  void AddKeyframe(std::unique_ptr<FloatKeyframe> keyframe);

  void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) {
    timing_function_ = std::move(timing_function);
  }
  TimingFunction* timing_function_for_testing() const {
    return timing_function_.get();
  }
  double scaled_duration() const { return scaled_duration_; }
  void set_scaled_duration(double scaled_duration) {
    scaled_duration_ = scaled_duration;
  }

  // AnimationCurve implementation
  base::TimeDelta Duration() const override;
  std::unique_ptr<AnimationCurve> Clone() const override;
  base::TimeDelta TickInterval() const override;

  // FloatAnimationCurve implementation
  float GetValue(base::TimeDelta t) const override;

  std::unique_ptr<AnimationCurve> Retarget(base::TimeDelta t, float new_target);

  using Keyframes = std::vector<std::unique_ptr<FloatKeyframe>>;
  const Keyframes& keyframes_for_testing() const { return keyframes_; }

 private:
  KeyframedFloatAnimationCurve();

  // Always sorted in order of increasing time. No two keyframes have the
  // same time.
  Keyframes keyframes_;
  std::unique_ptr<TimingFunction> timing_function_;
  double scaled_duration_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT KeyframedTransformAnimationCurve
    : public TransformAnimationCurve {
 public:
  // It is required that the keyframes be sorted by time.
  static std::unique_ptr<KeyframedTransformAnimationCurve> Create();

  KeyframedTransformAnimationCurve(const KeyframedTransformAnimationCurve&) =
      delete;
  ~KeyframedTransformAnimationCurve() override;

  KeyframedTransformAnimationCurve& operator=(
      const KeyframedTransformAnimationCurve&) = delete;

  void AddKeyframe(std::unique_ptr<TransformKeyframe> keyframe);
  void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) {
    timing_function_ = std::move(timing_function);
  }
  double scaled_duration() const { return scaled_duration_; }
  void set_scaled_duration(double scaled_duration) {
    scaled_duration_ = scaled_duration;
  }

  // AnimationCurve implementation
  base::TimeDelta Duration() const override;
  std::unique_ptr<AnimationCurve> Clone() const override;
  base::TimeDelta TickInterval() const override;

  // TransformAnimationCurve implementation
  gfx::TransformOperations GetValue(base::TimeDelta t) const override;
  bool PreservesAxisAlignment() const override;
  bool MaximumScale(float* max_scale) const override;

  std::unique_ptr<AnimationCurve> Retarget(
      base::TimeDelta t,
      const gfx::TransformOperations& new_target);

 private:
  KeyframedTransformAnimationCurve();

  // Always sorted in order of increasing time. No two keyframes have the
  // same time.
  std::vector<std::unique_ptr<TransformKeyframe>> keyframes_;
  std::unique_ptr<TimingFunction> timing_function_;
  double scaled_duration_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT KeyframedSizeAnimationCurve
    : public SizeAnimationCurve {
 public:
  // It is required that the keyframes be sorted by time.
  static std::unique_ptr<KeyframedSizeAnimationCurve> Create();

  KeyframedSizeAnimationCurve(const KeyframedSizeAnimationCurve&) = delete;
  ~KeyframedSizeAnimationCurve() override;

  KeyframedSizeAnimationCurve& operator=(const KeyframedSizeAnimationCurve&) =
      delete;

  void AddKeyframe(std::unique_ptr<SizeKeyframe> keyframe);
  void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) {
    timing_function_ = std::move(timing_function);
  }
  double scaled_duration() const { return scaled_duration_; }
  void set_scaled_duration(double scaled_duration) {
    scaled_duration_ = scaled_duration;
  }

  // AnimationCurve implementation
  base::TimeDelta Duration() const override;
  std::unique_ptr<AnimationCurve> Clone() const override;
  base::TimeDelta TickInterval() const override;

  // SizeAnimationCurve implementation
  gfx::SizeF GetValue(base::TimeDelta t) const override;

  std::unique_ptr<AnimationCurve> Retarget(base::TimeDelta t,
                                           const gfx::SizeF& new_target);

 private:
  KeyframedSizeAnimationCurve();

  // Always sorted in order of increasing time. No two keyframes have the
  // same time.
  std::vector<std::unique_ptr<SizeKeyframe>> keyframes_;
  std::unique_ptr<TimingFunction> timing_function_;
  double scaled_duration_;
};

class GFX_KEYFRAME_ANIMATION_EXPORT KeyframedRectAnimationCurve
    : public RectAnimationCurve {
 public:
  // It is required that the keyframes be sorted by time.
  static std::unique_ptr<KeyframedRectAnimationCurve> Create();

  KeyframedRectAnimationCurve(const KeyframedRectAnimationCurve&) = delete;
  ~KeyframedRectAnimationCurve() override;

  KeyframedRectAnimationCurve& operator=(const KeyframedRectAnimationCurve&) =
      delete;

  void AddKeyframe(std::unique_ptr<RectKeyframe> keyframe);
  void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) {
    timing_function_ = std::move(timing_function);
  }
  double scaled_duration() const { return scaled_duration_; }
  void set_scaled_duration(double scaled_duration) {
    scaled_duration_ = scaled_duration;
  }

  // AnimationCurve implementation
  base::TimeDelta Duration() const override;
  std::unique_ptr<AnimationCurve> Clone() const override;
  base::TimeDelta TickInterval() const override;

  // RectAnimationCurve implementation
  gfx::Rect GetValue(base::TimeDelta t) const override;

  std::unique_ptr<AnimationCurve> Retarget(base::TimeDelta t,
                                           const gfx::Rect& new_target);

 private:
  KeyframedRectAnimationCurve();

  // Always sorted in order of increasing time. No two keyframes have the
  // same time.
  std::vector<std::unique_ptr<RectKeyframe>> keyframes_;
  std::unique_ptr<TimingFunction> timing_function_;
  double scaled_duration_ = 0.;
};

template <typename T>
struct AnimationTraits {};

#define DEFINE_ANIMATION_TRAITS(value_type, name)                           \
  template <>                                                               \
  struct AnimationTraits<value_type> {                                      \
    typedef value_type ValueType;                                           \
    typedef name##AnimationCurve::Target TargetType;                        \
    typedef name##AnimationCurve CurveType;                                 \
    typedef Keyframed##name##AnimationCurve KeyframedCurveType;             \
    typedef name##Keyframe KeyframeType;                                    \
    static const CurveType* ToDerivedCurve(const AnimationCurve* curve) {   \
      return name##AnimationCurve::To##name##AnimationCurve(curve);         \
    }                                                                       \
    static CurveType* ToDerivedCurve(AnimationCurve* curve) {               \
      return name##AnimationCurve::To##name##AnimationCurve(curve);         \
    }                                                                       \
    static const KeyframedCurveType* ToKeyframedCurve(                      \
        const AnimationCurve* curve) {                                      \
      return static_cast<const KeyframedCurveType*>(ToDerivedCurve(curve)); \
    }                                                                       \
    static KeyframedCurveType* ToKeyframedCurve(AnimationCurve* curve) {    \
      return static_cast<KeyframedCurveType*>(ToDerivedCurve(curve));       \
    }                                                                       \
    static void OnValueAnimated(name##AnimationCurve::Target* target,       \
                                const ValueType& target_value,              \
                                int target_property) {                      \
      target->On##name##Animated(target_value, target_property, nullptr);   \
    }                                                                       \
  }

DEFINE_ANIMATION_TRAITS(float, Float);
DEFINE_ANIMATION_TRAITS(TransformOperations, Transform);
DEFINE_ANIMATION_TRAITS(SizeF, Size);
DEFINE_ANIMATION_TRAITS(SkColor, Color);
DEFINE_ANIMATION_TRAITS(Rect, Rect);

#undef DEFINE_ANIMATION_TRAITS

bool SufficientlyEqual(float lhs, float rhs);
bool SufficientlyEqual(const TransformOperations& lhs,
                       const TransformOperations& rhs);
bool SufficientlyEqual(const SizeF& lhs, const SizeF& rhs);
bool SufficientlyEqual(SkColor lhs, SkColor rhs);
bool SufficientlyEqual(const Rect& lhs, const Rect& rhs);

}  // namespace gfx

#endif  // UI_GFX_ANIMATION_KEYFRAME_KEYFRAMED_ANIMATION_CURVE_H_
