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

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

#include <limits.h>
#include <cmath>

#include "base/float_util.h"
#include "base/logging.h"
#include "ui/events/gesture_detection/motion_event.h"

using base::TimeDelta;
using base::TimeTicks;

namespace ui {
namespace {

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

const int kTouchStabilizeTimeMs = 128;

const float kScaleFactor = .5f;

}  // namespace

// Note: These constants were taken directly from the default (unscaled)
// versions found in Android's ViewConfiguration.
ScaleGestureDetector::Config::Config()
    : min_scaling_touch_major(48),
      min_scaling_span(100),
      use_touch_major_in_span(false),
      quick_scale_enabled(true),
      min_pinch_update_span_delta(0) {
}

ScaleGestureDetector::Config::~Config() {}

bool ScaleGestureDetector::SimpleScaleGestureListener::OnScale(
    const ScaleGestureDetector&, const MotionEvent&) {
  return false;
}

bool ScaleGestureDetector::SimpleScaleGestureListener::OnScaleBegin(
    const ScaleGestureDetector&, const MotionEvent&) {
  return true;
}

void ScaleGestureDetector::SimpleScaleGestureListener::OnScaleEnd(
    const ScaleGestureDetector&, const MotionEvent&) {}

ScaleGestureDetector::ScaleGestureDetector(const Config& config,
                                           ScaleGestureListener* listener)
    : listener_(listener),
      config_(config),
      focus_x_(0),
      focus_y_(0),
      quick_scale_enabled_(false),
      curr_span_(0),
      prev_span_(0),
      initial_span_(0),
      curr_span_x_(0),
      curr_span_y_(0),
      prev_span_x_(0),
      prev_span_y_(0),
      in_progress_(0),
      span_slop_(0),
      min_span_(0),
      use_touch_major_in_span_(config.use_touch_major_in_span),
      touch_upper_(0),
      touch_lower_(0),
      touch_history_last_accepted_(0),
      touch_history_direction_(0),
      touch_min_major_(0),
      touch_max_major_(0),
      double_tap_focus_x_(0),
      double_tap_focus_y_(0),
      double_tap_mode_(DOUBLE_TAP_MODE_NONE),
      event_before_or_above_starting_gesture_event_(false) {
  DCHECK(listener_);
  span_slop_ = (config.gesture_detector_config.touch_slop + kSlopEpsilon) * 2;
  touch_min_major_ = config.min_scaling_touch_major;
  touch_max_major_ = std::min(config.min_scaling_span, 2.f * touch_min_major_);
  min_span_ = config.min_scaling_span + kSlopEpsilon;
  ResetTouchHistory();
  SetQuickScaleEnabled(config.quick_scale_enabled);
}

ScaleGestureDetector::~ScaleGestureDetector() {}

bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) {
  curr_time_ = event.GetEventTime();

  const int action = event.GetAction();

  // Forward the event to check for double tap gesture.
  if (quick_scale_enabled_) {
    DCHECK(gesture_detector_);
    gesture_detector_->OnTouchEvent(event);
  }

  const bool stream_complete =
      action == MotionEvent::ACTION_UP ||
      action == MotionEvent::ACTION_CANCEL ||
      (action == MotionEvent::ACTION_POINTER_DOWN && InDoubleTapMode());

  if (action == MotionEvent::ACTION_DOWN || stream_complete) {
    // Reset any scale in progress with the listener.
    // If it's an ACTION_DOWN we're beginning a new event stream.
    // This means the app probably didn't give us all the events. Shame on it.
    if (in_progress_) {
      listener_->OnScaleEnd(*this, event);
      ResetScaleWithSpan(0);
    } else if (InDoubleTapMode() && stream_complete) {
      ResetScaleWithSpan(0);
    }

    if (stream_complete) {
      ResetTouchHistory();
      return true;
    }
  }

  const bool config_changed = action == MotionEvent::ACTION_DOWN ||
                              action == MotionEvent::ACTION_POINTER_UP ||
                              action == MotionEvent::ACTION_POINTER_DOWN;

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

  // Determine focal point.
  float sum_x = 0, sum_y = 0;
  const int count = static_cast<int>(event.GetPointerCount());
  const int unreleased_point_count = pointer_up ? count - 1 : count;
  const float inverse_unreleased_point_count = 1.0f / unreleased_point_count;

  float focus_x;
  float focus_y;
  if (InDoubleTapMode()) {
    // In double tap mode, the focal pt is always where the double tap
    // gesture started.
    focus_x = double_tap_focus_x_;
    focus_y = double_tap_focus_y_;
    if (event.GetY() < focus_y) {
      event_before_or_above_starting_gesture_event_ = true;
    } else {
      event_before_or_above_starting_gesture_event_ = false;
    }
  } else {
    for (int i = 0; i < count; i++) {
      if (skip_index == i)
        continue;
      sum_x += event.GetX(i);
      sum_y += event.GetY(i);
    }

    focus_x = sum_x * inverse_unreleased_point_count;
    focus_y = sum_y * inverse_unreleased_point_count;
  }

  if (use_touch_major_in_span_)
    AddTouchHistory(event);

  // Determine average deviation from focal point.
  float dev_sum_x = 0, dev_sum_y = 0;
  for (int i = 0; i < count; i++) {
    if (skip_index == i)
      continue;

    dev_sum_x += std::abs(event.GetX(i) - focus_x);
    dev_sum_y += std::abs(event.GetY(i) - focus_y);
  }
  // Convert the resulting diameter into a radius, to include touch
  // radius in overall deviation.
  const float touch_radius =
      use_touch_major_in_span_ ? touch_history_last_accepted_ / 2 : 0;

  const float dev_x = dev_sum_x * inverse_unreleased_point_count + touch_radius;
  const float dev_y = dev_sum_y * inverse_unreleased_point_count + touch_radius;

  // Span is the average distance between touch points through the focal point;
  // i.e. the diameter of the circle with a radius of the average deviation from
  // the focal point.
  const float span_x = dev_x * 2;
  const float span_y = dev_y * 2;
  float span;
  if (InDoubleTapMode()) {
    span = span_y;
  } else {
    span = std::sqrt(span_x * span_x + span_y * span_y);
  }

  // Dispatch begin/end events as needed.
  // If the configuration changes, notify the app to reset its current state by
  // beginning a fresh scale event stream.
  const bool was_in_progress = in_progress_;
  focus_x_ = focus_x;
  focus_y_ = focus_y;
  if (!InDoubleTapMode() && in_progress_ &&
      (span < min_span_ || config_changed)) {
    listener_->OnScaleEnd(*this, event);
    ResetScaleWithSpan(span);
  }
  if (config_changed) {
    prev_span_x_ = curr_span_x_ = span_x;
    prev_span_y_ = curr_span_y_ = span_y;
    initial_span_ = prev_span_ = curr_span_ = span;
  }

  const float min_span = InDoubleTapMode() ? span_slop_ : min_span_;
  if (!in_progress_ && span >= min_span && (InDoubleTapMode() || count > 1) &&
      (was_in_progress || std::abs(span - initial_span_) > span_slop_)) {
    prev_span_x_ = curr_span_x_ = span_x;
    prev_span_y_ = curr_span_y_ = span_y;
    prev_span_ = curr_span_ = span;
    prev_time_ = curr_time_;
    in_progress_ = listener_->OnScaleBegin(*this, event);
  }

  // Handle motion; focal point and span/scale factor are changing.
  if (action == MotionEvent::ACTION_MOVE) {
    curr_span_x_ = span_x;
    curr_span_y_ = span_y;
    curr_span_ = span;

    bool update_prev = true;

    if (in_progress_) {
      update_prev = listener_->OnScale(*this, event);
    }

    if (update_prev) {
      prev_span_x_ = curr_span_x_;
      prev_span_y_ = curr_span_y_;
      prev_span_ = curr_span_;
      prev_time_ = curr_time_;
    }
  }

  return true;
}

