// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/animation/keyframe/keyframe_effect.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/animation/keyframe/animation_curve.h"
#include "ui/gfx/animation/keyframe/keyframed_animation_curve.h"
#include "ui/gfx/animation/keyframe/test/animation_utils.h"
#include "ui/gfx/geometry/test/geometry_util.h"

namespace gfx {

static constexpr float kNoise = 1e-6f;
static constexpr float kEpsilon = 1e-5f;

// Tests client-specific property ids.
static constexpr int kLayoutOffsetPropertyId = 19;
static constexpr int kBackgroundColorPropertyId = 20;
static constexpr int kOpacityPropertyId = 21;
static constexpr int kBoundsPropertyId = 22;
static constexpr int kTransformPropertyId = 23;
static constexpr int kRectPropertyId = 24;

class TestAnimationTarget : public SizeAnimationCurve::Target,
                            public TransformAnimationCurve::Target,
                            public FloatAnimationCurve::Target,
                            public ColorAnimationCurve::Target,
                            public RectAnimationCurve::Target {
 public:
  TestAnimationTarget() {
    layout_offset_.AppendTranslate(0, 0, 0);
    operations_.AppendTranslate(0, 0, 0);
    operations_.AppendRotate(1, 0, 0, 0);
    operations_.AppendScale(1, 1, 1);
  }

  const SizeF& size() const { return size_; }
  const TransformOperations& operations() const { return operations_; }
  const TransformOperations& layout_offset() const { return layout_offset_; }
  float opacity() const { return opacity_; }
  SkColor background_color() const { return background_color_; }
  Rect rect() const { return rect_; }

  void OnSizeAnimated(const SizeF& size,
                      int target_property_id,
                      KeyframeModel* keyframe_model) override {
    size_ = size;
  }

  void OnTransformAnimated(const TransformOperations& operations,
                           int target_property_id,
                           KeyframeModel* keyframe_model) override {
    if (target_property_id == kLayoutOffsetPropertyId) {
      layout_offset_ = operations;
    } else {
      operations_ = operations;
    }
  }

  void OnFloatAnimated(const float& opacity,
                       int target_property_id,
                       KeyframeModel* keyframe_model) override {
    opacity_ = opacity;
  }

  void OnColorAnimated(const SkColor& color,
                       int target_property_id,
                       KeyframeModel* keyframe_model) override {
    background_color_ = color;
  }

  void OnRectAnimated(const Rect& rect,
                      int target_property_id,
                      KeyframeModel* keyframe_model) override {
    rect_ = rect;
  }

 private:
  TransformOperations layout_offset_;
  TransformOperations operations_;
  SizeF size_ = {10.0f, 10.0f};
  float opacity_ = 1.0f;
  SkColor background_color_ = SK_ColorRED;
  Rect rect_;
};

TEST(KeyframeAnimationTest, AddRemoveKeyframeModels) {
  KeyframeEffect animator;
  EXPECT_TRUE(animator.keyframe_models().empty());
  TestAnimationTarget target;

  animator.AddKeyframeModel(CreateSizeAnimation(&target, 1, kBoundsPropertyId,
                                                SizeF(10, 100), SizeF(20, 200),
                                                MicrosecondsToDelta(10000)));
  EXPECT_EQ(1ul, animator.keyframe_models().size());
  EXPECT_EQ(kBoundsPropertyId, animator.keyframe_models()[0]->TargetProperty());

  TransformOperations from_operations;
  from_operations.AppendTranslate(10, 100, 1000);
  TransformOperations to_operations;
  to_operations.AppendTranslate(20, 200, 2000);
  animator.AddKeyframeModel(CreateTransformAnimation(
      &target, 2, kTransformPropertyId, from_operations, to_operations,
      MicrosecondsToDelta(10000)));

  EXPECT_EQ(2ul, animator.keyframe_models().size());
  EXPECT_EQ(kTransformPropertyId,
            animator.keyframe_models()[1]->TargetProperty());

  animator.AddKeyframeModel(CreateTransformAnimation(
      &target, 3, kTransformPropertyId, from_operations, to_operations,
      MicrosecondsToDelta(10000)));
  EXPECT_EQ(3ul, animator.keyframe_models().size());
  EXPECT_EQ(kTransformPropertyId,
            animator.keyframe_models()[2]->TargetProperty());

  animator.RemoveKeyframeModels(kTransformPropertyId);
  EXPECT_EQ(1ul, animator.keyframe_models().size());
  EXPECT_EQ(kBoundsPropertyId, animator.keyframe_models()[0]->TargetProperty());

  animator.RemoveKeyframeModel(animator.keyframe_models()[0]->id());
  EXPECT_TRUE(animator.keyframe_models().empty());
}

TEST(KeyframeAnimationTest, AnimationLifecycle) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  animator.AddKeyframeModel(CreateSizeAnimation(&target, 1, kBoundsPropertyId,
                                                SizeF(10, 100), SizeF(20, 200),
                                                MicrosecondsToDelta(10000)));
  EXPECT_EQ(1ul, animator.keyframe_models().size());
  EXPECT_EQ(kBoundsPropertyId, animator.keyframe_models()[0]->TargetProperty());
  EXPECT_EQ(KeyframeModel::WAITING_FOR_TARGET_AVAILABILITY,
            animator.keyframe_models()[0]->run_state());

