// 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;

/**
 * Touch Handler. Class that handles all touch events and
 * uses them to interpret higher level gestures and behaviors. TouchEvent is a
 * built in mobile safari type:
 * [http://developer.apple.com/safari/library/documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html].
 *
 * Examples of higher level gestures this class is intended to support
 * - click, double click, long click
 * - dragging, swiping, zooming
 *
 * Touch Behavior:
 *      Use this class to make your elements 'touchable' (see Touchable.dart).
 *      Intended to work with all webkit browsers.
 *
 * Drag Behavior:
 *      Use this class to make your elements 'draggable' (see draggable.js).
 *      This behavior will handle all of the required events and report the
 *      properties of the drag to you while the touch is happening and at the
 *      end of the drag sequence. This behavior will NOT perform the actual
 *      dragging (redrawing the element) for you, this responsibility is left to
 *      the client code. This behavior contains a work around for a mobile
 *      safari bug where the 'touchend' event is not dispatched when the touch
 *      goes past the bottom of the browser window.
 *      This is intended to work well in iframes.
 *      Intended to work with all webkit browsers, tested only on iPhone 3.x so
 *      far.
 *
 * Click Behavior:
 *      Not yet implemented.
 *
 * Zoom Behavior:
 *      Not yet implemented.
 *
 * Swipe Behavior:
 *      Not yet implemented.
 */
class TouchHandler {
  Touchable _touchable;
  Element _element;

  /** The absolute sum of all touch y deltas. */
  int _totalMoveY;

  /** The absolute sum of all touch x deltas. */
  int _totalMoveX;

  /**
   * A list of tuples where the first item is the horizontal component of a
   * recent relevant touch and the second item is the touch's time stamp. Old
   * touches are removed based on the max tracking time and when direction
   * changes.
   */
  List<int> _recentTouchesX;

  /**
   * A list of tuples where the first item is the vertical component of a
   * recent relevant touch and the second item is the touch's time stamp. Old
   * touches are removed based on the max tracking time and when direction
   * changes.
   */
  List<int> _recentTouchesY;

  // TODO(jacobr): make customizable by passing optional parameters to the
  // TouchHandler constructor.
  /**
   * Minimum movement of touch required to be considered a drag.
   */
  static const _MIN_TRACKING_FOR_DRAG = 2;

  /**
   * The maximum number of ms to track a touch event. After an event is older
   * than this value, it will be ignored in velocity calculations.
   */
  static const _MAX_TRACKING_TIME = 250;

  /** The maximum number of touches to track. */
  static const _MAX_TRACKING_TOUCHES = 5;

  /**
   * The maximum velocity to return, in pixels per millisecond, that is used to
   * guard against errors in calculating end velocity of a drag. This is a very
   * fast drag velocity.
   */
  static const _MAXIMUM_VELOCITY = 5;

  /**
   * The velocity to return, in pixel per millisecond, when the time stamps on
   * the events are erroneous. The browser can return bad time stamps if the
   * thread is blocked for the duration of the drag. This is a low velocity to
   * prevent the content from moving quickly after a slow drag. It is less
   * jarring if the content moves slowly after a fast drag.
   */
  static const _VELOCITY_FOR_INCORRECT_EVENTS = 1;

  Draggable _draggable;
  bool _tracking;
  bool _dragging;
  bool _touching;
  int _startTouchX;
  int _startTouchY;
  int _startTime;
  TouchEvent _lastEvent;
  int _lastTouchX;
  int _lastTouchY;
  int _lastMoveX;
  int _lastMoveY;
  int _endTime;
  int _endTouchX;
  int _endTouchY;

  TouchHandler(Touchable touchable, [Element element = null])
      : _touchable = touchable,
        _totalMoveY = 0,
        _totalMoveX = 0,
        _recentTouchesX = new List<int>(),
        _recentTouchesY = new List<int>(),
        // TODO(jmesserly): I don't like having to initialize all booleans here
        // See b/5045736
        _dragging = false,
        _tracking = false,
        _touching = false {
    _element = element != null ? element : touchable.getElement();
  }

  /**
   * Begin tracking the touchable element, it is eligible for dragging.
   */
  void _beginTracking() {
    _tracking = true;
  }

