// Copyright 2016 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/chromeos/touch_accessibility_enabler.h"

#include <math.h>

#include <utility>

#include "base/logging.h"
#include "base/metrics/user_metrics.h"
#include "base/time/default_tick_clock.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event.h"
#include "ui/events/event_processor.h"
#include "ui/events/event_utils.h"

namespace ui {

namespace {

// Delay between timer callbacks. Each one plays a tick sound.
constexpr int kTimerDelayInMS = 500;

// The number of ticks of the timer before the first sound is generated.
constexpr int kTimerTicksOfFirstSoundFeedback = 6;

// The number of ticks of the timer before toggling spoken feedback.
constexpr int kTimerTicksToToggleSpokenFeedback = 10;

}  // namespace

TouchAccessibilityEnabler::TouchAccessibilityEnabler(
    aura::Window* root_window,
    TouchAccessibilityEnablerDelegate* delegate)
    : root_window_(root_window),
      delegate_(delegate),
      state_(NO_FINGERS_DOWN),
      tick_clock_(NULL) {
  DCHECK(root_window);
  DCHECK(delegate);
  root_window_->AddPreTargetHandler(this);
}

TouchAccessibilityEnabler::~TouchAccessibilityEnabler() {
  root_window_->RemovePreTargetHandler(this);
}

void TouchAccessibilityEnabler::OnTouchEvent(ui::TouchEvent* event) {
  // Skip events rewritten by TouchExplorationController, it will hand
  // us the unrewritten events directly.
  if (!(event->flags() & ui::EF_TOUCH_ACCESSIBILITY))
    HandleTouchEvent(*event);
}

void TouchAccessibilityEnabler::HandleTouchEvent(const ui::TouchEvent& event) {
  DCHECK(!(event.flags() & ui::EF_TOUCH_ACCESSIBILITY));
  const ui::EventType type = event.type();
  const gfx::PointF& location = event.location_f();
  const int touch_id = event.pointer_details().id;

  if (type == ui::ET_TOUCH_PRESSED) {
    touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
  } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
    auto iter = touch_locations_.find(touch_id);

    // Can happen if this object is constructed while fingers were down.
    if (iter == touch_locations_.end())
      return;

    touch_locations_.erase(touch_id);
  } else if (type == ui::ET_TOUCH_MOVED) {
    auto iter = touch_locations_.find(touch_id);

    // Can happen if this object is constructed while fingers were down.
    if (iter == touch_locations_.end())
      return;

    float delta = (location - iter->second).Length();
    if (delta > gesture_detector_config_.double_tap_slop) {
      state_ = WAIT_FOR_NO_FINGERS;
      CancelTimer();
      return;
    }
  } else {
    NOTREACHED() << "Unexpected event type received: " << event.name();
    return;
  }

  if (touch_locations_.size() == 0) {
    state_ = NO_FINGERS_DOWN;
    CancelTimer();
    return;
  }

  if (touch_locations_.size() > 2) {
    state_ = WAIT_FOR_NO_FINGERS;
    CancelTimer();
    return;
  }

  if (state_ == NO_FINGERS_DOWN && event.type() == ui::ET_TOUCH_PRESSED) {
    state_ = ONE_FINGER_DOWN;
  } else if (state_ == ONE_FINGER_DOWN &&
             event.type() == ui::ET_TOUCH_PRESSED) {
    state_ = TWO_FINGERS_DOWN;
    two_finger_start_time_ = Now();
    StartTimer();
  }
}

base::TimeTicks TouchAccessibilityEnabler::Now() {
  if (tick_clock_) {
    // This is the same as what EventTimeForNow() does, but here we do it
    // with a clock that can be replaced with a simulated clock for tests.
    return tick_clock_->NowTicks();
  }
  return ui::EventTimeForNow();
}

void TouchAccessibilityEnabler::StartTimer() {
  if (timer_.IsRunning())
    return;

  timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerDelayInMS),
               this, &ui::TouchAccessibilityEnabler::OnTimer);
}

void TouchAccessibilityEnabler::CancelTimer() {
  if (timer_.IsRunning())
    timer_.Stop();
}

void TouchAccessibilityEnabler::OnTimer() {
  base::TimeTicks now = Now();
  double tick_count_f =
      (now - two_finger_start_time_).InMillisecondsF() / kTimerDelayInMS;
  int tick_count = roundf(tick_count_f);

  if (tick_count == kTimerTicksOfFirstSoundFeedback) {
    base::RecordAction(
        base::UserMetricsAction("Accessibility.TwoFingersHeldDown"));
  }

  if (tick_count >= kTimerTicksOfFirstSoundFeedback &&
      tick_count < kTimerTicksToToggleSpokenFeedback) {
    delegate_->PlaySpokenFeedbackToggleCountdown(tick_count);
  }
  if (tick_count == kTimerTicksToToggleSpokenFeedback) {
    delegate_->ToggleSpokenFeedback();
    state_ = WAIT_FOR_NO_FINGERS;
  }
}

}  // namespace ui