  base::TimeTicks start_time = MicrosecondsToTicks(1);
  animator.Tick(start_time);
  EXPECT_EQ(KeyframeModel::RUNNING, animator.keyframe_models()[0]->run_state());

  EXPECT_SIZEF_EQ(SizeF(10, 100), target.size());

  // Tick beyond the animation
  animator.Tick(start_time + MicrosecondsToDelta(20000));

  EXPECT_TRUE(animator.keyframe_models().empty());

  // Should have assumed the final value.
  EXPECT_SIZEF_EQ(SizeF(20, 200), target.size());
}

TEST(KeyframeAnimationTest, AnimationQueue) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  animator.AddKeyframeModel(CreateSizeAnimation(&target, 1, kBoundsPropertyId,
                                                SizeF(10, 100), SizeF(20, 200),
                                                MicrosecondsToDelta(10000)));
  EXPECT_EQ(1ul, animator.keyframe_models().size());
  EXPECT_EQ(kBoundsPropertyId, animator.keyframe_models()[0]->TargetProperty());
  EXPECT_EQ(KeyframeModel::WAITING_FOR_TARGET_AVAILABILITY,
            animator.keyframe_models()[0]->run_state());

  base::TimeTicks start_time = MicrosecondsToTicks(1);
  animator.Tick(start_time);
  EXPECT_EQ(KeyframeModel::RUNNING, animator.keyframe_models()[0]->run_state());
  EXPECT_SIZEF_EQ(SizeF(10, 100), target.size());

  animator.AddKeyframeModel(CreateSizeAnimation(&target, 2, kBoundsPropertyId,
                                                SizeF(10, 100), SizeF(20, 200),
                                                MicrosecondsToDelta(10000)));

  TransformOperations from_operations;
  from_operations.AppendTranslate(10, 100, 1000);
  TransformOperations to_operations;
  to_operations.AppendTranslate(20, 200, 2000);
  animator.AddKeyframeModel(CreateTransformAnimation(
      &target, 3, kTransformPropertyId, from_operations, to_operations,
      MicrosecondsToDelta(10000)));

  EXPECT_EQ(3ul, animator.keyframe_models().size());
  EXPECT_EQ(kBoundsPropertyId, animator.keyframe_models()[1]->TargetProperty());
  EXPECT_EQ(kTransformPropertyId,
            animator.keyframe_models()[2]->TargetProperty());
  int id1 = animator.keyframe_models()[1]->id();

  animator.Tick(start_time + MicrosecondsToDelta(1));

  // Only the transform animation should have started (since there's no
  // conflicting animation).
  EXPECT_EQ(KeyframeModel::WAITING_FOR_TARGET_AVAILABILITY,
            animator.keyframe_models()[1]->run_state());
  EXPECT_EQ(KeyframeModel::RUNNING, animator.keyframe_models()[2]->run_state());

  // Tick beyond the first animator. This should cause it (and the transform
  // animation) to get removed and for the second bounds animation to start.
  animator.Tick(start_time + MicrosecondsToDelta(15000));

  EXPECT_EQ(1ul, animator.keyframe_models().size());
  EXPECT_EQ(KeyframeModel::RUNNING, animator.keyframe_models()[0]->run_state());
  EXPECT_EQ(id1, animator.keyframe_models()[0]->id());

  // Tick beyond all animations. There should be none remaining.
  animator.Tick(start_time + MicrosecondsToDelta(30000));
  EXPECT_TRUE(animator.keyframe_models().empty());
}

