// 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/gestures/gesture_provider_impl.h"

#include "base/auto_reset.h"
#include "base/logging.h"
#include "ui/events/event.h"
#include "ui/events/gesture_detection/gesture_config_helper.h"
#include "ui/events/gesture_detection/gesture_event_data.h"
#include "ui/events/gestures/gesture_configuration.h"

namespace ui {

GestureProviderImpl::GestureProviderImpl(GestureProviderImplClient* client)
    : client_(client),
      filtered_gesture_provider_(ui::DefaultGestureProviderConfig(), this),
      handling_event_(false) {
  filtered_gesture_provider_.SetDoubleTapSupportForPlatformEnabled(false);
}

GestureProviderImpl::~GestureProviderImpl() {
}

bool GestureProviderImpl::OnTouchEvent(const TouchEvent& event) {
  int index = pointer_state_.FindPointerIndexOfId(event.touch_id());
  bool pointer_id_is_active = index != -1;

  if (event.type() == ET_TOUCH_PRESSED && pointer_id_is_active) {
    // Ignore touch press events if we already believe the pointer is down.
    return false;
  } else if (event.type() != ET_TOUCH_PRESSED && !pointer_id_is_active) {
    // We could have an active touch stream transfered to us, resulting in touch
    // move or touch up events without associated touch down events. Ignore
    // them.
    return false;
  }

  // If this is a touchmove event, and it isn't different from the last
  // event, ignore it.
  if (event.type() == ET_TOUCH_MOVED &&
      event.x() == pointer_state_.GetX(index) &&
      event.y() == pointer_state_.GetY(index)) {
    return false;
  }

  last_touch_event_latency_info_ = *event.latency();
  pointer_state_.OnTouch(event);

  bool result = filtered_gesture_provider_.OnTouchEvent(pointer_state_);
  pointer_state_.CleanupRemovedTouchPoints(event);
  return result;
}

void GestureProviderImpl::OnTouchEventAck(bool event_consumed) {
  DCHECK(pending_gestures_.empty());
  DCHECK(!handling_event_);
  base::AutoReset<bool> handling_event(&handling_event_, true);
  filtered_gesture_provider_.OnTouchEventAck(event_consumed);
  last_touch_event_latency_info_.Clear();
}

void GestureProviderImpl::OnGestureEvent(const GestureEventData& gesture) {
  GestureEventDetails details = gesture.details;
  details.set_oldest_touch_id(gesture.motion_event_id);

  if (gesture.type() == ET_GESTURE_TAP) {
    int tap_count = 1;
    if (previous_tap_ && IsConsideredDoubleTap(*previous_tap_, gesture))
      tap_count = 1 + (previous_tap_->details.tap_count() % 3);
    details.set_tap_count(tap_count);
    if (!previous_tap_)
      previous_tap_.reset(new GestureEventData(gesture));
    else
      *previous_tap_ = gesture;
    previous_tap_->details = details;
  } else if (gesture.type() == ET_GESTURE_TAP_CANCEL) {
    previous_tap_.reset();
  }

  scoped_ptr<ui::GestureEvent> event(
      new ui::GestureEvent(gesture.x, gesture.y, gesture.flags,
                           gesture.time - base::TimeTicks(), details));

  ui::LatencyInfo* gesture_latency = event->latency();

  gesture_latency->CopyLatencyFrom(last_touch_event_latency_info_,
                                   ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
  gesture_latency->CopyLatencyFrom(last_touch_event_latency_info_,
                                   ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
  gesture_latency->CopyLatencyFrom(
      last_touch_event_latency_info_,
      ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT);

  if (!handling_event_) {
    // Dispatching event caused by timer.
    client_->OnGestureEvent(event.get());
  } else {
    // Memory managed by ScopedVector pending_gestures_.
    pending_gestures_.push_back(event.release());
  }
}

ScopedVector<GestureEvent>* GestureProviderImpl::GetAndResetPendingGestures() {
  if (pending_gestures_.empty())
    return NULL;
  // Caller is responsible for deleting old_pending_gestures.
  ScopedVector<GestureEvent>* old_pending_gestures =
      new ScopedVector<GestureEvent>();
  old_pending_gestures->swap(pending_gestures_);
  return old_pending_gestures;
}

bool GestureProviderImpl::IsConsideredDoubleTap(
    const GestureEventData& previous_tap,
    const GestureEventData& current_tap) const {
  if (current_tap.time - previous_tap.time >
      base::TimeDelta::FromMilliseconds(
          ui::GestureConfiguration::max_time_between_double_click_in_ms())) {
    return false;
  }

  float double_tap_slop_square =
      GestureConfiguration::max_distance_between_taps_for_double_tap();
  double_tap_slop_square *= double_tap_slop_square;
  const float delta_x = previous_tap.x - current_tap.x;
  const float delta_y = previous_tap.y - current_tap.y;
  return (delta_x * delta_x + delta_y * delta_y < double_tap_slop_square);
}

}  // namespace content
