// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// MSVC++ requires this to be set before any other includes to get M_PI.
#define _USE_MATH_DEFINES

#include "ui/events/gesture_detection/gesture_detector.h"

#include <cmath>

#include "base/timer/timer.h"
#include "ui/events/gesture_detection/gesture_listeners.h"
#include "ui/events/gesture_detection/motion_event.h"

namespace ui {
namespace {

// Using a small epsilon when comparing slop distances allows pixel perfect
// slop determination when using fractional DIP coordinates (assuming the slop
// region and DPI scale are reasonably proportioned).
const float kSlopEpsilon = .05f;

// Minimum distance a scroll must have traveled from the last scroll/focal point
// to trigger an |OnScroll| callback.
const float kScrollEpsilon = .1f;

const float kDegreesToRadians = static_cast<float>(M_PI) / 180.0f;

// Constants used by TimeoutGestureHandler.
enum TimeoutEvent {
  SHOW_PRESS = 0,
  LONG_PRESS,
  TAP,
  TIMEOUT_EVENT_COUNT
};

}  // namespace

// Note: These constants were taken directly from the default (unscaled)
// versions found in Android's ViewConfiguration. Do not change these default
// values without explicitly consulting an OWNER.
GestureDetector::Config::Config()
    : longpress_timeout(base::TimeDelta::FromMilliseconds(500)),
      showpress_timeout(base::TimeDelta::FromMilliseconds(180)),
      double_tap_timeout(base::TimeDelta::FromMilliseconds(300)),
      double_tap_min_time(base::TimeDelta::FromMilliseconds(40)),
      touch_slop(8),
      double_tap_slop(100),
      minimum_fling_velocity(50),
      maximum_fling_velocity(8000),
      swipe_enabled(false),
      minimum_swipe_velocity(20),
      maximum_swipe_deviation_angle(20.f),
      two_finger_tap_enabled(false),
      two_finger_tap_max_separation(300),
      two_finger_tap_timeout(base::TimeDelta::FromMilliseconds(700)),
      velocity_tracker_strategy(VelocityTracker::Strategy::STRATEGY_DEFAULT) {
}

GestureDetector::Config::~Config() {}

class GestureDetector::TimeoutGestureHandler {
 public:
  TimeoutGestureHandler(const Config& config, GestureDetector* gesture_detector)
      : gesture_detector_(gesture_detector) {
    DCHECK(config.showpress_timeout <= config.longpress_timeout);

    timeout_callbacks_[SHOW_PRESS] = &GestureDetector::OnShowPressTimeout;
    timeout_delays_[SHOW_PRESS] = config.showpress_timeout;

    timeout_callbacks_[LONG_PRESS] = &GestureDetector::OnLongPressTimeout;
    timeout_delays_[LONG_PRESS] =
        config.longpress_timeout + config.showpress_timeout;

    timeout_callbacks_[TAP] = &GestureDetector::OnTapTimeout;
    timeout_delays_[TAP] = config.double_tap_timeout;
  }

  ~TimeoutGestureHandler() {
    Stop();
  }

  void StartTimeout(TimeoutEvent event) {
    timeout_timers_[event].Start(FROM_HERE,
                                 timeout_delays_[event],
                                 gesture_detector_,
                                 timeout_callbacks_[event]);
  }

  void StopTimeout(TimeoutEvent event) { timeout_timers_[event].Stop(); }

  void Stop() {
    for (size_t i = SHOW_PRESS; i < TIMEOUT_EVENT_COUNT; ++i)
      timeout_timers_[i].Stop();
  }

  bool HasTimeout(TimeoutEvent event) const {
    return timeout_timers_[event].IsRunning();
  }

 private:
  typedef void (GestureDetector::*ReceiverMethod)();

  GestureDetector* const gesture_detector_;
  base::OneShotTimer<GestureDetector> timeout_timers_[TIMEOUT_EVENT_COUNT];
  ReceiverMethod timeout_callbacks_[TIMEOUT_EVENT_COUNT];
  base::TimeDelta timeout_delays_[TIMEOUT_EVENT_COUNT];
};

GestureDetector::GestureDetector(
    const Config& config,
    GestureListener* listener,
    DoubleTapListener* optional_double_tap_listener)
    : timeout_handler_(new TimeoutGestureHandler(config, this)),
      listener_(listener),
      double_tap_listener_(optional_double_tap_listener),
      touch_slop_square_(0),
      double_tap_touch_slop_square_(0),
      double_tap_slop_square_(0),
      two_finger_tap_distance_square_(0),
      min_fling_velocity_(1),
      max_fling_velocity_(1),
      min_swipe_velocity_(0),
      min_swipe_direction_component_ratio_(0),
      still_down_(false),
      defer_confirm_single_tap_(false),
      always_in_tap_region_(false),
      always_in_bigger_tap_region_(false),
      two_finger_tap_allowed_for_gesture_(false),
      is_double_tapping_(false),
      last_focus_x_(0),
      last_focus_y_(0),
      down_focus_x_(0),
      down_focus_y_(0),
      longpress_enabled_(true),
      showpress_enabled_(true),
      swipe_enabled_(false),
      two_finger_tap_enabled_(false),
      velocity_tracker_(config.velocity_tracker_strategy) {
  DCHECK(listener_);
  Init(config);
}

GestureDetector::~GestureDetector() {}

bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
  const MotionEvent::Action action = ev.GetAction();