TEST(KeyframeAnimationTest, FinishedTransition) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kOpacityPropertyId};
  transition.duration = MsToDelta(10);
  animator.set_transition(transition);

  base::TimeTicks start_time = MsToTicks(1000);
  animator.Tick(start_time);

  float from = 1.0f;
  float to = 0.0f;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from, to);

  animator.Tick(start_time);
  EXPECT_EQ(from, target.opacity());

  // We now simulate a long pause where the element hasn't been ticked (eg, it
  // may have been hidden). If this happens, the unticked transition must still
  // be treated as having finished.
  animator.TransitionFloatTo(&target, start_time + MsToDelta(1000),
                             kOpacityPropertyId, target.opacity(), 1.0f);

  animator.Tick(start_time + MsToDelta(1000));
  EXPECT_EQ(to, target.opacity());
}

TEST(KeyframeAnimationTest, OpacityTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kOpacityPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  float from = 1.0f;
  float to = 0.5f;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from, to);

  EXPECT_EQ(from, target.opacity());
  animator.Tick(start_time);

  // Scheduling a redundant, approximately equal transition should be ignored.
  int keyframe_model_id = animator.keyframe_models().front()->id();
  float nearby = to + kNoise;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from,
                             nearby);
  EXPECT_EQ(keyframe_model_id, animator.keyframe_models().front()->id());

  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_GT(from, target.opacity());
  EXPECT_LT(to, target.opacity());

  animator.Tick(start_time + MicrosecondsToDelta(10000));
  EXPECT_EQ(to, target.opacity());
}

TEST(KeyframeAnimationTest, ReversedOpacityTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kOpacityPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  float from = 1.0f;
  float to = 0.5f;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from, to);

  EXPECT_EQ(from, target.opacity());
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(1000));
  float value_before_reversing = target.opacity();
  EXPECT_GT(from, value_before_reversing);
  EXPECT_LT(to, value_before_reversing);

  animator.TransitionFloatTo(&target, start_time + MicrosecondsToDelta(1000),
                             kOpacityPropertyId, target.opacity(), from);
  animator.Tick(start_time + MicrosecondsToDelta(1000));
  EXPECT_FLOAT_EQ(value_before_reversing, target.opacity());

  animator.Tick(start_time + MicrosecondsToDelta(2000));
  EXPECT_EQ(from, target.opacity());
}

TEST(KeyframeAnimationTest, RetargetOpacityTransition) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  std::unique_ptr<KeyframedFloatAnimationCurve> curve(
      gfx::KeyframedFloatAnimationCurve::Create());
  curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 1.0f, nullptr));
  curve->AddKeyframe(
      FloatKeyframe::Create(MicrosecondsToDelta(10000), 0.0f, nullptr));
  curve->set_target(&target);
  animator.AddKeyframeModel(KeyframeModel::Create(
      std::move(curve), KeyframeEffect::GetNextKeyframeModelId(),
      kOpacityPropertyId));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);
  EXPECT_EQ(1.f, target.opacity());
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_FLOAT_EQ(0.5f, target.opacity());

  animator.GetKeyframeModel(kOpacityPropertyId)
      ->Retarget(start_time + MicrosecondsToDelta(5000), kOpacityPropertyId,
                 1.f);
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_FLOAT_EQ(0.5f, target.opacity());

  animator.Tick(start_time + MicrosecondsToDelta(7500));
  EXPECT_FLOAT_EQ(0.75f, target.opacity());
}

