// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


import 'dart:ui' show Offset;

import 'package:flutter/foundation.dart';

import 'lsq_solver.dart';

export 'dart:ui' show Offset;

/// A velocity in two dimensions.
@immutable
class Velocity {
  /// Creates a velocity.
  ///
  /// The [pixelsPerSecond] argument must not be null.
  const Velocity({
    required this.pixelsPerSecond,
  }) : assert(pixelsPerSecond != null);

  /// A velocity that isn't moving at all.
  static const Velocity zero = Velocity(pixelsPerSecond: Offset.zero);

  /// The number of pixels per second of velocity in the x and y directions.
  final Offset pixelsPerSecond;

  /// Return the negation of a velocity.
  Velocity operator -() => Velocity(pixelsPerSecond: -pixelsPerSecond);

  /// Return the difference of two velocities.
  Velocity operator -(Velocity other) {
    return Velocity(
        pixelsPerSecond: pixelsPerSecond - other.pixelsPerSecond);
  }

  /// Return the sum of two velocities.
  Velocity operator +(Velocity other) {
    return Velocity(
        pixelsPerSecond: pixelsPerSecond + other.pixelsPerSecond);
  }

  /// Return a velocity whose magnitude has been clamped to [minValue]
  /// and [maxValue].
  ///
  /// If the magnitude of this Velocity is less than minValue then return a new
  /// Velocity with the same direction and with magnitude [minValue]. Similarly,
  /// if the magnitude of this Velocity is greater than maxValue then return a
  /// new Velocity with the same direction and magnitude [maxValue].
  ///
  /// If the magnitude of this Velocity is within the specified bounds then
  /// just return this.
  Velocity clampMagnitude(double minValue, double maxValue) {
    assert(minValue != null && minValue >= 0.0);
    assert(maxValue != null && maxValue >= 0.0 && maxValue >= minValue);
    final double valueSquared = pixelsPerSecond.distanceSquared;
    if (valueSquared > maxValue * maxValue)
      return Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * maxValue);
    if (valueSquared < minValue * minValue)
      return Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * minValue);
    return this;
  }

  @override
  bool operator ==(Object other) {
    return other is Velocity
        && other.pixelsPerSecond == pixelsPerSecond;
  }

  @override
  int get hashCode => pixelsPerSecond.hashCode;

  @override
  String toString() => 'Velocity(${pixelsPerSecond.dx.toStringAsFixed(1)}, ${pixelsPerSecond.dy.toStringAsFixed(1)})';
}

/// A two dimensional velocity estimate.
///
/// VelocityEstimates are computed by [VelocityTracker.getVelocityEstimate]. An
/// estimate's [confidence] measures how well the velocity tracker's position
/// data fit a straight line, [duration] is the time that elapsed between the
/// first and last position sample used to compute the velocity, and [offset]
/// is similarly the difference between the first and last positions.
///
/// See also:
///
///  * [VelocityTracker], which computes [VelocityEstimate]s.
///  * [Velocity], which encapsulates (just) a velocity vector and provides some
///    useful velocity operations.
class VelocityEstimate {
  /// Creates a dimensional velocity estimate.
  ///
  /// [pixelsPerSecond], [confidence], [duration], and [offset] must not be null.
  const VelocityEstimate({
    required this.pixelsPerSecond,
    required this.confidence,
    required this.duration,
    required this.offset,
  }) : assert(pixelsPerSecond != null),
       assert(confidence != null),
       assert(duration != null),
       assert(offset != null);

  /// The number of pixels per second of velocity in the x and y directions.
  final Offset pixelsPerSecond;

  /// A value between 0.0 and 1.0 that indicates how well [VelocityTracker]
  /// was able to fit a straight line to its position data.
  ///
  /// The value of this property is 1.0 for a perfect fit, 0.0 for a poor fit.
  final double confidence;

  /// The time that elapsed between the first and last position sample used
  /// to compute [pixelsPerSecond].
  final Duration duration;

  /// The difference between the first and last position sample used
  /// to compute [pixelsPerSecond].
  final Offset offset;

  @override
  String toString() => 'VelocityEstimate(${pixelsPerSecond.dx.toStringAsFixed(1)}, ${pixelsPerSecond.dy.toStringAsFixed(1)}; offset: $offset, duration: $duration, confidence: ${confidence.toStringAsFixed(1)})';
}

