// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// @dart = 2.9

part of touch;

/// Implementations can be used to simulate the deceleration of an element within
/// a certain region. To use this behavior you need to provide an initial
/// velocity that is meant to represent the gesture that is initiating this
/// deceleration. You also provide the bounds of the region that the element
/// exists in, and the current offset of the element within that region. The
/// transitions will have the element decelerate to rest, or stretch past the
/// offset boundaries and then come to rest.
///
/// This is primarily designed to solve the problem of slow scrolling in mobile
/// safari. You can use this along with the [Scroller] behavior to make a
/// scrollable area scroll the same way it would in a native application.
///
/// Implementations of this interface do not maintain any references to HTML
/// elements, and therefore cannot do any redrawing of elements. They only
/// calculates where the element should be on an interval. It is the delegate's
/// responsibility to redraw the element when the onDecelerate callback is
/// invoked. It is recommended that you move the element with a hardware
/// accelerated method such as using 'translate3d' on the element's
/// -webkit-transform style property.
abstract class Momentum {
  factory Momentum(MomentumDelegate delegate,
          [num defaultDecelerationFactor = 1]) =>
      TimeoutMomentum(delegate, defaultDecelerationFactor);

  bool get decelerating;

  num get decelerationFactor;

  /**
  * Transition end handler. This function must be invoked after any transition
  * that occurred as a result of a call to the delegate's onDecelerate callback.
  */
  void onTransitionEnd();

  /// Start decelerating.
  /// The [velocity] passed should be in terms of number of pixels / millisecond.
  /// [minCoord] and [maxCoord] specify the content's scrollable boundary.
  /// The current offset of the element within its boundaries is specified by
  /// [initialOffset].
  /// Returns true if deceleration has been initiated.
  bool start(Coordinate velocity, Coordinate minCoord, Coordinate maxCoord,
      Coordinate initialOffset,
      [num decelerationFactor]);

  /// Calculate the velocity required to transition between coordinates [start]
  /// and [target] optionally specifying a custom [decelerationFactor].
  Coordinate calculateVelocity(Coordinate start, Coordinate target,
      [num decelerationFactor]);

  /// Stop decelerating and return the current velocity. */
  Coordinate stop();

  /// Aborts decelerating without dispatching any notification events. */
  void abort();

  /// null if no transition is in progress. */
  Coordinate get destination;
}

/// Momentum Delegate interface.
/// You are required to implement this interface in order to use the
/// Momentum behavior.
abstract class MomentumDelegate {
  /// Callback for a deceleration step. The delegate is responsible for redrawing
  /// the element in its new position specified in px.
  void onDecelerate(num x, num y);

  /// Callback for end of deceleration.
  void onDecelerationEnd();
}

class BouncingState {
  static const NOT_BOUNCING = 0;
  static const BOUNCING_AWAY = 1;
  static const BOUNCING_BACK = 2;
}

class _Move {
  final num x;
  final num y;
  final num vx;
  final num vy;
  final num time;

  _Move(this.x, this.y, this.vx, this.vy, this.time);
}

/// Secant method root solver helper class.
/// We use http://en.wikipedia.org/wiki/Secant_method
/// falling back to the http://en.wikipedia.org/wiki/Bisection_method
/// if it doesn't appear we are converging properlty.
/// TODO(jacobr): simplify the code so we don't have to use this solver
/// class at all.
class Solver {
  static num solve(num Function(num) fn, num targetY, num startX,
      [int maxIterations = 50]) {
    num lastX = 0;
    num lastY = fn(lastX);
    num deltaX;
    num deltaY;
    num minX;
    num maxX;
    num x = startX;
    num delta = startX;
    for (int i = 0; i < maxIterations; i++) {
      num y = fn(x);
      if (y.round() == targetY.round()) {
        return x;
      }
      if (y > targetY) {
        maxX = x;
      } else {
        minX = x;
      }

      num errorY = targetY - y;
      deltaX = x - lastX;
      deltaY = y - lastY;
      lastX = x;
      lastY = y;
      // Avoid divide by zero and as a hack just repeat the previous delta.
      // Obviously this is a little dangerous and we might not converge.
      if (deltaY != 0) {
        delta = errorY * deltaX / deltaY;
      }
      x += delta;
      if (minX != null && maxX != null && (x > minX || x < maxX)) {
        // Fall back to binary search.
        x = (minX + maxX) / 2;
      }
    }
    window.console.warn('''Could not find an exact solution. LastY=$lastY,
        targetY=$targetY lastX=$lastX delta=$delta  deltaX=$deltaX
        deltaY=$deltaY''');
    return x;
  }
}