TEST(KeyframeAnimationTest, RetargetTransitionBeforeLastKeyframe) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  std::unique_ptr<KeyframedFloatAnimationCurve> curve(
      gfx::KeyframedFloatAnimationCurve::Create());
  curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 1.0f, nullptr));
  curve->AddKeyframe(
      FloatKeyframe::Create(MicrosecondsToDelta(5000), 0.5f, nullptr));
  curve->AddKeyframe(
      FloatKeyframe::Create(MicrosecondsToDelta(10000), 0.0f, nullptr));
  curve->set_target(&target);
  animator.AddKeyframeModel(KeyframeModel::Create(
      std::move(curve), KeyframeEffect::GetNextKeyframeModelId(),
      kOpacityPropertyId));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);
  EXPECT_EQ(1.f, target.opacity());

  animator.GetKeyframeModel(kOpacityPropertyId)
      ->Retarget(start_time + MicrosecondsToDelta(4000), kOpacityPropertyId,
                 0.1f);
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_FLOAT_EQ(0.5f, target.opacity());

  animator.Tick(start_time + MicrosecondsToDelta(7500));
  EXPECT_FLOAT_EQ(0.3f, target.opacity());
}

TEST(KeyframeAnimationTest, LayoutOffsetTransitions) {
  // In this test, we do expect exact equality.
  float tolerance = 0.0f;
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kLayoutOffsetPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  TransformOperations from = target.layout_offset();

  TransformOperations to;
  to.AppendTranslate(8, 0, 0);

  animator.TransitionTransformOperationsTo(&target, start_time,
                                           kLayoutOffsetPropertyId, from, to);

  EXPECT_TRUE(from.ApproximatelyEqual(target.layout_offset(), tolerance));
  animator.Tick(start_time);

  // Scheduling a redundant, approximately equal transition should be ignored.
  int keyframe_model_id = animator.keyframe_models().front()->id();
  TransformOperations nearby = to;
  nearby.at(0).translate.x += kNoise;
  animator.TransitionTransformOperationsTo(
      &target, start_time, kLayoutOffsetPropertyId, from, nearby);
  EXPECT_EQ(keyframe_model_id, animator.keyframe_models().front()->id());

  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_LT(from.at(0).translate.x, target.layout_offset().at(0).translate.x);
  EXPECT_GT(to.at(0).translate.x, target.layout_offset().at(0).translate.x);

  animator.Tick(start_time + MicrosecondsToDelta(10000));
  EXPECT_TRUE(to.ApproximatelyEqual(target.layout_offset(), tolerance));
}

TEST(KeyframeAnimationTest, TransformTransitions) {
  // In this test, we do expect exact equality.
  float tolerance = 0.0f;
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kTransformPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  TransformOperations from = target.operations();

  TransformOperations to;
  to.AppendTranslate(8, 0, 0);
  to.AppendRotate(1, 0, 0, 0);
  to.AppendScale(1, 1, 1);

  animator.TransitionTransformOperationsTo(&target, start_time,
                                           kTransformPropertyId, from, to);

  EXPECT_TRUE(from.ApproximatelyEqual(target.operations(), tolerance));
  animator.Tick(start_time);

  // Scheduling a redundant, approximately equal transition should be ignored.
  int keyframe_model_id = animator.keyframe_models().front()->id();
  TransformOperations nearby = to;
  nearby.at(0).translate.x += kNoise;
  animator.TransitionTransformOperationsTo(&target, start_time,
                                           kTransformPropertyId, from, nearby);
  EXPECT_EQ(keyframe_model_id, animator.keyframe_models().front()->id());

  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_LT(from.at(0).translate.x, target.operations().at(0).translate.x);
  EXPECT_GT(to.at(0).translate.x, target.operations().at(0).translate.x);

  animator.Tick(start_time + MicrosecondsToDelta(10000));
  EXPECT_TRUE(to.ApproximatelyEqual(target.operations(), tolerance));
}

