// 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:math' as math;

import 'simulation.dart';
import 'tolerance.dart';

/// A simulation that applies a drag to slow a particle down.
///
/// Models a particle affected by fluid drag, e.g. air resistance.
///
/// The simulation ends when the velocity of the particle drops to zero (within
/// the current velocity [tolerance]).
class FrictionSimulation extends Simulation {
  /// Creates a [FrictionSimulation] with the given arguments, namely: the fluid
  /// drag coefficient, a unitless value; the initial position, in the same
  /// length units as used for [x]; and the initial velocity, in the same
  /// velocity units as used for [dx].
  FrictionSimulation(
    double drag,
    double position,
    double velocity, {
    Tolerance tolerance = Tolerance.defaultTolerance,
  }) : _drag = drag,
       _dragLog = math.log(drag),
       _x = position,
       _v = velocity,
       super(tolerance: tolerance);

  /// Creates a new friction simulation with its fluid drag coefficient set so
  /// as to ensure that the simulation starts and ends at the specified
  /// positions and velocities.
  ///
  /// The positions must use the same units as expected from [x], and the
  /// velocities must use the same units as expected from [dx].
  ///
  /// The sign of the start and end velocities must be the same, the magnitude
  /// of the start velocity must be greater than the magnitude of the end
  /// velocity, and the velocities must be in the direction appropriate for the
  /// particle to start from the start position and reach the end position.
  factory FrictionSimulation.through(double startPosition, double endPosition, double startVelocity, double endVelocity) {
    assert(startVelocity == 0.0 || endVelocity == 0.0 || startVelocity.sign == endVelocity.sign);
    assert(startVelocity.abs() >= endVelocity.abs());
    assert((endPosition - startPosition).sign == startVelocity.sign);
    return FrictionSimulation(
      _dragFor(startPosition, endPosition, startVelocity, endVelocity),
      startPosition,
      startVelocity,
      tolerance: Tolerance(velocity: endVelocity.abs()),
    );
  }

  final double _drag;
  final double _dragLog;
  final double _x;
  final double _v;

  // Return the drag value for a FrictionSimulation whose x() and dx() values pass
  // through the specified start and end position/velocity values.
  //
  // Total time to reach endVelocity is just: (log(endVelocity) / log(startVelocity)) / log(_drag)
  // or (log(v1) - log(v0)) / log(D), given v = v0 * D^t per the dx() function below.
  // Solving for D given x(time) is trickier. Algebra courtesy of Wolfram Alpha:
  // x1 = x0 + (v0 * D^((log(v1) - log(v0)) / log(D))) / log(D) - v0 / log(D), find D
  static double _dragFor(double startPosition, double endPosition, double startVelocity, double endVelocity) {
    return math.pow(math.e, (startVelocity - endVelocity) / (startPosition - endPosition)) as double;
  }

  @override
  double x(double time) => _x + _v * math.pow(_drag, time) / _dragLog - _v / _dragLog;

  @override
  double dx(double time) => _v * math.pow(_drag, time);

  /// The value of [x] at `double.infinity`.
  double get finalX => _x - _v / _dragLog;

  /// The time at which the value of `x(time)` will equal [x].
  ///
  /// Returns `double.infinity` if the simulation will never reach [x].
  double timeAtX(double x) {
    if (x == _x)
      return 0.0;
    if (_v == 0.0 || (_v > 0 ? (x < _x || x > finalX) : (x > _x || x < finalX)))
      return double.infinity;
    return math.log(_dragLog * (x - _x) / _v + 1.0) / _dragLog;
  }

  @override
  bool isDone(double time) => dx(time).abs() < tolerance.velocity;
}

/// A [FrictionSimulation] that clamps the modeled particle to a specific range
/// of values.
class BoundedFrictionSimulation extends FrictionSimulation {
  /// Creates a [BoundedFrictionSimulation] with the given arguments, namely:
  /// the fluid drag coefficient, a unitless value; the initial position, in the
  /// same length units as used for [x]; the initial velocity, in the same
  /// velocity units as used for [dx], the minimum value for the position, and
  /// the maximum value for the position. The minimum and maximum values must be
  /// in the same units as the initial position, and the initial position must
  /// be within the given range.
  BoundedFrictionSimulation(
    double drag,
    double position,
    double velocity,
    this._minX,
    this._maxX,
  ) : assert(position.clamp(_minX, _maxX) == position),
      super(drag, position, velocity);

  final double _minX;
  final double _maxX;

  @override
  double x(double time) {
    return super.x(time).clamp(_minX, _maxX);
  }

  @override
  bool isDone(double time) {
    return super.isDone(time) ||
      (x(time) - _minX).abs() < tolerance.distance ||
      (x(time) - _maxX).abs() < tolerance.distance;
  }
}