void ScaleGestureDetector::SetQuickScaleEnabled(bool scales) {
  quick_scale_enabled_ = scales;
  if (quick_scale_enabled_ && !gesture_detector_) {
    gesture_detector_.reset(
        new GestureDetector(config_.gesture_detector_config, this, this));
  }
}

bool ScaleGestureDetector::IsQuickScaleEnabled() const {
  return quick_scale_enabled_;
}

bool ScaleGestureDetector::IsInProgress() const { return in_progress_; }

bool ScaleGestureDetector::InDoubleTapMode() const {
  return double_tap_mode_ == DOUBLE_TAP_MODE_IN_PROGRESS;
}

float ScaleGestureDetector::GetFocusX() const { return focus_x_; }

float ScaleGestureDetector::GetFocusY() const { return focus_y_; }

float ScaleGestureDetector::GetCurrentSpan() const { return curr_span_; }

float ScaleGestureDetector::GetCurrentSpanX() const { return curr_span_x_; }

float ScaleGestureDetector::GetCurrentSpanY() const { return curr_span_y_; }

float ScaleGestureDetector::GetPreviousSpan() const { return prev_span_; }

float ScaleGestureDetector::GetPreviousSpanX() const { return prev_span_x_; }

float ScaleGestureDetector::GetPreviousSpanY() const { return prev_span_y_; }

