// Copyright 2013 The Flutter 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 "flutter/shell/platform/fuchsia/flutter/keyboard.h"

#include <fuchsia/input/cpp/fidl.h>
#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/input3/cpp/fidl.h>

#include <iostream>

namespace flutter_runner {

using fuchsia::input::Key;
using fuchsia::ui::input::kModifierCapsLock;
using fuchsia::ui::input::kModifierLeftAlt;
using fuchsia::ui::input::kModifierLeftControl;
using fuchsia::ui::input::kModifierLeftShift;
using fuchsia::ui::input::kModifierNone;
using fuchsia::ui::input::kModifierRightAlt;
using fuchsia::ui::input::kModifierRightControl;
using fuchsia::ui::input::kModifierRightShift;
using fuchsia::ui::input3::KeyEvent;
using fuchsia::ui::input3::KeyEventType;

namespace {

// A simple keymap from a QWERTY keyboard to code points. A value 0 means no
// code point has been assigned for the respective keypress. Column 0 is the
// code point without a level modifier active, and Column 1 is the code point
// with a level modifier (e.g. Shift key) active.
static const uint32_t QWERTY_TO_CODE_POINTS[][2] = {
    // 0x00
    {},
    {},
    {},
    {},
    // 0x04,
    {'a', 'A'},
    {'b', 'B'},
    {'c', 'C'},
    {'d', 'D'},
    // 0x08
    {'e', 'E'},
    {'f', 'F'},
    {'g', 'G'},
    {'h', 'H'},
    // 0x0c
    {'i', 'I'},
    {'j', 'J'},
    {'k', 'K'},
    {'l', 'L'},
    // 0x10
    {'m', 'M'},
    {'n', 'N'},
    {'o', 'O'},
    {'p', 'P'},
    // 0x14
    {'q', 'Q'},
    {'r', 'R'},
    {'s', 'S'},
    {'t', 'T'},
    // 0x18
    {'u', 'U'},
    {'v', 'V'},
    {'w', 'W'},
    {'x', 'X'},
    // 0x1c
    {'y', 'Y'},
    {'z', 'Z'},
    {'1', '!'},
    {'2', '@'},
    // 0x20
    {'3', '#'},
    {'4', '$'},
    {'5', '%'},
    {'6', '^'},
    // 0x24
    {'7', '&'},
    {'8', '*'},
    {'9', '('},
    {'0', ')'},
    // 0x28
    {},
    {},
    {},
    {},
    // 0x2c
    {' ', ' '},
    {'-', '_'},
    {'=', '+'},
    {'[', '{'},
    // 0x30
    {']', '}'},
    {'\\', '|'},
    {},
    {';', ':'},
    // 0x34
    {'\'', '"'},
    {'`', '~'},
    {',', '<'},
    {'.', '>'},
    // 0x38
    {'/', '?'},
    {},
    {},
    {},
    // 0x3c
    {},
    {},
    {},
    {},
    // 0x40
    {},
    {},
    {},
    {},
    // 0x44
    {},
    {},
    {},
    {},
    // 0x48
    {},
    {},
    {},
    {},
    // 0x4c
    {},
    {},
    {},
    {},
    // 0x50
    {},
    {},
    {},
    {},
    // 0x54
    {'/', 0},
    {'*', 0},
    {'-', 0},
    {'+', 0},
    // 0x58
    {},
    {'1', 0},
    {'2', 0},
    {'3', 0},
    // 0x5c
    {'4', 0},
    {'5', 0},
    {'6', 0},
    {'7', 0},
    // 0x60
    {'8', 0},
    {'9', 0},
    {'0', 0},
    {'.', 0},
};

}  // namespace

Keyboard::Keyboard()
    : any_events_received_(false),
      stateful_caps_lock_(false),
      left_shift_(false),
      right_shift_(false),
      left_alt_(false),
      right_alt_(false),
      left_ctrl_(false),
      right_ctrl_(false),
      last_event_() {}

bool Keyboard::ConsumeEvent(KeyEvent event) {
  if (!event.has_type()) {
    return false;
  }
  if (!event.has_key()) {
    return false;
  }
  // Check if the time sequence of the events is correct.

  last_event_ = std::move(event);
  any_events_received_ = true;
  const Key& key = last_event_.key();
  const KeyEventType& event_type = last_event_.type();
  switch (event_type) {
    // For modifier keys, a SYNC is the same as a press.
    case KeyEventType::SYNC:
      switch (key) {
        case Key::CAPS_LOCK:
          stateful_caps_lock_ = true;
          break;
        case Key::LEFT_ALT:
          left_alt_ = true;
          break;
        case Key::LEFT_CTRL:
          left_ctrl_ = true;
          break;
        case Key::LEFT_SHIFT:
          left_shift_ = true;
          break;
        case Key::RIGHT_ALT:
          right_alt_ = true;
          break;
        case Key::RIGHT_CTRL:
          right_ctrl_ = true;
          break;
        case Key::RIGHT_SHIFT:
          right_shift_ = true;
          break;
        default:
          // no-op
          break;
      }
      break;
    case KeyEventType::PRESSED:
      switch (key) {
        case Key::CAPS_LOCK:
          stateful_caps_lock_ = !stateful_caps_lock_;
          break;
        case Key::LEFT_ALT:
          left_alt_ = true;
          break;
        case Key::LEFT_CTRL:
          left_ctrl_ = true;
          break;
        case Key::LEFT_SHIFT:
          left_shift_ = true;
          break;
        case Key::RIGHT_ALT:
          right_alt_ = true;
          break;
        case Key::RIGHT_CTRL:
          right_ctrl_ = true;
          break;
        case Key::RIGHT_SHIFT:
          right_shift_ = true;
          break;
        default:
          // No-op
          break;
      }
      break;
    case KeyEventType::RELEASED:
      switch (key) {
        case Key::CAPS_LOCK:
          // No-op.
          break;
        case Key::LEFT_ALT:
          left_alt_ = false;
          break;
        case Key::LEFT_CTRL:
          left_ctrl_ = false;
          break;
        case Key::LEFT_SHIFT:
          left_shift_ = false;
          break;
        case Key::RIGHT_ALT:
          right_alt_ = false;
          break;
        case Key::RIGHT_CTRL:
          right_ctrl_ = false;
          break;
        case Key::RIGHT_SHIFT:
          right_shift_ = false;
          break;
        default:
          // No-op
          break;
      }
      break;
    case KeyEventType::CANCEL:
      // No-op?
      break;
    default:
      // No-op
      break;
  }
  return false;
}

bool Keyboard::IsShift() {
  return left_shift_ | right_shift_ | stateful_caps_lock_;
}

bool Keyboard::IsKeys() {
  return (static_cast<uint64_t>(last_event_.key()) & 0xFFFF0000) == 0x00070000;
}

uint32_t Keyboard::Modifiers() {
  return kModifierNone + (kModifierLeftShift * left_shift_) +
         (kModifierLeftAlt * left_alt_) + (kModifierLeftControl * left_ctrl_) +
         (kModifierRightShift * right_shift_) +
         (kModifierRightAlt * right_alt_) +
         (kModifierRightControl * right_ctrl_) +
         (kModifierCapsLock * stateful_caps_lock_);
}

uint32_t Keyboard::LastCodePoint() {
  static const int qwerty_map_size =
      sizeof(QWERTY_TO_CODE_POINTS) / sizeof(QWERTY_TO_CODE_POINTS[0]);
  if (!IsKeys()) {
    return 0;
  }
  const auto usage = LastHIDUsage();
  if (usage < qwerty_map_size) {
    return QWERTY_TO_CODE_POINTS[usage][IsShift() & 1];
  }
  // Any other keys don't have a code point.
  return 0;
}

uint32_t Keyboard::LastHIDUsage() {
  return static_cast<uint64_t>(last_event_.key()) & 0xFFFF;
}

}  // namespace flutter_runner