  /**
   * Stop tracking the touchable element, it is no longer dragging.
   */
  void _endTracking() {
    _tracking = false;
    _dragging = false;
    _totalMoveY = 0;
    _totalMoveX = 0;
  }

  /**
   * Correct erroneous velocities by capping the velocity if we think it's too
   * high, or setting it to a default velocity if know that the event data is
   * bad. Returns the corrected velocity.
   */
  num _correctVelocity(num velocity) {
    num absVelocity = velocity.abs();
    if (absVelocity > _MAXIMUM_VELOCITY) {
      absVelocity = _recentTouchesY.length < 6
          ? _VELOCITY_FOR_INCORRECT_EVENTS
          : _MAXIMUM_VELOCITY;
    }
    return absVelocity * (velocity < 0 ? -1 : 1);
  }

  /**
   * Start listenting for events.
   * If [capture] is True the TouchHandler should listen during the capture
   * phase.
   */
  void enable([bool capture = false]) {
    Function onEnd = (e) {
      _onEnd(e.timeStamp.toInt(), e);
    };
    _addEventListeners(_element, (e) {
      _onStart(e);
    }, (e) {
      _onMove(e);
    }, onEnd, onEnd, capture);
  }

  /**
   * Get the current horizontal drag delta. Drag delta is defined as the deltaX
   * of the start touch position and the last touch position.
   */
  int getDragDeltaX() {
    return _lastTouchX - _startTouchX;
  }

  /**
   * Get the current vertical drag delta. Drag delta is defined as the deltaY of
   * the start touch position and the last touch position.
   */
  int getDragDeltaY() {
    return _lastTouchY - _startTouchY;
  }

  /**
   * Get end velocity of the drag. This method is specific to drag behavior, so
   * if touch behavior and drag behavior is split then this should go with drag
   * behavior. End velocity is defined as deltaXY / deltaTime where deltaXY is
   * the difference between endPosition and the oldest recent position, and
   * deltaTime is the difference between endTime and the oldest recent time
   * stamp.
   */
  Coordinate getEndVelocity() {
    num velocityX = 0;
    num velocityY = 0;

    if (_recentTouchesX.length > 0) {
      num timeDeltaX = Math.max(1, _endTime - _recentTouchesX[1]);
      velocityX = (_endTouchX - _recentTouchesX[0]) / timeDeltaX;
    }

    if (_recentTouchesY.length > 0) {
      num timeDeltaY = Math.max(1, _endTime - _recentTouchesY[1]);
      velocityY = (_endTouchY - _recentTouchesY[0]) / timeDeltaY;
    }
    velocityX = _correctVelocity(velocityX);
    velocityY = _correctVelocity(velocityY);
    return new Coordinate(velocityX, velocityY);
  }

  /**
   * Return the touch of the last event.
   */
  Touch _getLastTouch() {
    assert(_lastEvent != null); // Last event not set
    return _lastEvent.touches[0];
  }

  /**
   * Is the touch manager currently tracking touch moves to detect a drag?
   */
  bool isTracking() {
    return _tracking;
  }

  /**
   * Touch end handler.
   */
  void _onEnd(int timeStamp, [TouchEvent e = null]) {
    _touching = false;
    _touchable.onTouchEnd();
    if (!_tracking || _draggable == null) {
      return;
    }
    Touch touch = _getLastTouch();
    int clientX = touch.client.x;
    int clientY = touch.client.y;
    if (_dragging) {
      _endTime = timeStamp;
      _endTouchX = clientX;
      _endTouchY = clientY;
      _recentTouchesX = _removeOldTouches(_recentTouchesX, timeStamp);
      _recentTouchesY = _removeOldTouches(_recentTouchesY, timeStamp);
      _draggable.onDragEnd();
      if (e != null) {
        e.preventDefault();
      }
      ClickBuster.preventGhostClick(_startTouchX, _startTouchY);
    }
    _endTracking();
  }