/// Helper class modeling the physics of a throwable scrollable area along a
/// single dimension.
class SingleDimensionPhysics {
  /// The number of frames per second the animation should run at. */
  static const _FRAMES_PER_SECOND = 60;

  /// The spring coefficient for when the element has passed a boundary and is
  /// decelerating to change direction and bounce back. Each frame, the velocity
  /// will be changed by x times this coefficient, where x is the current stretch
  /// value of the element from its boundary. This will end when velocity reaches
  /// zero.
  static const _PRE_BOUNCE_COEFFICIENT = 7.0 / _FRAMES_PER_SECOND;

  /// The spring coefficient for when the element is bouncing back from a
  /// stretched offset to a min or max position. Each frame, the velocity will
  /// be changed to x times this coefficient, where x is the current stretch
  /// value of the element from its boundary. This will end when the stretch
  /// value reaches 0.
  static const _POST_BOUNCE_COEFFICIENT = 7.0 / _FRAMES_PER_SECOND;

  /// The number of milliseconds per animation frame.
  static const _MS_PER_FRAME = 1000.0 / _FRAMES_PER_SECOND;

  /// The constant factor applied to velocity at each frame to simulate
  /// deceleration.
  static const _DECELERATION_FACTOR = 0.97;

  static const _MAX_VELOCITY_STATIC_FRICTION = 0.08 * _MS_PER_FRAME;
  static const _DECELERATION_FACTOR_STATIC_FRICTION = 0.92;

  /// Minimum velocity required to start or continue deceleration, in
  /// pixels/frame. This is equivalent to 0.25 px/ms.
  static const _MIN_VELOCITY = 0.25 * _MS_PER_FRAME;

  /// Minimum velocity during a step, in pixels/frame. This is equivalent to 0.01
  /// px/ms.
  static const _MIN_STEP_VELOCITY = 0.01 * _MS_PER_FRAME;

  /// Boost the initial velocity by a certain factor before applying momentum.
  /// This just gives the momentum a better feel.
  static const _INITIAL_VELOCITY_BOOST_FACTOR = 1.25;

  /// Additional deceleration factor to apply for the current move only.  This
  /// is helpful for cases such as scroll wheel scrolling where the default
  /// amount of deceleration is inadequate.
  num customDecelerationFactor = 1;
  num _minCoord;
  num _maxCoord;

  /// The bouncing state. */
  int _bouncingState;

  num velocity;
  num _currentOffset;

  /// constant used when guessing at the velocity required to throw to a specific
  /// location. Chosen arbitrarily. All that really matters is that the velocity
  /// is large enough that a throw gesture will occur.
  static const _VELOCITY_GUESS = 20;

  SingleDimensionPhysics() : _bouncingState = BouncingState.NOT_BOUNCING;

  void configure(num minCoord, num maxCoord, num initialOffset,
      num customDecelerationFactor_, num velocity_) {
    _bouncingState = BouncingState.NOT_BOUNCING;
    _minCoord = minCoord;
    _maxCoord = maxCoord;
    _currentOffset = initialOffset;
    customDecelerationFactor = customDecelerationFactor_;
    _adjustInitialVelocityAndBouncingState(velocity_);
  }

  num solve(
      num initialOffset, num targetOffset, num customDecelerationFactor_) {
    initialOffset = initialOffset.round();
    targetOffset = targetOffset.round();
    if (initialOffset == targetOffset) {
      return 0;
    }
    return Solver.solve((num velocity_) {
      // Don't specify min and max coordinates as we don't need to bother
      // with the simulating bouncing off the edges.
      configure(null, null, initialOffset.round(), customDecelerationFactor_,
          velocity_);
      stepAll();
      return _currentOffset;
    }, targetOffset,
        targetOffset > initialOffset ? _VELOCITY_GUESS : -_VELOCITY_GUESS);
  }

  /// Helper method to calculate initial velocity.
  /// The [velocity] passed here should be in terms of number of
  /// pixels / millisecond. Returns the adjusted x and y velocities.
  void _adjustInitialVelocityAndBouncingState(num v) {
    velocity = v * _MS_PER_FRAME * _INITIAL_VELOCITY_BOOST_FACTOR;

    if (velocity.abs() < _MIN_VELOCITY) {
      if (_minCoord != null && _currentOffset < _minCoord) {
        velocity = (_minCoord - _currentOffset) * _POST_BOUNCE_COEFFICIENT;
        velocity = Math.max(velocity, _MIN_STEP_VELOCITY);
        _bouncingState = BouncingState.BOUNCING_BACK;
      } else if (_maxCoord != null && _currentOffset > _maxCoord) {
        velocity = (_currentOffset - _maxCoord) * _POST_BOUNCE_COEFFICIENT;
        velocity = -Math.max(velocity, _MIN_STEP_VELOCITY);
        _bouncingState = BouncingState.BOUNCING_BACK;
      }
    }
  }