TEST(KeyframeAnimationTest, ReversedTransformTransitions) {
  // In this test, we do expect exact equality.
  float tolerance = 0.0f;
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kTransformPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  TransformOperations from = target.operations();

  TransformOperations to;
  to.AppendTranslate(8, 0, 0);
  to.AppendRotate(1, 0, 0, 0);
  to.AppendScale(1, 1, 1);

  animator.TransitionTransformOperationsTo(&target, start_time,
                                           kTransformPropertyId, from, to);

  EXPECT_TRUE(from.ApproximatelyEqual(target.operations(), tolerance));
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(1000));
  TransformOperations value_before_reversing = target.operations();
  EXPECT_LT(from.at(0).translate.x, target.operations().at(0).translate.x);
  EXPECT_GT(to.at(0).translate.x, target.operations().at(0).translate.x);

  animator.TransitionTransformOperationsTo(
      &target, start_time + MicrosecondsToDelta(1000), kTransformPropertyId,
      target.operations(), from);
  animator.Tick(start_time + MicrosecondsToDelta(1000));
  EXPECT_TRUE(value_before_reversing.ApproximatelyEqual(target.operations(),
                                                        tolerance));

  animator.Tick(start_time + MicrosecondsToDelta(2000));
  EXPECT_TRUE(from.ApproximatelyEqual(target.operations(), tolerance));
}

TEST(KeyframeAnimationTest, RetargetTransformTransition) {
  float tolerance = 0.0f;
  TestAnimationTarget target;
  KeyframeEffect animator;

  TransformOperations from;
  from.AppendScale(1, 1, 1);
  from.AppendTranslate(0, 0, 0);
  TransformOperations to;
  to.AppendScale(11, 11, 11);
  to.AppendTranslate(-10, -10, -10);

  std::unique_ptr<KeyframedTransformAnimationCurve> curve(
      gfx::KeyframedTransformAnimationCurve::Create());
  curve->AddKeyframe(
      TransformKeyframe::Create(base::TimeDelta(), from, nullptr));
  curve->AddKeyframe(
      TransformKeyframe::Create(MicrosecondsToDelta(10000), to, nullptr));
  curve->set_target(&target);
  animator.AddKeyframeModel(KeyframeModel::Create(
      std::move(curve), KeyframeEffect::GetNextKeyframeModelId(),
      kTransformPropertyId));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);
  EXPECT_TRUE(from.ApproximatelyEqual(target.operations(), tolerance));
  animator.Tick(start_time + MicrosecondsToDelta(5000));

  EXPECT_FLOAT_EQ(6.f, target.operations().at(0).scale.x);
  EXPECT_FLOAT_EQ(-5.f, target.operations().at(1).translate.x);

  TransformOperations new_to;
  new_to.AppendScale(110, 110, 110);
  new_to.AppendTranslate(-101, -101, -101);

  animator.GetKeyframeModel(kTransformPropertyId)
      ->Retarget(start_time + MicrosecondsToDelta(5000), kTransformPropertyId,
                 new_to);
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_FLOAT_EQ(6.f, target.operations().at(0).scale.x);
  EXPECT_FLOAT_EQ(-5.f, target.operations().at(1).translate.x);

  animator.Tick(start_time + MicrosecondsToDelta(7500));
  EXPECT_FLOAT_EQ(58.f, target.operations().at(0).scale.x);
  EXPECT_FLOAT_EQ(-53.f, target.operations().at(1).translate.x);
}

TEST(KeyframeAnimationTest, BoundsTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kBoundsPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  SizeF from = target.size();
  SizeF to(20.0f, 20.0f);

  animator.TransitionSizeTo(&target, start_time, kBoundsPropertyId, from, to);

  EXPECT_SIZEF_EQ(from, target.size());
  animator.Tick(start_time);

  // Scheduling a redundant, approximately equal transition should be ignored.
  int keyframe_model_id = animator.keyframe_models().front()->id();
  SizeF nearby = to;
  nearby.set_width(to.width() + kNoise);
  animator.TransitionSizeTo(&target, start_time, kBoundsPropertyId, from,
                            nearby);
  EXPECT_EQ(keyframe_model_id, animator.keyframe_models().front()->id());

  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_LT(from.width(), target.size().width());
  EXPECT_GT(to.width(), target.size().width());
  EXPECT_LT(from.height(), target.size().height());
  EXPECT_GT(to.height(), target.size().height());

  animator.Tick(start_time + MicrosecondsToDelta(10000));
  EXPECT_SIZEF_EQ(to, target.size());
}

