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

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, 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;
    _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 = e.timeStamp;
      }
    }
    if (_dragging) {
      _draggable.onDragMove();
      _lastEvent = e;
      e.preventDefault();
      _recentTouchesX =
          _removeTouchesInWrongDirection(_recentTouchesX, _lastMoveX, moveX);
      _recentTouchesY =
          _removeTouchesInWrongDirection(_recentTouchesY, _lastMoveY, moveY);
      _recentTouchesX = _removeOldTouches(_recentTouchesX, e.timeStamp);
      _recentTouchesY = _removeOldTouches(_recentTouchesY, e.timeStamp);
      _recentTouchesX.add(clientX);
      _recentTouchesX.add(e.timeStamp);
      _recentTouchesY.add(clientY);
      _recentTouchesY.add(e.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;
    _startTime = e.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(e.timeStamp);
    _recentTouchesY.add(touch.client.y);
    _recentTouchesY.add(e.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;
  }
}