float ScaleGestureDetector::GetScaleFactor() const {
  if (InDoubleTapMode()) {
    // Drag is moving up; the further away from the gesture start, the smaller
    // the span should be, the closer, the larger the span, and therefore the
    // larger the scale.
    const bool scale_up = (event_before_or_above_starting_gesture_event_ &&
                           (curr_span_ < prev_span_)) ||
                          (!event_before_or_above_starting_gesture_event_ &&
                           (curr_span_ > prev_span_));
    const float span_diff =
        (std::abs(1.f - (curr_span_ / prev_span_)) * kScaleFactor);
    return prev_span_ <= 0 ? 1.f
                           : (scale_up ? (1.f + span_diff) : (1.f - span_diff));
  }
  return prev_span_ > 0 ? curr_span_ / prev_span_ : 1;
}

base::TimeDelta ScaleGestureDetector::GetTimeDelta() const {
  return curr_time_ - prev_time_;
}

base::TimeTicks ScaleGestureDetector::GetEventTime() const {
  return curr_time_;
}

bool ScaleGestureDetector::OnDoubleTap(const MotionEvent& ev) {
  // Double tap: start watching for a swipe.
  double_tap_focus_x_ = ev.GetX();
  double_tap_focus_y_ = ev.GetY();
  double_tap_mode_ = DOUBLE_TAP_MODE_IN_PROGRESS;
  return true;
}

void ScaleGestureDetector::AddTouchHistory(const MotionEvent& ev) {
  const base::TimeTicks current_time = ev.GetEventTime();
  DCHECK(!current_time.is_null());
  const int count = static_cast<int>(ev.GetPointerCount());
  bool accept = touch_history_last_accepted_time_.is_null() ||
                (current_time - touch_history_last_accepted_time_) >=
                    base::TimeDelta::FromMilliseconds(kTouchStabilizeTimeMs);
  float total = 0;
  int sample_count = 0;
  for (int i = 0; i < count; i++) {
    const bool has_last_accepted = !base::IsNaN(touch_history_last_accepted_);
    const int history_size = static_cast<int>(ev.GetHistorySize());
    const int pointersample_count = history_size + 1;
    for (int h = 0; h < pointersample_count; h++) {
      float major;
      if (h < history_size) {
        major = ev.GetHistoricalTouchMajor(i, h);
      } else {
        major = ev.GetTouchMajor(i);
      }
      if (major < touch_min_major_)
        major = touch_min_major_;
      if (major > touch_max_major_)
        major = touch_max_major_;
      total += major;

      if (base::IsNaN(touch_upper_) || major > touch_upper_) {
        touch_upper_ = major;
      }
      if (base::IsNaN(touch_lower_) || major < touch_lower_) {
        touch_lower_ = major;
      }

      if (has_last_accepted) {
        const float major_delta = major - touch_history_last_accepted_;
        const int direction_sig =
            major_delta > 0 ? 1 : (major_delta < 0 ? -1 : 0);
        if (direction_sig != touch_history_direction_ ||
            (direction_sig == 0 && touch_history_direction_ == 0)) {
          touch_history_direction_ = direction_sig;
          touch_history_last_accepted_time_ = h < history_size
                                                  ? ev.GetHistoricalEventTime(h)
                                                  : ev.GetEventTime();
          accept = false;
        }
      }
    }
    sample_count += pointersample_count;
  }

  const float avg = total / sample_count;

  if (accept) {
    float new_accepted = (touch_upper_ + touch_lower_ + avg) / 3;
    touch_upper_ = (touch_upper_ + new_accepted) / 2;
    touch_lower_ = (touch_lower_ + new_accepted) / 2;
    touch_history_last_accepted_ = new_accepted;
    touch_history_direction_ = 0;
    touch_history_last_accepted_time_ = ev.GetEventTime();
  }
}

void ScaleGestureDetector::ResetTouchHistory() {
  touch_upper_ = std::numeric_limits<float>::quiet_NaN();
  touch_lower_ = std::numeric_limits<float>::quiet_NaN();
  touch_history_last_accepted_ = std::numeric_limits<float>::quiet_NaN();
  touch_history_direction_ = 0;
  touch_history_last_accepted_time_ = base::TimeTicks();
}

void ScaleGestureDetector::ResetScaleWithSpan(float span) {
  in_progress_ = false;
  initial_span_ = span;
  double_tap_mode_ = DOUBLE_TAP_MODE_NONE;
}

}  // namespace ui
