// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/renderer/smoothed_value.h"

#include <algorithm>
#include <cmath>
#include <limits>

namespace cobalt {
namespace renderer {

SmoothedValue::SmoothedValue(base::TimeDelta time_to_converge,
                             base::optional<double> max_slope_magnitude)
    : time_to_converge_(time_to_converge),
      previous_derivative_(0),
      max_slope_magnitude_(max_slope_magnitude) {
  DCHECK(base::TimeDelta() < time_to_converge_);
  DCHECK(!max_slope_magnitude_ || *max_slope_magnitude_ > 0);
}

void SmoothedValue::SetTarget(double target, const base::TimeTicks& time) {
  // Determine the current derivative and value.
  double current_derivative = GetCurrentDerivative(time);
  base::optional<double> current_value;
  if (target_) {
    current_value = GetValueAtTime(time);
  }

  // Set the previous derivative and value to the current derivative and value.
  previous_derivative_ = current_derivative;
  previous_value_ = current_value;

  target_ = target;
  target_set_time_ = time;
}

void SmoothedValue::SnapToTarget() {
  previous_value_ = base::nullopt;
  previous_derivative_ = 0;
}

double SmoothedValue::GetValueAtTime(const base::TimeTicks& time) const {
  if (!previous_value_) {
    // If only one target has ever been set, simply return it.
    return *target_;
  }

  // Compute the current value based off of a cubic bezier curve.
  double t = SmoothedValue::t(time);
  double one_minus_t = 1 - t;
  double P0 = SmoothedValue::P0();
  double P1 = SmoothedValue::P1();
  double P2 = SmoothedValue::P2();
  double P3 = SmoothedValue::P3();

  return one_minus_t * one_minus_t * one_minus_t * P0 +
         3 * one_minus_t * one_minus_t * t * P1 + 3 * one_minus_t * t * t * P2 +
         t * t * t * P3;
}

double SmoothedValue::t(const base::TimeTicks& time) const {
  DCHECK(target_) << "SetTarget() must have been called previously.";

  base::TimeDelta time_diff = time - target_set_time_;
  double time_to_converge_in_seconds = time_to_converge_.InSecondsF();

  // Enforce any maximum slope constraints (which can result in overriding the
  // time to converge).
  if (max_slope_magnitude_) {
    double largest_slope = GetDerivativeWithLargestMagnitude();
    if (largest_slope == std::numeric_limits<double>::infinity() ||
        largest_slope == -std::numeric_limits<double>::infinity()) {
      // If we can have a slope of infinity, then just don't move.
      return 0;
    }

    // If we find that our smoothing curve's maximum slope would result in a
    // slope greater than the maximum slope constraint, stretch the time to
    // converge in order to meet the slope constraint.  This can result in
    // overriding the user-provided time to converge.
    double unconstrained_largest_slope =
        largest_slope / time_to_converge_in_seconds;
    if (unconstrained_largest_slope < -*max_slope_magnitude_) {
      time_to_converge_in_seconds =
          -largest_slope / *max_slope_magnitude_;
    } else if (unconstrained_largest_slope > *max_slope_magnitude_) {
      time_to_converge_in_seconds =
          largest_slope / *max_slope_magnitude_;
    }
  }

  double t = time_diff.InSecondsF() / time_to_converge_in_seconds;

  DCHECK_LE(0, t);

  return std::max(std::min(t, 1.0), 0.0);
}

double SmoothedValue::P1() const {
  // See comments in header for why P1() is calculated this way.
  return *previous_value_ + previous_derivative_ / 3.0f;
}

double SmoothedValue::P2() const {
  // See comments in header for why P2() is calculated this way.
  return P3();
}

namespace {
double EvaluateCubicBezierDerivative(double P0, double P1, double P2, double P3,
                                     double t) {
  double one_minus_t = 1 - t;
  return 3 * one_minus_t * one_minus_t * (P1 - P0) +
         6 * one_minus_t * t * (P2 - P1) + 3 * t * t * (P3 - P2);
}
}

double SmoothedValue::GetCurrentDerivative(const base::TimeTicks& time) const {
  if (!previous_value_) {
    // If only one target has ever been set, return 0 as our derivative.
    return 0;
  }

  double t = SmoothedValue::t(time);
  double P0 = SmoothedValue::P0();
  double P1 = SmoothedValue::P1();
  double P2 = SmoothedValue::P2();
  double P3 = SmoothedValue::P3();

  return EvaluateCubicBezierDerivative(P0, P1, P2, P3, t);
}

double SmoothedValue::GetDerivativeWithLargestMagnitude() const {
  double P0 = SmoothedValue::P0();
  double P1 = SmoothedValue::P1();
  double P2 = SmoothedValue::P2();
  double P3 = SmoothedValue::P3();

  // Since our spline is a cubic function, it will have a single inflection
  // point where its derivative is 0 (or infinite if
  // numerator = denominator = 0).  This function finds that single inflection
  // point and stores the value in |t|.  We then evaluate the derivative at
  // that inflection point, and at the beginning and end of the [0, 1] segment.
  // We then compare the results and return the derivative with the largest
  // magnitude.

  // Compute the location of the inflection point by setting the second
  // derivative to zero and solving.
  double numerator = (P2 - 2 * P1 + P0);
  double denominator = (-P3 + 3 * P2 - 3 * P1 + P0);
  double t;
  if (numerator == 0) {
    t = 0;
  } else if (denominator == 0.0) {
    double numerator_sign = (numerator >= 0 ? 1.0 : -1.0);
    return numerator_sign * std::numeric_limits<double>::infinity();
  } else {
    t = numerator / denominator;
  }

  // Evaluate the value of the derivative at each critical point.
  double at_inflection_point = EvaluateCubicBezierDerivative(P0, P1, P2, P3, t);
  double at_start = EvaluateCubicBezierDerivative(P0, P1, P2, P3, 0);
  double at_end = EvaluateCubicBezierDerivative(P0, P1, P2, P3, 1);

  if (std::abs(at_inflection_point) > std::abs(at_start)) {
    if (std::abs(at_inflection_point) > std::abs(at_end)) {
      return at_inflection_point;
    } else {
      return at_end;
    }
  } else {
    if (std::abs(at_start) > std::abs(at_end)) {
      return at_start;
    } else {
      return at_end;
    }
  }
}

}  // namespace renderer
}  // namespace cobalt