  /// Apply deceleration.
  void _adjustVelocity() {
    num speed = velocity.abs();
    velocity *= _DECELERATION_FACTOR;
    if (customDecelerationFactor != null) {
      velocity *= customDecelerationFactor;
    }
    // This isn't really how static friction works but it is a plausible
    // approximation.
    if (speed < _MAX_VELOCITY_STATIC_FRICTION) {
      velocity *= _DECELERATION_FACTOR_STATIC_FRICTION;
    }

    num stretchDistance;
    if (_minCoord != null && _currentOffset < _minCoord) {
      stretchDistance = _minCoord - _currentOffset;
    } else {
      if (_maxCoord != null && _currentOffset > _maxCoord) {
        stretchDistance = _maxCoord - _currentOffset;
      }
    }
    if (stretchDistance != null) {
      if (stretchDistance * velocity < 0) {
        _bouncingState = _bouncingState == BouncingState.BOUNCING_BACK
            ? BouncingState.NOT_BOUNCING
            : BouncingState.BOUNCING_AWAY;
        velocity += stretchDistance * _PRE_BOUNCE_COEFFICIENT;
      } else {
        _bouncingState = BouncingState.BOUNCING_BACK;
        velocity = stretchDistance > 0
            ? Math.max(
                stretchDistance * _POST_BOUNCE_COEFFICIENT, _MIN_STEP_VELOCITY)
            : Math.min(stretchDistance * _POST_BOUNCE_COEFFICIENT,
                -_MIN_STEP_VELOCITY);
      }
    } else {
      _bouncingState = BouncingState.NOT_BOUNCING;
    }
  }

  void step() {
    // It is common for scrolling to be disabled so in these cases we want to
    // avoid needless calculations.
    if (velocity != null) {
      _currentOffset += velocity;
      _adjustVelocity();
    }
  }

  void stepAll() {
    while (!isDone()) {
      step();
    }
  }

  /// Whether or not the current velocity is above the threshold required to
  /// continue decelerating.
  bool isVelocityAboveThreshold(num threshold) {
    return velocity.abs() >= threshold;
  }

  bool isDone() {
    return _bouncingState == BouncingState.NOT_BOUNCING &&
        !isVelocityAboveThreshold(_MIN_STEP_VELOCITY);
  }
}

/// Implementation of a momentum strategy using webkit-transforms
/// and timeouts.
class TimeoutMomentum implements Momentum {
  SingleDimensionPhysics physicsX;
  SingleDimensionPhysics physicsY;
  Coordinate _previousOffset;
  final Queue<_Move> _moves;
  num _stepTimeout;
  bool _decelerating;
  final MomentumDelegate _delegate;
  int _nextY;
  int _nextX;
  Coordinate _minCoord;
  Coordinate _maxCoord;
  num _customDecelerationFactor;
  final num _defaultDecelerationFactor;

  TimeoutMomentum(this._delegate, [num defaultDecelerationFactor = 1])
      : _defaultDecelerationFactor = defaultDecelerationFactor,
        _decelerating = false,
        _moves = Queue<_Move>(),
        physicsX = SingleDimensionPhysics(),
        physicsY = SingleDimensionPhysics();

  /// Calculate and return the moves for the deceleration motion.
  void _calculateMoves() {
    _moves.clear();
    num time = TimeUtil.now();
    while (!physicsX.isDone() || !physicsY.isDone()) {
      _stepWithoutAnimation();
      time += SingleDimensionPhysics._MS_PER_FRAME;
      if (_isStepNecessary()) {
        _moves.add(
            _Move(_nextX, _nextY, physicsX.velocity, physicsY.velocity, time));
        _previousOffset.y = _nextY;
        _previousOffset.x = _nextX;
      }
    }
  }

  @override
  bool get decelerating => _decelerating;
  @override
  num get decelerationFactor => _customDecelerationFactor;

