// Copyright 2013 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.

#include "cc/animation/scroll_offset_animation_curve.h"

#include <algorithm>
#include <cmath>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "cc/animation/timing_function.h"
#include "cc/base/time_util.h"
#include "ui/gfx/animation/tween.h"

using DurationBehavior = cc::ScrollOffsetAnimationCurve::DurationBehavior;

const double kConstantDuration = 9.0;
const double kDurationDivisor = 60.0;

const double kInverseDeltaRampStartPx = 120.0;
const double kInverseDeltaRampEndPx = 480.0;
const double kInverseDeltaMinDuration = 6.0;
const double kInverseDeltaMaxDuration = 12.0;

const double kInverseDeltaSlope =
    (kInverseDeltaMinDuration - kInverseDeltaMaxDuration) /
    (kInverseDeltaRampEndPx - kInverseDeltaRampStartPx);

const double kInverseDeltaOffset =
    kInverseDeltaMaxDuration - kInverseDeltaRampStartPx * kInverseDeltaSlope;

namespace cc {

namespace {

const double kEpsilon = 0.01f;

static float MaximumDimension(const gfx::Vector2dF& delta) {
  return std::abs(delta.x()) > std::abs(delta.y()) ? delta.x() : delta.y();
}

static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity(
    double velocity) {
  // Clamp velocity to a sane value.
  velocity = std::min(std::max(velocity, -1000.0), 1000.0);

  // Based on CubicBezierTimingFunction::EaseType::EASE_IN_OUT preset
  // with first control point scaled.
  const double x1 = 0.42;
  const double y1 = velocity * x1;
  return CubicBezierTimingFunction::Create(x1, y1, 0.58, 1);
}

}  // namespace

std::unique_ptr<ScrollOffsetAnimationCurve> ScrollOffsetAnimationCurve::Create(
    const gfx::ScrollOffset& target_value,
    std::unique_ptr<TimingFunction> timing_function,
    DurationBehavior duration_behavior) {
  return base::WrapUnique(new ScrollOffsetAnimationCurve(
      target_value, std::move(timing_function), duration_behavior));
}

ScrollOffsetAnimationCurve::ScrollOffsetAnimationCurve(
    const gfx::ScrollOffset& target_value,
    std::unique_ptr<TimingFunction> timing_function,
    DurationBehavior duration_behavior)
    : target_value_(target_value),
      timing_function_(std::move(timing_function)),
      duration_behavior_(duration_behavior),
      has_set_initial_value_(false) {}

ScrollOffsetAnimationCurve::~ScrollOffsetAnimationCurve() {}

base::TimeDelta ScrollOffsetAnimationCurve::SegmentDuration(
    const gfx::Vector2dF& delta,
    DurationBehavior behavior,
    base::TimeDelta delayed_by) {
  double duration = kConstantDuration;
  switch (behavior) {
    case DurationBehavior::CONSTANT:
      duration = kConstantDuration;
      break;
    case DurationBehavior::DELTA_BASED:
      duration = std::sqrt(std::abs(MaximumDimension(delta)));
      break;
    case DurationBehavior::INVERSE_DELTA:
      duration = std::min(
          std::max(kInverseDeltaOffset +
                       std::abs(MaximumDimension(delta)) * kInverseDeltaSlope,
                   kInverseDeltaMinDuration),
          kInverseDeltaMaxDuration);
      break;
    default:
      NOTREACHED();
  }

  base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds(
      duration / kDurationDivisor * base::Time::kMicrosecondsPerSecond);

  time_delta -= delayed_by;
  if (time_delta >= base::TimeDelta())
    return time_delta;
  return base::TimeDelta();
}

void ScrollOffsetAnimationCurve::SetInitialValue(
    const gfx::ScrollOffset& initial_value,
    base::TimeDelta delayed_by) {
  initial_value_ = initial_value;
  has_set_initial_value_ = true;
  total_animation_duration_ = SegmentDuration(
      target_value_.DeltaFrom(initial_value_), duration_behavior_, delayed_by);
}

bool ScrollOffsetAnimationCurve::HasSetInitialValue() const {
  return has_set_initial_value_;
}

void ScrollOffsetAnimationCurve::ApplyAdjustment(
    const gfx::Vector2dF& adjustment) {
  initial_value_ = ScrollOffsetWithDelta(initial_value_, adjustment);
  target_value_ = ScrollOffsetWithDelta(target_value_, adjustment);
}

gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(
    base::TimeDelta t) const {
  base::TimeDelta duration = total_animation_duration_ - last_retarget_;
  t -= last_retarget_;

  if (duration.is_zero())
    return target_value_;

  if (t <= base::TimeDelta())
    return initial_value_;

  if (t >= duration)
    return target_value_;

  double progress = timing_function_->GetValue(TimeUtil::Divide(t, duration));
  return gfx::ScrollOffset(
      gfx::Tween::FloatValueBetween(
          progress, initial_value_.x(), target_value_.x()),
      gfx::Tween::FloatValueBetween(
          progress, initial_value_.y(), target_value_.y()));
}

base::TimeDelta ScrollOffsetAnimationCurve::Duration() const {
  return total_animation_duration_;
}

AnimationCurve::CurveType ScrollOffsetAnimationCurve::Type() const {
  return SCROLL_OFFSET;
}

std::unique_ptr<AnimationCurve> ScrollOffsetAnimationCurve::Clone() const {
  return CloneToScrollOffsetAnimationCurve();
}

std::unique_ptr<ScrollOffsetAnimationCurve>
ScrollOffsetAnimationCurve::CloneToScrollOffsetAnimationCurve() const {
  std::unique_ptr<TimingFunction> timing_function(
      static_cast<TimingFunction*>(timing_function_->Clone().release()));
  std::unique_ptr<ScrollOffsetAnimationCurve> curve_clone =
      Create(target_value_, std::move(timing_function), duration_behavior_);
  curve_clone->initial_value_ = initial_value_;
  curve_clone->total_animation_duration_ = total_animation_duration_;
  curve_clone->last_retarget_ = last_retarget_;
  curve_clone->has_set_initial_value_ = has_set_initial_value_;
  return curve_clone;
}

static double VelocityBasedDurationBound(gfx::Vector2dF old_delta,
                                         double old_normalized_velocity,
                                         double old_duration,
                                         gfx::Vector2dF new_delta) {
  double old_delta_max_dimension = MaximumDimension(old_delta);
  double new_delta_max_dimension = MaximumDimension(new_delta);

  // If we are already at the target, stop animating.
  if (std::abs(new_delta_max_dimension) < kEpsilon)
    return 0;

  // Guard against division by zero.
  if (std::abs(old_delta_max_dimension) < kEpsilon ||
      std::abs(old_normalized_velocity) < kEpsilon) {
    return std::numeric_limits<double>::infinity();
  }

  // Estimate how long it will take to reach the new target at our present
  // velocity, with some fudge factor to account for the "ease out".
  double old_true_velocity =
      old_normalized_velocity * old_delta_max_dimension / old_duration;
  double bound = (new_delta_max_dimension / old_true_velocity) * 2.5f;

  // If bound < 0 we are moving in the opposite direction.
  return bound < 0 ? std::numeric_limits<double>::infinity() : bound;
}

void ScrollOffsetAnimationCurve::UpdateTarget(
    double t,
    const gfx::ScrollOffset& new_target) {
  if (std::abs(MaximumDimension(target_value_.DeltaFrom(new_target))) <
      kEpsilon) {
    target_value_ = new_target;
    return;
  }

  base::TimeDelta delayed_by = base::TimeDelta::FromSecondsD(
      std::max(0.0, last_retarget_.InSecondsF() - t));
  t = std::max(t, last_retarget_.InSecondsF());

  gfx::ScrollOffset current_position =
      GetValue(base::TimeDelta::FromSecondsD(t));
  gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_);
  gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position);

  // The last segement was of zero duration.
  if ((total_animation_duration_ - last_retarget_).is_zero()) {
    DCHECK_EQ(t, last_retarget_.InSecondsF());
    total_animation_duration_ =
        SegmentDuration(new_delta, duration_behavior_, delayed_by);
    target_value_ = new_target;
    return;
  }

  double old_duration =
      (total_animation_duration_ - last_retarget_).InSecondsF();
  double old_normalized_velocity = timing_function_->Velocity(
      (t - last_retarget_.InSecondsF()) / old_duration);

  // Use the velocity-based duration bound when it is less than the constant
  // segment duration. This minimizes the "rubber-band" bouncing effect when
  // old_normalized_velocity is large and new_delta is small.
  double new_duration = std::min(
      SegmentDuration(new_delta, duration_behavior_, delayed_by).InSecondsF(),
      VelocityBasedDurationBound(old_delta, old_normalized_velocity,
                                 old_duration, new_delta));

  if (new_duration < kEpsilon) {
    // We are already at or very close to the new target. Stop animating.
    target_value_ = new_target;
    total_animation_duration_ = base::TimeDelta::FromSecondsD(t);
    return;
  }

  // TimingFunction::Velocity gives the slope of the curve from 0 to 1.
  // To match the "true" velocity in px/sec we must adjust this slope for
  // differences in duration and scroll delta between old and new curves.
  double new_normalized_velocity =
      old_normalized_velocity * (new_duration / old_duration) *
      (MaximumDimension(old_delta) / MaximumDimension(new_delta));

  initial_value_ = current_position;
  target_value_ = new_target;
  total_animation_duration_ = base::TimeDelta::FromSecondsD(t + new_duration);
  last_retarget_ = base::TimeDelta::FromSecondsD(t);
  timing_function_ = EaseOutWithInitialVelocity(new_normalized_velocity);
}

}  // namespace cc
