// 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]) =>
      new 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 = null;
    num maxX = null;
    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;
    this.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;
  Queue<_Move> _moves;
  num _stepTimeout;
  bool _decelerating;
  MomentumDelegate _delegate;
  int _nextY;
  int _nextX;
  Coordinate _minCoord;
  Coordinate _maxCoord;
  num _customDecelerationFactor;
  num _defaultDecelerationFactor;

  TimeoutMomentum(this._delegate, [num defaultDecelerationFactor = 1])
      : _defaultDecelerationFactor = defaultDecelerationFactor,
        _decelerating = false,
        _moves = new Queue<_Move>(),
        physicsX = new SingleDimensionPhysics(),
        physicsY = new 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(new _Move(
            _nextX, _nextY, physicsX.velocity, physicsY.velocity, time));
        _previousOffset.y = _nextY;
        _previousOffset.x = _nextX;
      }
    }
  }

  bool get decelerating => _decelerating;
  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.
   */
  void onTransitionEnd() {}

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

  bool start(Coordinate velocity, Coordinate minCoord, Coordinate maxCoord,
      Coordinate initialOffset,
      [num decelerationFactor = null]) {
    _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.isEmpty) {
        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.isEmpty &&
        !identical(_moves.first, _moves.last) &&
        _moves.first.time < lastEpoch) {
      _moves.removeFirst();
    }

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

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

  Coordinate stop() {
    final wasDecelerating = _decelerating;
    _decelerating = false;
    Coordinate velocity;
    if (!_moves.isEmpty) {
      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 =
          new Coordinate(move.vx / velocityScale, move.vy / velocityScale);
    } else {
      velocity = new Coordinate(0, 0);
    }
    _moves.clear();
    if (_stepTimeout != null) {
      Env.cancelRequestAnimationFrame(_stepTimeout);
      _stepTimeout = null;
    }
    if (wasDecelerating) {
      _delegate.onDecelerationEnd();
    }
    return velocity;
  }

  Coordinate get destination {
    if (!_moves.isEmpty) {
      final lastMove = _moves.last;
      return new Coordinate(lastMove.x, lastMove.y);
    } else {
      return null;
    }
  }
}