  /// Checks whether or not an animation step is necessary or not. Animations
  /// steps are not necessary when the velocity gets so low that in several
  /// frames the offset is the same.
  /// Returns true if there is movement to be done in the next frame.
  bool _isStepNecessary() {
    return _nextY != _previousOffset.y || _nextX != _previousOffset.x;
  }

  /// The [TouchHandler] requires this function but we don't need to do
  /// anything here.
  @override
  void onTransitionEnd() {}

  @override
  Coordinate calculateVelocity(Coordinate start_, Coordinate target,
      [num decelerationFactor]) {
    return Coordinate(physicsX.solve(start_.x, target.x, decelerationFactor),
        physicsY.solve(start_.y, target.y, decelerationFactor));
  }

  @override
  bool start(Coordinate velocity, Coordinate minCoord, Coordinate maxCoord,
      Coordinate initialOffset,
      [num decelerationFactor]) {
    _customDecelerationFactor = _defaultDecelerationFactor;
    if (decelerationFactor != null) {
      _customDecelerationFactor = decelerationFactor;
    }

    if (_stepTimeout != null) {
      Env.cancelRequestAnimationFrame(_stepTimeout);
      _stepTimeout = null;
    }

    assert(_stepTimeout == null);
    assert(minCoord.x <= maxCoord.x);
    assert(minCoord.y <= maxCoord.y);
    _previousOffset = initialOffset.clone();
    physicsX.configure(minCoord.x, maxCoord.x, initialOffset.x,
        _customDecelerationFactor, velocity.x);
    physicsY.configure(minCoord.y, maxCoord.y, initialOffset.y,
        _customDecelerationFactor, velocity.y);
    if (!physicsX.isDone() || !physicsY.isDone()) {
      _calculateMoves();
      if (_moves.isNotEmpty) {
        num firstTime = _moves.first.time;
        _stepTimeout = Env.requestAnimationFrame(_step, null, firstTime);
        _decelerating = true;
        return true;
      }
    }
    _decelerating = false;
    return false;
  }

  /// Update the x, y values of the element offset without actually moving the
  /// element. This is done because we store decimal values for x, y for
  /// precision, but moving is only required when the offset is changed by at
  /// least a whole integer.
  void _stepWithoutAnimation() {
    physicsX.step();
    physicsY.step();
    _nextX = physicsX._currentOffset.round();
    _nextY = physicsY._currentOffset.round();
  }

  /// Calculate the next offset of the element and animate it to that position.
  void _step(num timestamp) {
    _stepTimeout = null;

    // Prune moves that are more than 1 frame behind when we have more
    // available moves.
    num lastEpoch = timestamp - SingleDimensionPhysics._MS_PER_FRAME;
    while (_moves.isNotEmpty &&
        !identical(_moves.first, _moves.last) &&
        _moves.first.time < lastEpoch) {
      _moves.removeFirst();
    }

    if (_moves.isNotEmpty) {
      final move = _moves.removeFirst();
      _delegate.onDecelerate(move.x, move.y);
      if (_moves.isNotEmpty) {
        num nextTime = _moves.first.time;
        assert(_stepTimeout == null);
        _stepTimeout = Env.requestAnimationFrame(_step, null, nextTime);
      } else {
        stop();
      }
    }
  }

  @override
  void abort() {
    _decelerating = false;
    _moves.clear();
    if (_stepTimeout != null) {
      Env.cancelRequestAnimationFrame(_stepTimeout);
      _stepTimeout = null;
    }
  }

  @override
  Coordinate stop() {
    final wasDecelerating = _decelerating;
    _decelerating = false;
    Coordinate velocity;
    if (_moves.isNotEmpty) {
      final move = _moves.first;
      // This is a workaround for the ugly hacks that get applied when a user
      // passed a velocity in to this Momentum implementation.
      num velocityScale = SingleDimensionPhysics._MS_PER_FRAME *
          SingleDimensionPhysics._INITIAL_VELOCITY_BOOST_FACTOR;
      velocity = Coordinate(move.vx / velocityScale, move.vy / velocityScale);
    } else {
      velocity = Coordinate(0, 0);
    }
    _moves.clear();
    if (_stepTimeout != null) {
      Env.cancelRequestAnimationFrame(_stepTimeout);
      _stepTimeout = null;
    }
    if (wasDecelerating) {
      _delegate.onDecelerationEnd();
    }
    return velocity;
  }

  @override
  Coordinate get destination {
    if (_moves.isNotEmpty) {
      final lastMove = _moves.last;
      return Coordinate(lastMove.x, lastMove.y);
    } else {
      return null;
    }
  }
}
