// 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 'simulation.dart';

// Examples can assume:
// late AnimationController _controller;

/// A simulation that applies a constant accelerating force.
///
/// Models a particle that follows Newton's second law of motion. The simulation
/// ends when the position exceeds a defined threshold.
///
/// {@tool snippet}
///
/// This method triggers an [AnimationController] (a previously constructed
/// `_controller` field) to simulate a fall of 300 pixels.
///
/// ```dart
/// void _startFall() {
///   _controller.animateWith(GravitySimulation(
///     10.0, // acceleration, pixels per second per second
///     0.0, // starting position, pixels
///     300.0, // ending position, pixels
///     0.0, // starting velocity, pixels per second
///   ));
/// }
/// ```
/// {@end-tool}
///
/// This [AnimationController] could be used with an [AnimatedBuilder] to
/// animate the position of a child as if it was falling.
///
/// The end distance threshold (the constructor's third argument) must be
/// specified as a positive number but can be reached in either the positive or
/// negative direction. For example (assuming negative numbers represent higher
/// physical positions than positive numbers, as is the case with the normal
/// [Canvas] coordinate system), if the acceleration is positive ("down") the
/// starting velocity is negative ("up"), and the starting distance is zero, the
/// particle will climb from the origin, reach a plateau, then fall back towards
/// and past the origin. If the end distance threshold is less than the height
/// of the plateau, then the simulation will end during the climb; otherwise, it
/// will end during the fall, after the particle travels below the origin by
/// that distance.
///
/// See also:
///
///  * [Curves.bounceOut], a [Curve] that has a similar aesthetics but includes
///    a bouncing effect.
class GravitySimulation extends Simulation {
  /// Creates a [GravitySimulation] using the given arguments, which are,
  /// respectively: an acceleration that is to be applied continually over time;
  /// an initial position relative to an origin; the magnitude of the distance
  /// from that origin beyond which (in either direction) to consider the
  /// simulation to be "done", which must be positive; and an initial velocity.
  ///
  /// The initial position and maximum distance are measured in arbitrary length
  /// units L from an arbitrary origin. The units will match those used for [x].
  ///
  /// The time unit T used for the arguments to [x], [dx], and [isDone],
  /// combined with the aforementioned length unit, together determine the units
  /// that must be used for the velocity and acceleration arguments: L/T and
  /// L/T² respectively. The same units of velocity are used for the velocity
  /// obtained from [dx].
  GravitySimulation(
    double acceleration,
    double distance,
    double endDistance,
    double velocity,
  ) : assert(acceleration != null),
      assert(distance != null),
      assert(velocity != null),
      assert(endDistance != null),
      assert(endDistance >= 0),
      _a = acceleration,
      _x = distance,
      _v = velocity,
      _end = endDistance;

  final double _x;
  final double _v;
  final double _a;
  final double _end;

  @override
  double x(double time) => _x + _v * time + 0.5 * _a * time * time;

  @override
  double dx(double time) => _v + time * _a;

  @override
  bool isDone(double time) => x(time).abs() >= _end;

  @override
  String toString() => '${objectRuntimeType(this, 'GravitySimulation')}(g: ${_a.toStringAsFixed(1)}, x₀: ${_x.toStringAsFixed(1)}, dx₀: ${_v.toStringAsFixed(1)}, xₘₐₓ: ±${_end.toStringAsFixed(1)})';
}
