// Copyright 2014 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 "ui/events/gesture_detection/velocity_tracker.h"

#include <cmath>

#include "base/logging.h"
#include "ui/events/gesture_detection/motion_event.h"

using base::TimeDelta;
using base::TimeTicks;

namespace ui {

// Implements a particular velocity tracker algorithm.
class VelocityTrackerStrategy {
 public:
  virtual ~VelocityTrackerStrategy() {}

  virtual void Clear() = 0;
  virtual void ClearPointers(BitSet32 id_bits) = 0;
  virtual void AddMovement(const base::TimeTicks& event_time,
                           BitSet32 id_bits,
                           const Position* positions) = 0;
  virtual bool GetEstimator(uint32_t id, Estimator* out_estimator) const = 0;

 protected:
  VelocityTrackerStrategy() {}
};

namespace {

static_assert(MotionEvent::MAX_POINTER_ID < 32, "max pointer id too large");

// Threshold between ACTION_MOVE events for determining that a pointer has
// stopped moving. Some input devices do not send ACTION_MOVE events in the case
// where a pointer has stopped.  We need to detect this case so that we can
// accurately predict the velocity after the pointer starts moving again.
const int kAssumePointerMoveStoppedTimeMs = 40;

// Threshold between ACTION_MOVE and ACTION_{UP|POINTER_UP} events for
// determining that a pointer has stopped moving. This is a larger threshold
// than |kAssumePointerMoveStoppedTimeMs|, as some devices may delay synthesis
// of ACTION_{UP|POINTER_UP} to reduce risk of noisy release.
const int kAssumePointerUpStoppedTimeMs = 80;

struct Position {
  float x, y;
};

struct Estimator {
  static const uint8_t kMaxDegree = 4;

  // Estimator time base.
  TimeTicks time;

  // Polynomial coefficients describing motion in X and Y.
  float xcoeff[kMaxDegree + 1], ycoeff[kMaxDegree + 1];

  // Polynomial degree (number of coefficients), or zero if no information is
  // available.
  uint32_t degree;

  // Confidence (coefficient of determination), between 0 (no fit)
  // and 1 (perfect fit).
  float confidence;

  inline void Clear() {
    time = TimeTicks();
    degree = 0;
    confidence = 0;
    for (size_t i = 0; i <= kMaxDegree; i++) {
      xcoeff[i] = 0;
      ycoeff[i] = 0;
    }
  }
};

float VectorDot(const float* a, const float* b, uint32_t m) {
  float r = 0;
  while (m--) {
    r += *(a++) * *(b++);
  }
  return r;
}

float VectorNorm(const float* a, uint32_t m) {
  float r = 0;
  while (m--) {
    float t = *(a++);
    r += t * t;
  }
  return sqrtf(r);
}

// Velocity tracker algorithm based on least-squares linear regression.
class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
 public:
  enum Weighting {
    // No weights applied.  All data points are equally reliable.
    WEIGHTING_NONE,

    // Weight by time delta.  Data points clustered together are weighted less.
    WEIGHTING_DELTA,

    // Weight such that points within a certain horizon are weighed more than
    // those outside of that horizon.
    WEIGHTING_CENTRAL,

    // Weight such that points older than a certain amount are weighed less.
    WEIGHTING_RECENT,
  };

  enum Restriction {
    // There's no restriction on the output of the velocity tracker.
    RESTRICTION_NONE,

    // If the velocity determined by the tracker is in a sufficiently different
    // direction from the primary motion of the finger for the events being
    // considered for velocity calculation, return a velocity of 0.
    RESTRICTION_ALIGNED_DIRECTIONS
  };

  // Number of samples to keep.
  static const uint8_t kHistorySize = 20;

  // Degree must be no greater than Estimator::kMaxDegree.
  LeastSquaresVelocityTrackerStrategy(
      uint32_t degree,
      Weighting weighting,
      Restriction restriction);
  ~LeastSquaresVelocityTrackerStrategy() override;

  void Clear() override;
  void ClearPointers(BitSet32 id_bits) override;
  void AddMovement(const TimeTicks& event_time,
                   BitSet32 id_bits,
                   const Position* positions) override;
  bool GetEstimator(uint32_t id, Estimator* out_estimator) const override;