  velocity_tracker_.AddMovement(ev);

  const bool pointer_up = action == MotionEvent::ACTION_POINTER_UP;
  const int skip_index = pointer_up ? ev.GetActionIndex() : -1;

  // Determine focal point.
  float sum_x = 0, sum_y = 0;
  const int count = static_cast<int>(ev.GetPointerCount());
  for (int i = 0; i < count; i++) {
    if (skip_index == i)
      continue;
    sum_x += ev.GetX(i);
    sum_y += ev.GetY(i);
  }
  const int div = pointer_up ? count - 1 : count;
  const float focus_x = sum_x / div;
  const float focus_y = sum_y / div;

  bool handled = false;

  switch (action) {
    case MotionEvent::ACTION_POINTER_DOWN: {
      down_focus_x_ = last_focus_x_ = focus_x;
      down_focus_y_ = last_focus_y_ = focus_y;
      // Cancel long press and taps.
      CancelTaps();

      if (!two_finger_tap_allowed_for_gesture_)
        break;

      const int action_index = ev.GetActionIndex();
      const float dx = ev.GetX(action_index) - current_down_event_->GetX();
      const float dy = ev.GetY(action_index) - current_down_event_->GetY();

      if (ev.GetPointerCount() == 2 &&
          dx * dx + dy * dy < two_finger_tap_distance_square_) {
        secondary_pointer_down_event_ = ev.Clone();
      } else {
        two_finger_tap_allowed_for_gesture_ = false;
      }
    } break;

    case MotionEvent::ACTION_POINTER_UP: {
      down_focus_x_ = last_focus_x_ = focus_x;
      down_focus_y_ = last_focus_y_ = focus_y;

      // Check the dot product of current velocities.
      // If the pointer that left was opposing another velocity vector, clear.
      velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_);
      const int up_index = ev.GetActionIndex();
      const int id1 = ev.GetPointerId(up_index);
      const float vx1 = velocity_tracker_.GetXVelocity(id1);
      const float vy1 = velocity_tracker_.GetYVelocity(id1);
      float vx_total = vx1;
      float vy_total = vy1;
      for (int i = 0; i < count; i++) {
        if (i == up_index)
          continue;

        const int id2 = ev.GetPointerId(i);
        const float vx2 = velocity_tracker_.GetXVelocity(id2);
        const float vy2 = velocity_tracker_.GetYVelocity(id2);
        const float dot = vx1 * vx2 + vy1 * vy2;
        if (dot < 0) {
          vx_total = 0;
          vy_total = 0;
          velocity_tracker_.Clear();
          break;
        }
        vx_total += vx2;
        vy_total += vy2;
      }

      handled = HandleSwipeIfNeeded(ev, vx_total / count, vy_total / count);

      if (two_finger_tap_allowed_for_gesture_ && ev.GetPointerCount() == 2 &&
          (ev.GetEventTime() - secondary_pointer_down_event_->GetEventTime() <=
           two_finger_tap_timeout_)) {
        handled = listener_->OnTwoFingerTap(*current_down_event_, ev);
      }
      two_finger_tap_allowed_for_gesture_ = false;
    } break;

    case MotionEvent::ACTION_DOWN:
      if (double_tap_listener_) {
        bool had_tap_message = timeout_handler_->HasTimeout(TAP);
        if (had_tap_message)
          timeout_handler_->StopTimeout(TAP);
        if (current_down_event_ && previous_up_event_ && had_tap_message &&
            IsConsideredDoubleTap(
                *current_down_event_, *previous_up_event_, ev)) {
          // This is a second tap.
          is_double_tapping_ = true;
          // Give a callback with the first tap of the double-tap.
          handled |= double_tap_listener_->OnDoubleTap(*current_down_event_);
          // Give a callback with down event of the double-tap.
          handled |= double_tap_listener_->OnDoubleTapEvent(ev);
        } else {
          // This is a first tap.
          DCHECK(double_tap_timeout_ > base::TimeDelta());
          timeout_handler_->StartTimeout(TAP);
        }
      }

      down_focus_x_ = last_focus_x_ = focus_x;
      down_focus_y_ = last_focus_y_ = focus_y;
      current_down_event_ = ev.Clone();