class _PointAtTime {
  const _PointAtTime(this.point, this.time)
    : assert(point != null),
      assert(time != null);

  final Duration time;
  final Offset point;

  @override
  String toString() => '_PointAtTime($point at $time)';
}

/// Computes a pointer's velocity based on data from [PointerMoveEvent]s.
///
/// The input data is provided by calling [addPosition]. Adding data is cheap.
///
/// To obtain a velocity, call [getVelocity] or [getVelocityEstimate]. This will
/// compute the velocity based on the data added so far. Only call these when
/// you need to use the velocity, as they are comparatively expensive.
///
/// The quality of the velocity estimation will be better if more data points
/// have been received.
class VelocityTracker {
  static const int _assumePointerMoveStoppedMilliseconds = 40;
  static const int _historySize = 20;
  static const int _horizonMilliseconds = 100;
  static const int _minSampleSize = 3;

  // Circular buffer; current sample at _index.
  final List<_PointAtTime?> _samples = List<_PointAtTime?>.filled(_historySize, null, growable: false);
  int _index = 0;

  /// Adds a position as the given time to the tracker.
  void addPosition(Duration time, Offset position) {
    _index += 1;
    if (_index == _historySize)
      _index = 0;
    _samples[_index] = _PointAtTime(position, time);
  }

  /// Returns an estimate of the velocity of the object being tracked by the
  /// tracker given the current information available to the tracker.
  ///
  /// Information is added using [addPosition].
  ///
  /// Returns null if there is no data on which to base an estimate.
  VelocityEstimate? getVelocityEstimate() {
    final List<double> x = <double>[];
    final List<double> y = <double>[];
    final List<double> w = <double>[];
    final List<double> time = <double>[];
    int sampleCount = 0;
    int index = _index;

    final _PointAtTime? newestSample = _samples[index];
    if (newestSample == null)
      return null;

    _PointAtTime previousSample = newestSample;
    _PointAtTime oldestSample = newestSample;

    // Starting with the most recent PointAtTime sample, iterate backwards while
    // the samples represent continuous motion.
    do {
      final _PointAtTime? sample = _samples[index];
      if (sample == null)
        break;

      final double age = (newestSample.time - sample.time).inMicroseconds.toDouble() / 1000;
      final double delta = (sample.time - previousSample.time).inMicroseconds.abs().toDouble() / 1000;
      previousSample = sample;
      if (age > _horizonMilliseconds || delta > _assumePointerMoveStoppedMilliseconds)
        break;

      oldestSample = sample;
      final Offset position = sample.point;
      x.add(position.dx);
      y.add(position.dy);
      w.add(1.0);
      time.add(-age);
      index = (index == 0 ? _historySize : index) - 1;

      sampleCount += 1;
    } while (sampleCount < _historySize);

    if (sampleCount >= _minSampleSize) {
      final LeastSquaresSolver xSolver = LeastSquaresSolver(time, x, w);
      final PolynomialFit? xFit = xSolver.solve(2);
      if (xFit != null) {
        final LeastSquaresSolver ySolver = LeastSquaresSolver(time, y, w);
        final PolynomialFit? yFit = ySolver.solve(2);
        if (yFit != null) {
          return VelocityEstimate( // convert from pixels/ms to pixels/s
            pixelsPerSecond: Offset(xFit.coefficients[1] * 1000, yFit.coefficients[1] * 1000),
            confidence: xFit.confidence * yFit.confidence,
            duration: newestSample.time - oldestSample.time,
            offset: newestSample.point - oldestSample.point,
          );
        }
      }
    }

    // We're unable to make a velocity estimate but we did have at least one
    // valid pointer position.
    return VelocityEstimate(
      pixelsPerSecond: Offset.zero,
      confidence: 1.0,
      duration: newestSample.time - oldestSample.time,
      offset: newestSample.point - oldestSample.point,
    );
  }

  /// Computes the velocity of the pointer at the time of the last
  /// provided data point.
  ///
  /// This can be expensive. Only call this when you need the velocity.
  ///
  /// Returns [Velocity.zero] if there is no data from which to compute an
  /// estimate or if the estimated velocity is zero.
  Velocity getVelocity() {
    final VelocityEstimate? estimate = getVelocityEstimate();
    if (estimate == null || estimate.pixelsPerSecond == Offset.zero)
      return Velocity.zero;
    return Velocity(pixelsPerSecond: estimate.pixelsPerSecond);
  }
}