 private:
  // Sample horizon.
  // We don't use too much history by default since we want to react to quick
  // changes in direction.
  static const uint8_t kHorizonMS = 100;

  struct Movement {
    TimeTicks event_time;
    BitSet32 id_bits;
    Position positions[VelocityTracker::MAX_POINTERS];

    inline const Position& GetPosition(uint32_t id) const {
      return positions[id_bits.get_index_of_bit(id)];
    }
  };

  float ChooseWeight(uint32_t index) const;

  const uint32_t degree_;
  const Weighting weighting_;
  const Restriction restriction_;
  uint32_t index_;
  Movement movements_[kHistorySize];
};

// Velocity tracker algorithm that uses an IIR filter.
class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
 public:
  // Degree must be 1 or 2.
  explicit IntegratingVelocityTrackerStrategy(uint32_t degree);
  ~IntegratingVelocityTrackerStrategy() override;

  void Clear() override;
  void ClearPointers(BitSet32 id_bits) override;
  void AddMovement(const TimeTicks& event_time,
                   BitSet32 id_bits,
                   const Position* positions) override;
  bool GetEstimator(uint32_t id, Estimator* out_estimator) const override;

 private:
  // Current state estimate for a particular pointer.
  struct State {
    TimeTicks update_time;
    uint32_t degree;

    float xpos, xvel, xaccel;
    float ypos, yvel, yaccel;
  };

  const uint32_t degree_;
  BitSet32 pointer_id_bits_;
  State mPointerState[MotionEvent::MAX_POINTER_ID + 1];

  void InitState(State& state,
                 const TimeTicks& event_time,
                 float xpos,
                 float ypos) const;
  void UpdateState(State& state,
                   const TimeTicks& event_time,
                   float xpos,
                   float ypos) const;
  void PopulateEstimator(const State& state, Estimator* out_estimator) const;
};

VelocityTrackerStrategy* CreateStrategy(VelocityTracker::Strategy strategy) {
  LeastSquaresVelocityTrackerStrategy::Weighting none =
      LeastSquaresVelocityTrackerStrategy::WEIGHTING_NONE;
  LeastSquaresVelocityTrackerStrategy::Restriction no_restriction =
      LeastSquaresVelocityTrackerStrategy::RESTRICTION_NONE;
  switch (strategy) {
    case VelocityTracker::LSQ1:
      return new LeastSquaresVelocityTrackerStrategy(1, none, no_restriction);
    case VelocityTracker::LSQ2:
      return new LeastSquaresVelocityTrackerStrategy(2, none, no_restriction);
    case VelocityTracker::LSQ2_RESTRICTED:
      return new LeastSquaresVelocityTrackerStrategy(
          2, LeastSquaresVelocityTrackerStrategy::WEIGHTING_NONE,
          LeastSquaresVelocityTrackerStrategy::RESTRICTION_ALIGNED_DIRECTIONS);
    case VelocityTracker::LSQ3:
      return new LeastSquaresVelocityTrackerStrategy(3, none, no_restriction);
    case VelocityTracker::WLSQ2_DELTA:
      return new LeastSquaresVelocityTrackerStrategy(
          2, LeastSquaresVelocityTrackerStrategy::WEIGHTING_DELTA,
          no_restriction);
    case VelocityTracker::WLSQ2_CENTRAL:
      return new LeastSquaresVelocityTrackerStrategy(
          2, LeastSquaresVelocityTrackerStrategy::WEIGHTING_CENTRAL,
          no_restriction);
    case VelocityTracker::WLSQ2_RECENT:
      return new LeastSquaresVelocityTrackerStrategy(
          2, LeastSquaresVelocityTrackerStrategy::WEIGHTING_RECENT,
          no_restriction);
    case VelocityTracker::INT1:
      return new IntegratingVelocityTrackerStrategy(1);
    case VelocityTracker::INT2:
      return new IntegratingVelocityTrackerStrategy(2);
  }
  NOTREACHED() << "Unrecognized velocity tracker strategy: " << strategy;
  // Quadratic regression is a safe default.
  return CreateStrategy(VelocityTracker::STRATEGY_DEFAULT);
}

}  // namespace

// --- VelocityTracker ---

VelocityTracker::VelocityTracker(Strategy strategy)
    : current_pointer_id_bits_(0),
      active_pointer_id_(-1),
      strategy_(CreateStrategy(strategy)) {}