      secondary_pointer_down_event_.reset();
      always_in_tap_region_ = true;
      always_in_bigger_tap_region_ = true;
      still_down_ = true;
      defer_confirm_single_tap_ = false;
      two_finger_tap_allowed_for_gesture_ = two_finger_tap_enabled_;

      // Always start the SHOW_PRESS timer before the LONG_PRESS timer to ensure
      // proper timeout ordering.
      if (showpress_enabled_)
        timeout_handler_->StartTimeout(SHOW_PRESS);
      if (longpress_enabled_)
        timeout_handler_->StartTimeout(LONG_PRESS);
      handled |= listener_->OnDown(ev);
      break;

    case MotionEvent::ACTION_MOVE:
      {
        const float scroll_x = last_focus_x_ - focus_x;
        const float scroll_y = last_focus_y_ - focus_y;
        if (is_double_tapping_) {
          // Give the move events of the double-tap.
          DCHECK(double_tap_listener_);
          handled |= double_tap_listener_->OnDoubleTapEvent(ev);
        } else if (always_in_tap_region_) {
          const float delta_x = focus_x - down_focus_x_;
          const float delta_y = focus_y - down_focus_y_;
          const float distance_square = delta_x * delta_x + delta_y * delta_y;
          if (distance_square > touch_slop_square_) {
            handled = listener_->OnScroll(
                *current_down_event_, ev, scroll_x, scroll_y);
            last_focus_x_ = focus_x;
            last_focus_y_ = focus_y;
            always_in_tap_region_ = false;
            timeout_handler_->Stop();
          }
          if (distance_square > double_tap_touch_slop_square_)
            always_in_bigger_tap_region_ = false;
        } else if (std::abs(scroll_x) > kScrollEpsilon ||
                   std::abs(scroll_y) > kScrollEpsilon) {
          // We should eventually apply touch slop for multi-finger
          // scrolls as well as single finger scrolls. See
          // crbug.com/492185 for details.
          handled =
              listener_->OnScroll(*current_down_event_, ev, scroll_x, scroll_y);
          last_focus_x_ = focus_x;
          last_focus_y_ = focus_y;
        }

        if (!two_finger_tap_allowed_for_gesture_)
          break;

        // Two-finger tap should be prevented if either pointer exceeds its
        // (independent) slop region.
        const int id0 = current_down_event_->GetPointerId(0);
        const int ev_idx0 = ev.GetPointerId(0) == id0 ? 0 : 1;

        // Check if the primary pointer exceeded the slop region.
        float dx = current_down_event_->GetX() - ev.GetX(ev_idx0);
        float dy = current_down_event_->GetY() - ev.GetY(ev_idx0);
        if (dx * dx + dy * dy > touch_slop_square_) {
          two_finger_tap_allowed_for_gesture_ = false;
          break;
        }
        if (ev.GetPointerCount() == 2) {
          // Check if the secondary pointer exceeded the slop region.
          const int ev_idx1 = ev_idx0 == 0 ? 1 : 0;
          const int idx1 = secondary_pointer_down_event_->GetActionIndex();
          dx = secondary_pointer_down_event_->GetX(idx1) - ev.GetX(ev_idx1);
          dy = secondary_pointer_down_event_->GetY(idx1) - ev.GetY(ev_idx1);
          if (dx * dx + dy * dy > touch_slop_square_)
            two_finger_tap_allowed_for_gesture_ = false;
        }
      }
      break;

    case MotionEvent::ACTION_UP:
      still_down_ = false;
      {
        if (is_double_tapping_) {
          // Finally, give the up event of the double-tap.
          DCHECK(double_tap_listener_);
          handled |= double_tap_listener_->OnDoubleTapEvent(ev);
        } else if (always_in_tap_region_) {
          handled = listener_->OnSingleTapUp(ev);
          if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) {
            double_tap_listener_->OnSingleTapConfirmed(ev);
          }
        } else {

          // A fling must travel the minimum tap distance.
          const int pointer_id = ev.GetPointerId(0);
          velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_);
          const float velocity_y = velocity_tracker_.GetYVelocity(pointer_id);
          const float velocity_x = velocity_tracker_.GetXVelocity(pointer_id);

          if ((std::abs(velocity_y) > min_fling_velocity_) ||
              (std::abs(velocity_x) > min_fling_velocity_)) {
            handled = listener_->OnFling(
                *current_down_event_, ev, velocity_x, velocity_y);
          }

          handled |= HandleSwipeIfNeeded(ev, velocity_x, velocity_y);
        }

        previous_up_event_ = ev.Clone();

        velocity_tracker_.Clear();
        is_double_tapping_ = false;
        defer_confirm_single_tap_ = false;
        timeout_handler_->StopTimeout(SHOW_PRESS);
        timeout_handler_->StopTimeout(LONG_PRESS);
      }
      break;

    case MotionEvent::ACTION_CANCEL:
      Cancel();
      break;
  }

  return handled;
}