/// A [VelocityTracker] subclass that provides a close approximation of iOS
/// scroll view's velocity estimation strategy.
///
/// The estimated velocity reported by this class is a close approximation of
/// the velocity an iOS scroll view would report with the same
/// [PointerMoveEvent]s, when the touch that initiates a fling is released.
///
/// This class differs from the [VelocityTracker] class in that it uses weighted
/// average of the latest few velocity samples of the tracked pointer, instead
/// of doing a linear regression on a relatively large amount of data points, to
/// estimate the velocity of the tracked pointer. Adding data points and
/// estimating the velocity are both cheap.
///
/// To obtain a velocity, call [getVelocity] or [getVelocityEstimate]. The
/// esimated velocity is typically used as the initial flinging velocity of a
/// `Scrollable`, when its drag gesture ends.
///
/// See also:
///
/// * [scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)](https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619385-scrollviewwillenddragging),
///   the iOS method that reports the fling velocity when the touch is released.
class IOSScrollViewFlingVelocityTracker extends VelocityTracker {
  /// The velocity estimation uses at most 4 `_PointAtTime` samples. The extra
  /// samples are there to make the `VelocityEstimate.offset` sufficiently large
  /// to be recognized as a fling. See
  /// `VerticalDragGestureRecognizer.isFlingGesture`.
  static const int _sampleSize = 20;

  final List<_PointAtTime?> _touchSamples = List<_PointAtTime?>.filled(_sampleSize, null, growable: false);

  @override
  void addPosition(Duration time, Offset position) {
    assert(() {
      final _PointAtTime? previousPoint = _touchSamples[_index];
      if (previousPoint == null || previousPoint.time <= time)
        return true;
      throw FlutterError(
        'The position being added ($position) has a smaller timestamp ($time)'
        'than its predecessor: $previousPoint.'
      );
    }());
    _index = (_index + 1) % _sampleSize;
    _touchSamples[_index] = _PointAtTime(position, time);
  }

  // Computes the velocity using 2 adjacent points in history. When index = 0,
  // it uses the latest point recorded and the point recorded immediately before
  // it. The smaller index is, the ealier in history the points used are.
  Offset _previousVelocityAt(int index) {
    final int endIndex = (_index + index) % _sampleSize;
    final int startIndex = (_index + index - 1) % _sampleSize;
    final _PointAtTime? end = _touchSamples[endIndex];
    final _PointAtTime? start = _touchSamples[startIndex];

    if (end == null || start == null) {
      return Offset.zero;
    }

    final int dt = (end.time - start.time).inMicroseconds;
    assert(dt >= 0);

    return dt > 0
      // Convert dt to milliseconds to preserve floating point precision.
      ? (end.point - start.point) * 1000 / (dt.toDouble() / 1000)
      : Offset.zero;
  }

  @override
  VelocityEstimate getVelocityEstimate() {
    // The velocity estimated using this expression is an aproximation of the
    // scroll velocity of an iOS scroll view at the moment the user touch was
    // released, not the final velocity of the iOS pan gesture recognizer
    // installed on the scroll view would report. Typically in an iOS scroll
    // view the velocity values are different between the two, because the
    // scroll view usually slows down when the touch is released.
    final Offset estimatedVelocity = _previousVelocityAt(-2) * 0.6
                                   + _previousVelocityAt(-1) * 0.35
                                   + _previousVelocityAt(0) * 0.05;

    final _PointAtTime? newestSample = _touchSamples[_index];
    _PointAtTime? oldestNonNullSample;

    for (int i = 1; i <= _sampleSize; i += 1) {
      oldestNonNullSample = _touchSamples[(_index + i) % _sampleSize];
      if (oldestNonNullSample != null)
        break;
    }

    if (oldestNonNullSample == null || newestSample == null) {
      assert(false, 'There must be at least 1 point in _touchSamples: $_touchSamples');
      return const VelocityEstimate(
        pixelsPerSecond: Offset.zero,
        confidence: 0.0,
        duration: Duration.zero,
        offset: Offset.zero,
      );
    } else {
      return VelocityEstimate(
        pixelsPerSecond: estimatedVelocity,
        confidence: 1.0,
        duration: newestSample.time - oldestNonNullSample.time,
        offset: newestSample.point - oldestNonNullSample.point,
      );
    }
  }
}