TEST(KeyframeAnimationTest, RetargetSizeTransition) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  SizeF from(1, 2);
  SizeF to(11, 22);

  std::unique_ptr<KeyframedSizeAnimationCurve> curve(
      gfx::KeyframedSizeAnimationCurve::Create());
  curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), from, nullptr));
  curve->AddKeyframe(
      SizeKeyframe::Create(MicrosecondsToDelta(10000), to, nullptr));
  curve->set_target(&target);
  animator.AddKeyframeModel(KeyframeModel::Create(
      std::move(curve), KeyframeEffect::GetNextKeyframeModelId(),
      kBoundsPropertyId));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);
  EXPECT_EQ(from, target.size());
  animator.Tick(start_time + MicrosecondsToDelta(5000));

  EXPECT_SIZEF_EQ(SizeF(6, 12), target.size());

  SizeF new_to(600, 1200);

  animator.GetKeyframeModel(kBoundsPropertyId)
      ->Retarget(start_time + MicrosecondsToDelta(5000), kRectPropertyId,
                 new_to);
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_SIZEF_EQ(SizeF(6, 12), target.size());

  animator.Tick(start_time + MicrosecondsToDelta(7500));
  EXPECT_SIZEF_EQ(SizeF(303, 606), target.size());
}

TEST(KeyframeAnimationTest, ReversedBoundsTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kBoundsPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  SizeF from = target.size();
  SizeF to(20.0f, 20.0f);

  animator.TransitionSizeTo(&target, start_time, kBoundsPropertyId, from, to);

  EXPECT_SIZEF_EQ(from, target.size());
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(1000));
  SizeF value_before_reversing = target.size();
  EXPECT_LT(from.width(), target.size().width());
  EXPECT_GT(to.width(), target.size().width());
  EXPECT_LT(from.height(), target.size().height());
  EXPECT_GT(to.height(), target.size().height());

  animator.TransitionSizeTo(&target, start_time + MicrosecondsToDelta(1000),
                            kBoundsPropertyId, target.size(), from);
  animator.Tick(start_time + MicrosecondsToDelta(1000));
  EXPECT_SIZEF_EQ(value_before_reversing, target.size());

  animator.Tick(start_time + MicrosecondsToDelta(2000));
  EXPECT_SIZEF_EQ(from, target.size());
}

TEST(KeyframeAnimationTest, BackgroundColorTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kBackgroundColorPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  SkColor from = SK_ColorRED;
  SkColor to = SK_ColorGREEN;

  animator.TransitionColorTo(&target, start_time, kBackgroundColorPropertyId,
                             from, to);

  EXPECT_EQ(from, target.background_color());
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_GT(SkColorGetR(from), SkColorGetR(target.background_color()));
  EXPECT_LT(SkColorGetR(to), SkColorGetR(target.background_color()));
  EXPECT_LT(SkColorGetG(from), SkColorGetG(target.background_color()));
  EXPECT_GT(SkColorGetG(to), SkColorGetG(target.background_color()));
  EXPECT_EQ(0u, SkColorGetB(target.background_color()));
  EXPECT_EQ(255u, SkColorGetA(target.background_color()));

  animator.Tick(start_time + MicrosecondsToDelta(10000));
  EXPECT_EQ(to, target.background_color());
}

TEST(KeyframeAnimationTest, ReversedBackgroundColorTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kBackgroundColorPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);
  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  SkColor from = SK_ColorRED;
  SkColor to = SK_ColorGREEN;

  animator.TransitionColorTo(&target, start_time, kBackgroundColorPropertyId,
                             from, to);

  EXPECT_EQ(from, target.background_color());
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(1000));
  SkColor value_before_reversing = target.background_color();
  EXPECT_GT(SkColorGetR(from), SkColorGetR(target.background_color()));
  EXPECT_LT(SkColorGetR(to), SkColorGetR(target.background_color()));
  EXPECT_LT(SkColorGetG(from), SkColorGetG(target.background_color()));
  EXPECT_GT(SkColorGetG(to), SkColorGetG(target.background_color()));
  EXPECT_EQ(0u, SkColorGetB(target.background_color()));
  EXPECT_EQ(255u, SkColorGetA(target.background_color()));

  animator.TransitionColorTo(&target, start_time + MicrosecondsToDelta(1000),
                             kBackgroundColorPropertyId,
                             target.background_color(), from);
  animator.Tick(start_time + MicrosecondsToDelta(1000));
  EXPECT_EQ(value_before_reversing, target.background_color());

  animator.Tick(start_time + MicrosecondsToDelta(2000));
  EXPECT_EQ(from, target.background_color());
}

