// Copyright 2018 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 "ash/events/select_to_speak_event_handler.h"

#include <string>
#include <utility>

#include "ash/accessibility/accessibility_controller.h"
#include "ash/public/interfaces/accessibility_controller.mojom.h"
#include "ash/shell.h"
#include "base/macros.h"
#include "ui/aura/env.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event.h"
#include "ui/events/event_sink.h"

namespace ash {

const ui::KeyboardCode kSpeakSelectionKey = ui::VKEY_S;

SelectToSpeakEventHandler::SelectToSpeakEventHandler(
    mojom::SelectToSpeakEventHandlerDelegatePtr delegate_ptr)
    : delegate_ptr_(std::move(delegate_ptr)) {
  DCHECK(delegate_ptr_.is_bound());
  Shell::Get()->AddPreTargetHandler(this,
                                    ui::EventTarget::Priority::kAccessibility);
}

SelectToSpeakEventHandler::~SelectToSpeakEventHandler() {
  Shell::Get()->RemovePreTargetHandler(this);
}

bool SelectToSpeakEventHandler::IsSelectToSpeakEnabled() {
  return Shell::Get()->accessibility_controller()->IsSelectToSpeakEnabled();
}

void SelectToSpeakEventHandler::SetSelectToSpeakStateSelecting(
    bool is_selecting) {
  if (is_selecting && state_ == INACTIVE) {
    // The extension has requested that it enter SELECTING state, and we
    // aren't already in a SELECTING state. Prepare to start capturing events
    // from stylus, mouse or touch.
    // If we are already in any state besides INACTIVE then there is no
    // work that needs to be done.
    state_ = SELECTION_REQUESTED;
  } else if (!is_selecting) {
    // If we were using search + mouse, continue to wait for the search key
    // up event by not resetting the state to INACTIVE.
    if (state_ != MOUSE_RELEASED)
      state_ = INACTIVE;
    touch_id_ = ui::PointerDetails::kUnknownPointerId;
    touch_type_ = ui::EventPointerType::POINTER_TYPE_UNKNOWN;
  }
}

void SelectToSpeakEventHandler::FlushMojoForTest() {
  delegate_ptr_.FlushForTesting();
}

void SelectToSpeakEventHandler::OnKeyEvent(ui::KeyEvent* event) {
  DCHECK(IsSelectToSpeakEnabled());
  DCHECK(event);

  ui::KeyboardCode key_code = event->key_code();
  bool cancel_event = false;

  // Update the state when pressing and releasing the Search key (VKEY_LWIN).
  if (key_code == ui::VKEY_LWIN) {
    if (event->type() == ui::ET_KEY_PRESSED && state_ == INACTIVE) {
      state_ = SEARCH_DOWN;
    } else if (event->type() == ui::ET_KEY_RELEASED) {
      if (state_ == CAPTURING_MOUSE) {
        cancel_event = true;
        state_ = WAIT_FOR_MOUSE_RELEASE;
      } else if (state_ == MOUSE_RELEASED) {
        cancel_event = true;
        state_ = INACTIVE;
      } else if (state_ == CAPTURING_SPEAK_SELECTION_KEY) {
        cancel_event = true;
        state_ = WAIT_FOR_SPEAK_SELECTION_KEY_RELEASE;
      } else if (state_ == SPEAK_SELECTION_KEY_RELEASED) {
        cancel_event = true;
        state_ = INACTIVE;
      } else if (state_ == SEARCH_DOWN) {
        // They just tapped the search key without clicking the mouse.
        // Don't cancel this event -- the search key may still be used
        // by another part of Chrome, and we didn't use it here.
        state_ = INACTIVE;
      }
    }
  } else if (key_code == kSpeakSelectionKey) {
    if (event->type() == ui::ET_KEY_PRESSED &&
        (state_ == SEARCH_DOWN || state_ == SPEAK_SELECTION_KEY_RELEASED)) {
      // They pressed the S key while search was down.
      // It's possible to press the selection key multiple times to read
      // the same region over and over, so state S_RELEASED can become state
      // CAPTURING_SPEAK_SELECTION_KEY if the search key is not lifted.
      cancel_event = true;
      state_ = CAPTURING_SPEAK_SELECTION_KEY;
    } else if (event->type() == ui::ET_KEY_RELEASED) {
      if (state_ == CAPTURING_SPEAK_SELECTION_KEY) {
        // They released the speak selection key while it was being captured.
        cancel_event = true;
        state_ = SPEAK_SELECTION_KEY_RELEASED;
      } else if (state_ == WAIT_FOR_SPEAK_SELECTION_KEY_RELEASE) {
        // They have already released the search key
        cancel_event = true;
        state_ = INACTIVE;
      }
    }
  } else if (state_ == SEARCH_DOWN) {
    state_ = INACTIVE;
  }

  // Forward the key to the chrome process for the extension.
  delegate_ptr_->DispatchKeyEvent(ui::Event::Clone(*event));

  if (cancel_event)
    CancelEvent(event);
}

void SelectToSpeakEventHandler::OnMouseEvent(ui::MouseEvent* event) {
  DCHECK(IsSelectToSpeakEnabled());
  DCHECK(event);
  if (state_ == INACTIVE)
    return;

  if (event->type() == ui::ET_MOUSE_PRESSED) {
    if (state_ == SEARCH_DOWN || state_ == MOUSE_RELEASED)
      state_ = CAPTURING_MOUSE;
    else if (state_ == SELECTION_REQUESTED)
      state_ = CAPTURING_MOUSE_ONLY;
  }

  if (state_ == WAIT_FOR_MOUSE_RELEASE &&
      event->type() == ui::ET_MOUSE_RELEASED) {
    state_ = INACTIVE;
    return;
  }

  // Only forward the event to the extension if we are capturing mouse
  // events.
  if (state_ != CAPTURING_MOUSE && state_ != CAPTURING_MOUSE_ONLY)
    return;

  if (event->type() == ui::ET_MOUSE_RELEASED) {
    if (state_ == CAPTURING_MOUSE)
      state_ = MOUSE_RELEASED;
    else if (state_ == CAPTURING_MOUSE_ONLY)
      state_ = INACTIVE;
  }

  delegate_ptr_->DispatchMouseEvent(ui::Event::Clone(*event));

  if (event->type() == ui::ET_MOUSE_PRESSED ||
      event->type() == ui::ET_MOUSE_RELEASED)
    CancelEvent(event);
}

void SelectToSpeakEventHandler::OnTouchEvent(ui::TouchEvent* event) {
  DCHECK(IsSelectToSpeakEnabled());
  DCHECK(event);
  // Only capture touch events if selection was requested or we are capturing
  // touch events already.
  if (state_ != SELECTION_REQUESTED && state_ != CAPTURING_TOUCH_ONLY)
    return;

  // On a touch-down event, if selection was requested, we begin capturing
  // touch events.
  if (event->type() == ui::ET_TOUCH_PRESSED && state_ == SELECTION_REQUESTED &&
      touch_id_ == ui::PointerDetails::kUnknownPointerId) {
    state_ = CAPTURING_TOUCH_ONLY;
    touch_id_ = event->pointer_details().id;
    touch_type_ = event->pointer_details().pointer_type;
  }

  if (touch_id_ != event->pointer_details().id ||
      touch_type_ != event->pointer_details().pointer_type) {
    // If this was a different pointer, cancel the event and return early.
    // We only want to track one touch pointer at a time.
    CancelEvent(event);
    return;
  }

  // On a touch-up event, we go back to inactive state, but still forward the
  // event to the extension.
  if (event->type() == ui::ET_TOUCH_RELEASED &&
      state_ == CAPTURING_TOUCH_ONLY) {
    state_ = INACTIVE;
    touch_id_ = ui::PointerDetails::kUnknownPointerId;
    touch_type_ = ui::EventPointerType::POINTER_TYPE_UNKNOWN;
  }

  // Create a mouse event to send to the extension, describing the touch.
  // This is done because there is no RenderWidgetHost::ForwardTouchEvent,
  // and we already have mouse event plumbing in place for Select-to-Speak.
  ui::EventType type;
  switch (event->type()) {
    case ui::ET_TOUCH_PRESSED:
      type = ui::ET_MOUSE_PRESSED;
      break;
    case ui::ET_TOUCH_RELEASED:
    case ui::ET_TOUCH_CANCELLED:
      type = ui::ET_MOUSE_RELEASED;
      break;
    case ui::ET_TOUCH_MOVED:
      type = ui::ET_MOUSE_DRAGGED;
      break;
    default:
      return;
  }
  int flags = ui::EF_LEFT_MOUSE_BUTTON;
  ui::MouseEvent mutable_event(type, event->location(), event->root_location(),
                               event->time_stamp(), flags, flags);

  delegate_ptr_->DispatchMouseEvent(ui::Event::Clone(mutable_event));

  if (event->type() != ui::ET_TOUCH_MOVED) {
    // Don't cancel move events in case focus needs to change.
    CancelEvent(event);
  }
}

void SelectToSpeakEventHandler::CancelEvent(ui::Event* event) {
  DCHECK(event);
  if (event->cancelable()) {
    event->SetHandled();
    event->StopPropagation();
  }
}

}  // namespace ash