VelocityTracker::~VelocityTracker() {}

void VelocityTracker::Clear() {
  current_pointer_id_bits_.clear();
  active_pointer_id_ = -1;
  strategy_->Clear();
}

void VelocityTracker::ClearPointers(BitSet32 id_bits) {
  BitSet32 remaining_id_bits(current_pointer_id_bits_.value & ~id_bits.value);
  current_pointer_id_bits_ = remaining_id_bits;

  if (active_pointer_id_ >= 0 && id_bits.has_bit(active_pointer_id_)) {
    active_pointer_id_ = !remaining_id_bits.is_empty()
                             ? remaining_id_bits.first_marked_bit()
                             : -1;
  }

  strategy_->ClearPointers(id_bits);
}

void VelocityTracker::AddMovement(const TimeTicks& event_time,
                                  BitSet32 id_bits,
                                  const Position* positions) {
  while (id_bits.count() > MAX_POINTERS)
    id_bits.clear_last_marked_bit();

  if ((current_pointer_id_bits_.value & id_bits.value) &&
      (event_time - last_event_time_) >=
          base::TimeDelta::FromMilliseconds(kAssumePointerMoveStoppedTimeMs)) {
    // We have not received any movements for too long. Assume that all pointers
    // have stopped.
    strategy_->Clear();
  }
  last_event_time_ = event_time;

  current_pointer_id_bits_ = id_bits;
  if (active_pointer_id_ < 0 || !id_bits.has_bit(active_pointer_id_))
    active_pointer_id_ = id_bits.is_empty() ? -1 : id_bits.first_marked_bit();

  strategy_->AddMovement(event_time, id_bits, positions);
}

void VelocityTracker::AddMovement(const MotionEvent& event) {
  int32_t actionMasked = event.GetAction();

  switch (actionMasked) {
    case MotionEvent::ACTION_DOWN:
      // case MotionEvent::HOVER_ENTER:
      // Clear all pointers on down before adding the new movement.
      Clear();
      break;
    case MotionEvent::ACTION_POINTER_DOWN: {
      // Start a new movement trace for a pointer that just went down.
      // We do this on down instead of on up because the client may want to
      // query the final velocity for a pointer that just went up.
      BitSet32 downIdBits;
      downIdBits.mark_bit(event.GetPointerId(event.GetActionIndex()));
      ClearPointers(downIdBits);
      break;
    }
    case MotionEvent::ACTION_MOVE:
      // case MotionEvent::ACTION_HOVER_MOVE:
      break;
    case MotionEvent::ACTION_UP:
    case MotionEvent::ACTION_POINTER_UP:
      // Note that ACTION_UP and ACTION_POINTER_UP always report the last known
      // position of the pointers that went up.  ACTION_POINTER_UP does include
      // the new position of pointers that remained down but we will also
      // receive an ACTION_MOVE with this information if any of them actually
      // moved.  Since we don't know how many pointers will be going up at once
      // it makes sense to just wait for the following ACTION_MOVE before adding
      // the movement. However, if the up event itself is delayed because of
      // (difficult albeit possible) prolonged stationary screen contact, assume
      // that motion has stopped.
      if ((event.GetEventTime() - last_event_time_) >=
          base::TimeDelta::FromMilliseconds(kAssumePointerUpStoppedTimeMs))
        strategy_->Clear();
      return;
    default:
      // Ignore all other actions because they do not convey any new information
      // about pointer movement.  We also want to preserve the last known
      // velocity of the pointers.
      return;
  }

  size_t pointer_count = event.GetPointerCount();
  if (pointer_count > MAX_POINTERS) {
    pointer_count = MAX_POINTERS;
  }

  BitSet32 id_bits;
  for (size_t i = 0; i < pointer_count; i++) {
    id_bits.mark_bit(event.GetPointerId(i));
  }

  uint32_t pointer_index[MAX_POINTERS];
  for (size_t i = 0; i < pointer_count; i++) {
    pointer_index[i] = id_bits.get_index_of_bit(event.GetPointerId(i));
  }

  Position positions[MAX_POINTERS];
  size_t historySize = event.GetHistorySize();
  for (size_t h = 0; h < historySize; h++) {
    for (size_t i = 0; i < pointer_count; i++) {
      uint32_t index = pointer_index[i];
      positions[index].x = event.GetHistoricalX(i, h);
      positions[index].y = event.GetHistoricalY(i, h);
    }
    AddMovement(event.GetHistoricalEventTime(h), id_bits, positions);
  }

  for (size_t i = 0; i < pointer_count; i++) {
    uint32_t index = pointer_index[i];
    positions[index].x = event.GetX(i);
    positions[index].y = event.GetY(i);
  }
  AddMovement(event.GetEventTime(), id_bits, positions);
}