TEST(KeyframeAnimationTest, RetargetColorTransition) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  SkColor from = SkColorSetRGB(0, 0, 0);
  SkColor to = SkColorSetRGB(10, 10, 10);

  std::unique_ptr<KeyframedColorAnimationCurve> curve(
      gfx::KeyframedColorAnimationCurve::Create());
  curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta(), from, nullptr));
  curve->AddKeyframe(
      ColorKeyframe::Create(MicrosecondsToDelta(10000), to, nullptr));
  curve->set_target(&target);
  animator.AddKeyframeModel(KeyframeModel::Create(
      std::move(curve), KeyframeEffect::GetNextKeyframeModelId(),
      kBackgroundColorPropertyId));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);
  EXPECT_EQ(from, target.background_color());
  animator.Tick(start_time + MicrosecondsToDelta(5000));

  EXPECT_EQ(5u, SkColorGetR(target.background_color()));

  SkColor new_to = SkColorSetRGB(101, 101, 101);

  animator.GetKeyframeModel(kBackgroundColorPropertyId)
      ->Retarget(start_time + MicrosecondsToDelta(5000), kRectPropertyId,
                 new_to);
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_EQ(5u, SkColorGetR(target.background_color()));

  animator.Tick(start_time + MicrosecondsToDelta(7500));
  EXPECT_EQ(53u, SkColorGetR(target.background_color()));
}

TEST(KeyframeAnimationTest, DoubleReversedTransitions) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kOpacityPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  float from = 1.0f;
  float to = 0.5f;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from, to);

  EXPECT_EQ(from, target.opacity());
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(1000));
  float value_before_reversing = target.opacity();
  EXPECT_GT(from, value_before_reversing);
  EXPECT_LT(to, value_before_reversing);

  animator.TransitionFloatTo(&target, start_time + MicrosecondsToDelta(1000),
                             kOpacityPropertyId, target.opacity(), from);
  animator.Tick(start_time + MicrosecondsToDelta(1000));
  EXPECT_FLOAT_EQ(value_before_reversing, target.opacity());

  animator.Tick(start_time + MicrosecondsToDelta(1500));
  value_before_reversing = target.opacity();
  // If the code for reversing transitions does not account for an existing time
  // offset, then reversing a second time will give incorrect values.
  animator.TransitionFloatTo(&target, start_time + MicrosecondsToDelta(1500),
                             kOpacityPropertyId, target.opacity(), to);
  animator.Tick(start_time + MicrosecondsToDelta(1500));
  EXPECT_FLOAT_EQ(value_before_reversing, target.opacity());
}

TEST(KeyframeAnimationTest, RedundantTransition) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kOpacityPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  float from = 1.0f;
  float to = 0.5f;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from, to);

  EXPECT_EQ(from, target.opacity());
  animator.Tick(start_time);

  animator.Tick(start_time + MicrosecondsToDelta(1000));
  float value_before_redundant_transition = target.opacity();

  // While an existing transition is in progress to the same value, we should
  // not start a new transition.
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId,
                             target.opacity(), to);

  EXPECT_EQ(1lu, animator.keyframe_models().size());
  EXPECT_EQ(value_before_redundant_transition, target.opacity());
}

TEST(KeyframeAnimationTest, TransitionToSameValue) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  Transition transition;
  transition.target_properties = {kOpacityPropertyId};
  transition.duration = MicrosecondsToDelta(10000);
  animator.set_transition(transition);

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  // Transitioning to the same value should be a no-op.
  float from = 1.0f;
  float to = 1.0f;
  animator.TransitionFloatTo(&target, start_time, kOpacityPropertyId, from, to);
  EXPECT_EQ(from, target.opacity());
  EXPECT_TRUE(animator.keyframe_models().empty());
}