void GestureDetector::SetDoubleTapListener(
    DoubleTapListener* double_tap_listener) {
  if (double_tap_listener == double_tap_listener_)
    return;

  DCHECK(!is_double_tapping_);

  // Null'ing the double-tap listener should flush an active tap timeout.
  if (!double_tap_listener) {
    if (timeout_handler_->HasTimeout(TAP)) {
      timeout_handler_->StopTimeout(TAP);
      OnTapTimeout();
    }
  }

  double_tap_listener_ = double_tap_listener;
}

void GestureDetector::Init(const Config& config) {
  DCHECK(listener_);

  const float touch_slop = config.touch_slop + kSlopEpsilon;
  const float double_tap_touch_slop = touch_slop;
  const float double_tap_slop = config.double_tap_slop + kSlopEpsilon;
  touch_slop_square_ = touch_slop * touch_slop;
  double_tap_touch_slop_square_ = double_tap_touch_slop * double_tap_touch_slop;
  double_tap_slop_square_ = double_tap_slop * double_tap_slop;
  double_tap_timeout_ = config.double_tap_timeout;
  double_tap_min_time_ = config.double_tap_min_time;
  DCHECK(double_tap_min_time_ < double_tap_timeout_);
  min_fling_velocity_ = config.minimum_fling_velocity;
  max_fling_velocity_ = config.maximum_fling_velocity;

  swipe_enabled_ = config.swipe_enabled;
  min_swipe_velocity_ = config.minimum_swipe_velocity;
  DCHECK_GT(config.maximum_swipe_deviation_angle, 0);
  DCHECK_LE(config.maximum_swipe_deviation_angle, 45);
  const float maximum_swipe_deviation_angle =
      std::min(45.f, std::max(0.001f, config.maximum_swipe_deviation_angle));
  min_swipe_direction_component_ratio_ =
      1.f / tan(maximum_swipe_deviation_angle * kDegreesToRadians);

  two_finger_tap_enabled_ = config.two_finger_tap_enabled;
  two_finger_tap_distance_square_ = config.two_finger_tap_max_separation *
                                    config.two_finger_tap_max_separation;
  two_finger_tap_timeout_ = config.two_finger_tap_timeout;
}

void GestureDetector::OnShowPressTimeout() {
  listener_->OnShowPress(*current_down_event_);
}

void GestureDetector::OnLongPressTimeout() {
  timeout_handler_->StopTimeout(TAP);
  defer_confirm_single_tap_ = false;
  listener_->OnLongPress(*current_down_event_);
}

void GestureDetector::OnTapTimeout() {
  if (!double_tap_listener_)
    return;
  if (!still_down_) {
    CHECK(previous_up_event_);
    double_tap_listener_->OnSingleTapConfirmed(*previous_up_event_);
  } else {
    defer_confirm_single_tap_ = true;
  }
}

void GestureDetector::Cancel() {
  CancelTaps();
  velocity_tracker_.Clear();
  still_down_ = false;
}

void GestureDetector::CancelTaps() {
  timeout_handler_->Stop();
  is_double_tapping_ = false;
  always_in_tap_region_ = false;
  always_in_bigger_tap_region_ = false;
  defer_confirm_single_tap_ = false;
}

bool GestureDetector::IsConsideredDoubleTap(
    const MotionEvent& first_down,
    const MotionEvent& first_up,
    const MotionEvent& second_down) const {
  if (!always_in_bigger_tap_region_)
    return false;

  const base::TimeDelta delta_time =
      second_down.GetEventTime() - first_up.GetEventTime();
  if (delta_time < double_tap_min_time_ || delta_time > double_tap_timeout_)
    return false;

  const float delta_x = first_down.GetX() - second_down.GetX();
  const float delta_y = first_down.GetY() - second_down.GetY();
  return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square_);
}

bool GestureDetector::HandleSwipeIfNeeded(const MotionEvent& up,
                                          float vx,
                                          float vy) {
  if (!swipe_enabled_ || (!vx && !vy))
    return false;
  float vx_abs = std::abs(vx);
  float vy_abs = std::abs(vy);

  if (vx_abs < min_swipe_velocity_)
    vx_abs = vx = 0;
  if (vy_abs < min_swipe_velocity_)
    vy_abs = vy = 0;

  // Note that the ratio will be 0 if both velocites are below the min.
  float ratio = vx_abs > vy_abs ? vx_abs / std::max(vy_abs, 0.001f)
                                : vy_abs / std::max(vx_abs, 0.001f);

  if (ratio < min_swipe_direction_component_ratio_)
    return false;

  if (vx_abs > vy_abs)
    vy = 0;
  else
    vx = 0;
  return listener_->OnSwipe(*current_down_event_, up, vx, vy);
}

}  // namespace ui