bool VelocityTracker::GetVelocity(uint32_t id,
                                  float* out_vx,
                                  float* out_vy) const {
  Estimator estimator;
  if (GetEstimator(id, &estimator) && estimator.degree >= 1) {
    *out_vx = estimator.xcoeff[1];
    *out_vy = estimator.ycoeff[1];
    return true;
  }
  *out_vx = 0;
  *out_vy = 0;
  return false;
}

void LeastSquaresVelocityTrackerStrategy::AddMovement(
    const TimeTicks& event_time,
    BitSet32 id_bits,
    const Position* positions) {
  if (++index_ == kHistorySize) {
    index_ = 0;
  }

  Movement& movement = movements_[index_];
  movement.event_time = event_time;
  movement.id_bits = id_bits;
  uint32_t count = id_bits.count();
  for (uint32_t i = 0; i < count; i++) {
    movement.positions[i] = positions[i];
  }
}

bool VelocityTracker::GetEstimator(uint32_t id,
                                   Estimator* out_estimator) const {
  return strategy_->GetEstimator(id, out_estimator);
}

// --- LeastSquaresVelocityTrackerStrategy ---

LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(
    uint32_t degree,
    Weighting weighting,
    Restriction restriction)
    : degree_(degree),
      weighting_(weighting),
      restriction_(restriction) {
  DCHECK_LT(degree_, static_cast<uint32_t>(Estimator::kMaxDegree));
  Clear();
}

LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {}

void LeastSquaresVelocityTrackerStrategy::Clear() {
  index_ = 0;
  movements_[0].id_bits.clear();
}

/**
 * Solves a linear least squares problem to obtain a N degree polynomial that
 * fits the specified input data as nearly as possible.
 *
 * Returns true if a solution is found, false otherwise.
 *
 * The input consists of two vectors of data points X and Y with indices 0..m-1
 * along with a weight vector W of the same size.
 *
 * The output is a vector B with indices 0..n that describes a polynomial
 * that fits the data, such the sum of W[i] * W[i] * abs(Y[i] - (B[0] + B[1]
 * X[i] * + B[2] X[i]^2 ... B[n] X[i]^n)) for all i between 0 and m-1 is
 * minimized.
 *
 * Accordingly, the weight vector W should be initialized by the caller with the
 * reciprocal square root of the variance of the error in each input data point.
 * In other words, an ideal choice for W would be W[i] = 1 / var(Y[i]) = 1 /
 * stddev(Y[i]).
 * The weights express the relative importance of each data point.  If the
 * weights are* all 1, then the data points are considered to be of equal
 * importance when fitting the polynomial.  It is a good idea to choose weights
 * that diminish the importance of data points that may have higher than usual
 * error margins.
 *
 * Errors among data points are assumed to be independent.  W is represented
 * here as a vector although in the literature it is typically taken to be a
 * diagonal matrix.
 *
 * That is to say, the function that generated the input data can be
 * approximated by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
 *
 * The coefficient of determination (R^2) is also returned to describe the
 * goodness of fit of the model for the given data.  It is a value between 0
 * and 1, where 1 indicates perfect correspondence.
 *
 * This function first expands the X vector to a m by n matrix A such that
 * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n, then
 * multiplies it by w[i]./
 *
 * Then it calculates the QR decomposition of A yielding an m by m orthonormal
 * matrix Q and an m by n upper triangular matrix R.  Because R is upper
 * triangular (lower part is all zeroes), we can simplify the decomposition into
 * an m by n matrix Q1 and a n by n matrix R1 such that A = Q1 R1.
 *
 * Finally we solve the system of linear equations given by
 * R1 B = (Qtranspose W Y) to find B.
 *
 * For efficiency, we lay out A and Q column-wise in memory because we
 * frequently operate on the column vectors.  Conversely, we lay out R row-wise.
 *
 * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
 * http://en.wikipedia.org/wiki/Gram-Schmidt
 */