TEST(KeyframeAnimationTest, CorrectTargetValue) {
  TestAnimationTarget target;
  KeyframeEffect animator;
  base::TimeDelta duration = MicrosecondsToDelta(10000);

  float from_opacity = 1.0f;
  float to_opacity = 0.5f;
  SizeF from_bounds = SizeF(10, 200);
  SizeF to_bounds = SizeF(20, 200);
  SkColor from_color = SK_ColorRED;
  SkColor to_color = SK_ColorGREEN;
  TransformOperations from_transform;
  from_transform.AppendTranslate(10, 100, 1000);
  TransformOperations to_transform;
  to_transform.AppendTranslate(20, 200, 2000);

  // Verify the default value is returned if there's no running animations.
  EXPECT_EQ(from_opacity,
            animator.GetTargetFloatValue(kOpacityPropertyId, from_opacity));
  EXPECT_SIZEF_EQ(from_bounds,
                  animator.GetTargetSizeValue(kBoundsPropertyId, from_bounds));
  EXPECT_EQ(from_color, animator.GetTargetColorValue(kBackgroundColorPropertyId,
                                                     from_color));
  EXPECT_TRUE(from_transform.ApproximatelyEqual(
      animator.GetTargetTransformOperationsValue(kTransformPropertyId,
                                                 from_transform),
      kEpsilon));

  // Add keyframe_models.
  animator.AddKeyframeModel(CreateFloatAnimation(
      &target, 2, kOpacityPropertyId, from_opacity, to_opacity, duration));
  animator.AddKeyframeModel(CreateSizeAnimation(
      &target, 1, kBoundsPropertyId, from_bounds, to_bounds, duration));
  animator.AddKeyframeModel(CreateColorAnimation(
      &target, 3, kBackgroundColorPropertyId, from_color, to_color, duration));
  animator.AddKeyframeModel(
      CreateTransformAnimation(&target, 4, kTransformPropertyId, from_transform,
                               to_transform, duration));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);

  // Verify target value.
  EXPECT_EQ(to_opacity,
            animator.GetTargetFloatValue(kOpacityPropertyId, from_opacity));
  EXPECT_SIZEF_EQ(to_bounds,
                  animator.GetTargetSizeValue(kBoundsPropertyId, from_bounds));
  EXPECT_EQ(to_color, animator.GetTargetColorValue(kBackgroundColorPropertyId,
                                                   from_color));
  EXPECT_TRUE(to_transform.ApproximatelyEqual(
      animator.GetTargetTransformOperationsValue(kTransformPropertyId,
                                                 from_transform),
      kEpsilon));
}

TEST(KeyframeAnimationTest, RetargetRectTransition) {
  TestAnimationTarget target;
  KeyframeEffect animator;

  Rect from(1, 2, 3, 4);
  Rect to(11, 22, 33, 44);

  std::unique_ptr<KeyframedRectAnimationCurve> curve(
      gfx::KeyframedRectAnimationCurve::Create());
  curve->AddKeyframe(RectKeyframe::Create(base::TimeDelta(), from, nullptr));
  curve->AddKeyframe(
      RectKeyframe::Create(MicrosecondsToDelta(10000), to, nullptr));
  curve->set_target(&target);
  animator.AddKeyframeModel(KeyframeModel::Create(
      std::move(curve), KeyframeEffect::GetNextKeyframeModelId(),
      kRectPropertyId));

  base::TimeTicks start_time = MicrosecondsToTicks(1000000);
  animator.Tick(start_time);
  EXPECT_EQ(from, target.rect());
  animator.Tick(start_time + MicrosecondsToDelta(5000));

  EXPECT_EQ(Rect(6, 12, 18, 24), target.rect());

  Rect new_to(600, 1200, 1800, 2400);

  animator.GetKeyframeModel(kRectPropertyId)
      ->Retarget(start_time + MicrosecondsToDelta(5000), kRectPropertyId,
                 new_to);
  animator.Tick(start_time + MicrosecondsToDelta(5000));
  EXPECT_EQ(Rect(6, 12, 18, 24), target.rect());

  animator.Tick(start_time + MicrosecondsToDelta(7500));
  EXPECT_EQ(Rect(303, 606, 909, 1212), target.rect());
}

}  // namespace gfx