  /**
   * Touch move handler.
   */
  void _onMove(TouchEvent e) {
    if (!_tracking || _draggable == null) {
      return;
    }
    final touch = e.touches[0];
    int clientX = touch.client.x;
    int clientY = touch.client.y;
    int moveX = _lastTouchX - clientX;
    int moveY = _lastTouchY - clientY;
    int timeStamp = e.timeStamp.toInt();
    _totalMoveX += moveX.abs();
    _totalMoveY += moveY.abs();
    _lastTouchX = clientX;
    _lastTouchY = clientY;
    if (!_dragging &&
        ((_totalMoveY > _MIN_TRACKING_FOR_DRAG && _draggable.verticalEnabled) ||
            (_totalMoveX > _MIN_TRACKING_FOR_DRAG &&
                _draggable.horizontalEnabled))) {
      _dragging = _draggable.onDragStart(e);
      if (!_dragging) {
        _endTracking();
      } else {
        _startTouchX = clientX;
        _startTouchY = clientY;
        _startTime = timeStamp;
      }
    }
    if (_dragging) {
      _draggable.onDragMove();
      _lastEvent = e;
      e.preventDefault();
      _recentTouchesX =
          _removeTouchesInWrongDirection(_recentTouchesX, _lastMoveX, moveX);
      _recentTouchesY =
          _removeTouchesInWrongDirection(_recentTouchesY, _lastMoveY, moveY);
      _recentTouchesX = _removeOldTouches(_recentTouchesX, timeStamp);
      _recentTouchesY = _removeOldTouches(_recentTouchesY, timeStamp);
      _recentTouchesX.add(clientX);
      _recentTouchesX.add(timeStamp);
      _recentTouchesY.add(clientY);
      _recentTouchesY.add(timeStamp);
    }
    _lastMoveX = moveX;
    _lastMoveY = moveY;
  }

  /**
   * Touch start handler.
   */
  void _onStart(TouchEvent e) {
    if (_touching) {
      return;
    }
    _touching = true;
    if (!_touchable.onTouchStart(e) || _draggable == null) {
      return;
    }
    final touch = e.touches[0];
    _startTouchX = _lastTouchX = touch.client.x;
    _startTouchY = _lastTouchY = touch.client.y;
    int timeStamp = e.timeStamp.toInt();
    _startTime = timeStamp;
    // TODO(jacobr): why don't we just clear the lists?
    _recentTouchesX = new List<int>();
    _recentTouchesY = new List<int>();
    _recentTouchesX.add(touch.client.x);
    _recentTouchesX.add(timeStamp);
    _recentTouchesY.add(touch.client.y);
    _recentTouchesY.add(timeStamp);
    _lastEvent = e;
    _beginTracking();
  }

  /**
   * Filters the provided recent touches list to remove all touches older than
   * the max tracking time or the 5th most recent touch.
   * [recentTouches] specifies a list of tuples where the first item is the x
   * or y component of the recent touch and the second item is the touch time
   * stamp. The time of the most recent event is specified by [recentTime].
   */
  List<int> _removeOldTouches(List<int> recentTouches, int recentTime) {
    int count = 0;
    final len = recentTouches.length;
    assert(len % 2 == 0);
    while (count < len &&
            recentTime - recentTouches[count + 1] > _MAX_TRACKING_TIME ||
        (len - count) > _MAX_TRACKING_TOUCHES * 2) {
      count += 2;
    }
    return count == 0 ? recentTouches : _removeFirstN(recentTouches, count);
  }

  static List<int> _removeFirstN(List<int> list, int n) {
    return list.sublist(n);
  }

  /**
   * Filters the provided recent touches list to remove all touches except the
   * last if the move direction has changed.
   * [recentTouches] specifies a list of tuples where the first item is the x
   * or y component of the recent touch and the second item is the touch time
   * stamp. The x or y component of the most recent move is specified by
   * [recentMove].
   */
  List<int> _removeTouchesInWrongDirection(
      List<int> recentTouches, int lastMove, int recentMove) {
    if (lastMove != 0 &&
        recentMove != 0 &&
        recentTouches.length > 2 &&
        _xor(lastMove > 0, recentMove > 0)) {
      return _removeFirstN(recentTouches, recentTouches.length - 2);
    }
    return recentTouches;
  }

  // TODO(jacobr): why doesn't bool implement the xor operator directly?
  static bool _xor(bool a, bool b) => a != b;

  /**
   * Reset the touchable element.
   */
  void reset() {
    _endTracking();
    _touching = false;
  }

  /**
   * Call this method to enable drag behavior on a draggable delegate.
   * The [draggable] object can be the same as the [_touchable] object, they are
   * assigned to different members to allow for strong typing with interfaces.
   */
  void setDraggable(Draggable draggable) {
    _draggable = draggable;
  }
}