static bool SolveLeastSquares(const float* x,
                              const float* y,
                              const float* w,
                              uint32_t m,
                              uint32_t n,
                              float* out_b,
                              float* out_det) {
  // MSVC does not support variable-length arrays (used by the original Android
  // implementation of this function).
#if defined(COMPILER_MSVC)
  const uint32_t M_ARRAY_LENGTH =
      LeastSquaresVelocityTrackerStrategy::kHistorySize;
  const uint32_t N_ARRAY_LENGTH = Estimator::kMaxDegree;
  DCHECK_LE(m, M_ARRAY_LENGTH);
  DCHECK_LE(n, N_ARRAY_LENGTH);
#else
  const uint32_t M_ARRAY_LENGTH = m;
  const uint32_t N_ARRAY_LENGTH = n;
#endif

  // Expand the X vector to a matrix A, pre-multiplied by the weights.
  float a[N_ARRAY_LENGTH][M_ARRAY_LENGTH];  // column-major order
  for (uint32_t h = 0; h < m; h++) {
    a[0][h] = w[h];
    for (uint32_t i = 1; i < n; i++) {
      a[i][h] = a[i - 1][h] * x[h];
    }
  }

  // Apply the Gram-Schmidt process to A to obtain its QR decomposition.

  // Orthonormal basis, column-major order.
  float q[N_ARRAY_LENGTH][M_ARRAY_LENGTH];
  // Upper triangular matrix, row-major order.
  float r[N_ARRAY_LENGTH][N_ARRAY_LENGTH];
  for (uint32_t j = 0; j < n; j++) {
    for (uint32_t h = 0; h < m; h++) {
      q[j][h] = a[j][h];
    }
    for (uint32_t i = 0; i < j; i++) {
      float dot = VectorDot(&q[j][0], &q[i][0], m);
      for (uint32_t h = 0; h < m; h++) {
        q[j][h] -= dot * q[i][h];
      }
    }

    float norm = VectorNorm(&q[j][0], m);
    if (norm < 0.000001f) {
      // vectors are linearly dependent or zero so no solution
      return false;
    }

    float invNorm = 1.0f / norm;
    for (uint32_t h = 0; h < m; h++) {
      q[j][h] *= invNorm;
    }
    for (uint32_t i = 0; i < n; i++) {
      r[j][i] = i < j ? 0 : VectorDot(&q[j][0], &a[i][0], m);
    }
  }

  // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.
  // We just work from bottom-right to top-left calculating B's coefficients.
  float wy[M_ARRAY_LENGTH];
  for (uint32_t h = 0; h < m; h++) {
    wy[h] = y[h] * w[h];
  }
  for (uint32_t i = n; i-- != 0;) {
    out_b[i] = VectorDot(&q[i][0], wy, m);
    for (uint32_t j = n - 1; j > i; j--) {
      out_b[i] -= r[i][j] * out_b[j];
    }
    out_b[i] /= r[i][i];
  }

  // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
  // SSerr is the residual sum of squares (variance of the error),
  // and SStot is the total sum of squares (variance of the data) where each
  // has been weighted.
  float ymean = 0;
  for (uint32_t h = 0; h < m; h++) {
    ymean += y[h];
  }
  ymean /= m;

  float sserr = 0;
  float sstot = 0;
  for (uint32_t h = 0; h < m; h++) {
    float err = y[h] - out_b[0];
    float term = 1;
    for (uint32_t i = 1; i < n; i++) {
      term *= x[h];
      err -= term * out_b[i];
    }
    sserr += w[h] * w[h] * err * err;
    float var = y[h] - ymean;
    sstot += w[h] * w[h] * var * var;
  }
  *out_det = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
  return true;
}

void LeastSquaresVelocityTrackerStrategy::ClearPointers(BitSet32 id_bits) {
  BitSet32 remaining_id_bits(movements_[index_].id_bits.value & ~id_bits.value);
  movements_[index_].id_bits = remaining_id_bits;
}

