// 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 'package:flutter/foundation.dart';

import 'events.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 {
  /// Create a new velocity tracker for a pointer [kind].
  @Deprecated(
    'Use VelocityTracker.withKind and provide the PointerDeviceKind associated with the gesture being tracked. '
    'This feature was deprecated after v1.22.0-12.1.pre.'
  )
  VelocityTracker([this.kind = PointerDeviceKind.touch]);

  /// Create a new velocity tracker for a pointer [kind].
  VelocityTracker.withKind(this.kind);

  static const int _assumePointerMoveStoppedMilliseconds = 40;
  static const int _historySize = 20;
  static const int _horizonMilliseconds = 100;
  static const int _minSampleSize = 3;

  /// The kind of pointer this tracker is for.
  final PointerDeviceKind kind;

  // 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
/// estimated 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 {
  /// Create a new IOSScrollViewFlingVelocityTracker.
  IOSScrollViewFlingVelocityTracker(PointerDeviceKind kind) : super.withKind(kind);

  /// 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,
      );
    }
  }
}