bool LeastSquaresVelocityTrackerStrategy::GetEstimator(
    uint32_t id,
    Estimator* out_estimator) const {
  out_estimator->Clear();

  // Iterate over movement samples in reverse time order and collect samples.
  float x[kHistorySize];
  float y[kHistorySize];
  float w[kHistorySize];
  float time[kHistorySize];
  uint32_t m = 0;
  uint32_t index = index_;
  const base::TimeDelta horizon = base::TimeDelta::FromMilliseconds(kHorizonMS);
  const Movement& newest_movement = movements_[index_];
  const Movement* first_movement = nullptr;

  do {
    const Movement& movement = movements_[index];
    if (!movement.id_bits.has_bit(id))
      break;

    first_movement = &movement;
    TimeDelta age = newest_movement.event_time - movement.event_time;
    if (age > horizon)
      break;

    const Position& position = movement.GetPosition(id);
    x[m] = position.x;
    y[m] = position.y;
    w[m] = ChooseWeight(index);
    time[m] = -static_cast<float>(age.InSecondsF());
    index = (index == 0 ? kHistorySize : index) - 1;
  } while (++m < kHistorySize);

  if (m == 0)
    return false;  // no data

  // Calculate a least squares polynomial fit.
  uint32_t degree = degree_;
  if (degree > m - 1)
    degree = m - 1;

  if (degree >= 1) {
    float xdet, ydet;
    uint32_t n = degree + 1;
    if (SolveLeastSquares(time, x, w, m, n, out_estimator->xcoeff, &xdet) &&
        SolveLeastSquares(time, y, w, m, n, out_estimator->ycoeff, &ydet)) {
      if (restriction_ == RESTRICTION_ALIGNED_DIRECTIONS) {
        DCHECK(first_movement);
        float dx = newest_movement.GetPosition(id).x -
                   first_movement->GetPosition(id).x;
        float dy = newest_movement.GetPosition(id).y -
                   first_movement->GetPosition(id).y;

        // If the velocity is in a sufficiently different direction from the
        // primary movement, ignore it.
        if (out_estimator->xcoeff[1] * dx + out_estimator->ycoeff[1] * dy < 0)
          return false;
      }

      out_estimator->time = newest_movement.event_time;
      out_estimator->degree = degree;
      out_estimator->confidence = xdet * ydet;
      return true;
    }
  }

  // No velocity data available for this pointer, but we do have its current
  // position.
  out_estimator->xcoeff[0] = x[0];
  out_estimator->ycoeff[0] = y[0];
  out_estimator->time = newest_movement.event_time;
  out_estimator->degree = 0;
  out_estimator->confidence = 1;
  return true;
}

float LeastSquaresVelocityTrackerStrategy::ChooseWeight(uint32_t index) const {
  switch (weighting_) {
    case WEIGHTING_DELTA: {
      // Weight points based on how much time elapsed between them and the next
      // point so that points that "cover" a shorter time span are weighed less.
      //   delta  0ms: 0.5
      //   delta 10ms: 1.0
      if (index == index_) {
        return 1.0f;
      }
      uint32_t next_index = (index + 1) % kHistorySize;
      float delta_millis =
          static_cast<float>((movements_[next_index].event_time -
                              movements_[index].event_time).InMillisecondsF());
      if (delta_millis < 0)
        return 0.5f;
      if (delta_millis < 10)
        return 0.5f + delta_millis * 0.05f;

      return 1.0f;
    }

    case WEIGHTING_CENTRAL: {
      // Weight points based on their age, weighing very recent and very old
      // points less.
      //   age  0ms: 0.5
      //   age 10ms: 1.0
      //   age 50ms: 1.0
      //   age 60ms: 0.5
      float age_millis =
          static_cast<float>((movements_[index_].event_time -
                              movements_[index].event_time).InMillisecondsF());
      if (age_millis < 0)
        return 0.5f;
      if (age_millis < 10)
        return 0.5f + age_millis * 0.05f;
      if (age_millis < 50)
        return 1.0f;
      if (age_millis < 60)
        return 0.5f + (60 - age_millis) * 0.05f;

      return 0.5f;
    }

    case WEIGHTING_RECENT: {
      // Weight points based on their age, weighing older points less.
      //   age   0ms: 1.0
      //   age  50ms: 1.0
      //   age 100ms: 0.5
      float age_millis =
          static_cast<float>((movements_[index_].event_time -
                              movements_[index].event_time).InMillisecondsF());
      if (age_millis < 50) {
        return 1.0f;
      }
      if (age_millis < 100) {
        return 0.5f + (100 - age_millis) * 0.01f;
      }
      return 0.5f;
    }

    case WEIGHTING_NONE:
    default:
      return 1.0f;
  }
}

// --- IntegratingVelocityTrackerStrategy ---

IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(
    uint32_t degree)
    : degree_(degree) {
  DCHECK_LT(degree_, static_cast<uint32_t>(Estimator::kMaxDegree));
}

IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {}

void IntegratingVelocityTrackerStrategy::Clear() { pointer_id_bits_.clear(); }

void IntegratingVelocityTrackerStrategy::ClearPointers(BitSet32 id_bits) {
  pointer_id_bits_.value &= ~id_bits.value;
}

void IntegratingVelocityTrackerStrategy::AddMovement(
    const TimeTicks& event_time,
    BitSet32 id_bits,
    const Position* positions) {
  uint32_t index = 0;
  for (BitSet32 iter_id_bits(id_bits); !iter_id_bits.is_empty();) {
    uint32_t id = iter_id_bits.clear_first_marked_bit();
    State& state = mPointerState[id];
    const Position& position = positions[index++];
    if (pointer_id_bits_.has_bit(id))
      UpdateState(state, event_time, position.x, position.y);
    else
      InitState(state, event_time, position.x, position.y);
  }

  pointer_id_bits_ = id_bits;
}

bool IntegratingVelocityTrackerStrategy::GetEstimator(
    uint32_t id,
    Estimator* out_estimator) const {
  out_estimator->Clear();

  if (pointer_id_bits_.has_bit(id)) {
    const State& state = mPointerState[id];
    PopulateEstimator(state, out_estimator);
    return true;
  }

  return false;
}

void IntegratingVelocityTrackerStrategy::InitState(State& state,
                                                   const TimeTicks& event_time,
                                                   float xpos,
                                                   float ypos) const {
  state.update_time = event_time;
  state.degree = 0;
  state.xpos = xpos;
  state.xvel = 0;
  state.xaccel = 0;
  state.ypos = ypos;
  state.yvel = 0;
  state.yaccel = 0;
}

void IntegratingVelocityTrackerStrategy::UpdateState(
    State& state,
    const TimeTicks& event_time,
    float xpos,
    float ypos) const {
  const base::TimeDelta MIN_TIME_DELTA = TimeDelta::FromMicroseconds(2);
  const float FILTER_TIME_CONSTANT = 0.010f;  // 10 milliseconds

  if (event_time <= state.update_time + MIN_TIME_DELTA)
    return;

  float dt = static_cast<float>((event_time - state.update_time).InSecondsF());
  state.update_time = event_time;

  float xvel = (xpos - state.xpos) / dt;
  float yvel = (ypos - state.ypos) / dt;
  if (state.degree == 0) {
    state.xvel = xvel;
    state.yvel = yvel;
    state.degree = 1;
  } else {
    float alpha = dt / (FILTER_TIME_CONSTANT + dt);
    if (degree_ == 1) {
      state.xvel += (xvel - state.xvel) * alpha;
      state.yvel += (yvel - state.yvel) * alpha;
    } else {
      float xaccel = (xvel - state.xvel) / dt;
      float yaccel = (yvel - state.yvel) / dt;
      if (state.degree == 1) {
        state.xaccel = xaccel;
        state.yaccel = yaccel;
        state.degree = 2;
      } else {
        state.xaccel += (xaccel - state.xaccel) * alpha;
        state.yaccel += (yaccel - state.yaccel) * alpha;
      }
      state.xvel += (state.xaccel * dt) * alpha;
      state.yvel += (state.yaccel * dt) * alpha;
    }
  }
  state.xpos = xpos;
  state.ypos = ypos;
}

void IntegratingVelocityTrackerStrategy::PopulateEstimator(
    const State& state,
    Estimator* out_estimator) const {
  out_estimator->time = state.update_time;
  out_estimator->confidence = 1.0f;
  out_estimator->degree = state.degree;
  out_estimator->xcoeff[0] = state.xpos;
  out_estimator->xcoeff[1] = state.xvel;
  out_estimator->xcoeff[2] = state.xaccel / 2;
  out_estimator->ycoeff[0] = state.ypos;
  out_estimator->ycoeff[1] = state.yvel;
  out_estimator->ycoeff[2] = state.yaccel / 2;
}

}  // namespace ui
