// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/wayland/dev_input.h"

#include <linux/input.h>
#include <string.h>

#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/wayland/application_wayland.h"

namespace starboard {
namespace shared {
namespace wayland {

namespace {

// YouTube Technical Requirement 2018 (2016/11/1 - Initial draft)
// 9.5 The device MUST dispatch the following key events, as appropriate:
//  * Window.keydown
//      * After a key is held down for 500ms, the Window.keydown event
//        MUST repeat every 50ms until a user stops holding the key down.
//  * Window.keyup
const SbTime kKeyHoldTime = 500 * kSbTimeMillisecond;
const SbTime kKeyRepeatTime = 50 * kSbTimeMillisecond;

void SeatHandleCapabilities(void* data,
                            struct wl_seat* seat,
                            unsigned int caps) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnSeatCapabilitiesChanged(seat, caps);
}

const struct wl_seat_listener seat_listener = {
    &SeatHandleCapabilities,
};

#define KEY_INFO_BUTTON 0xbc

// Converts an input_event code into an SbKey.
SbKey KeyCodeToSbKey(uint16_t code) {
  switch (code) {
    case KEY_BACKSPACE:
      return kSbKeyBack;
    case KEY_DELETE:
      return kSbKeyDelete;
    case KEY_TAB:
      return kSbKeyTab;
    case KEY_LINEFEED:
    case KEY_ENTER:
    case KEY_KPENTER:
      return kSbKeyReturn;
    case KEY_CLEAR:
      return kSbKeyClear;
    case KEY_SPACE:
      return kSbKeySpace;
    case KEY_HOME:
      return kSbKeyHome;
    case KEY_END:
      return kSbKeyEnd;
    case KEY_PAGEUP:
      return kSbKeyPrior;
    case KEY_PAGEDOWN:
      return kSbKeyNext;
    case KEY_LEFT:
      return kSbKeyLeft;
    case KEY_RIGHT:
      return kSbKeyRight;
    case KEY_DOWN:
      return kSbKeyDown;
    case KEY_UP:
      return kSbKeyUp;
    case KEY_ESC:
      return kSbKeyEscape;
    case KEY_KATAKANA:
    case KEY_HIRAGANA:
    case KEY_KATAKANAHIRAGANA:
      return kSbKeyKana;
    case KEY_HANGEUL:
      return kSbKeyHangul;
    case KEY_HANJA:
      return kSbKeyHanja;
    case KEY_HENKAN:
      return kSbKeyConvert;
    case KEY_MUHENKAN:
      return kSbKeyNonconvert;
    case KEY_ZENKAKUHANKAKU:
      return kSbKeyDbeDbcschar;
    case KEY_A:
      return kSbKeyA;
    case KEY_B:
      return kSbKeyB;
    case KEY_C:
      return kSbKeyC;
    case KEY_D:
      return kSbKeyD;
    case KEY_E:
      return kSbKeyE;
    case KEY_F:
      return kSbKeyF;
    case KEY_G:
      return kSbKeyG;
    case KEY_H:
      return kSbKeyH;
    case KEY_I:
      return kSbKeyI;
    case KEY_J:
      return kSbKeyJ;
    case KEY_K:
      return kSbKeyK;
    case KEY_L:
      return kSbKeyL;
    case KEY_M:
      return kSbKeyM;
    case KEY_N:
      return kSbKeyN;
    case KEY_O:
      return kSbKeyO;
    case KEY_P:
      return kSbKeyP;
    case KEY_Q:
      return kSbKeyQ;
    case KEY_R:
      return kSbKeyR;
    case KEY_S:
      return kSbKeyS;
    case KEY_T:
      return kSbKeyT;
    case KEY_U:
      return kSbKeyU;
    case KEY_V:
      return kSbKeyV;
    case KEY_W:
      return kSbKeyW;
    case KEY_X:
      return kSbKeyX;
    case KEY_Y:
      return kSbKeyY;
    case KEY_Z:
      return kSbKeyZ;

    case KEY_0:
      return kSbKey0;
    case KEY_1:
      return kSbKey1;
    case KEY_2:
      return kSbKey2;
    case KEY_3:
      return kSbKey3;
    case KEY_4:
      return kSbKey4;
    case KEY_5:
      return kSbKey5;
    case KEY_6:
      return kSbKey6;
    case KEY_7:
      return kSbKey7;
    case KEY_8:
      return kSbKey8;
    case KEY_9:
      return kSbKey9;

    case KEY_NUMERIC_0:
    case KEY_NUMERIC_1:
    case KEY_NUMERIC_2:
    case KEY_NUMERIC_3:
    case KEY_NUMERIC_4:
    case KEY_NUMERIC_5:
    case KEY_NUMERIC_6:
    case KEY_NUMERIC_7:
    case KEY_NUMERIC_8:
    case KEY_NUMERIC_9:
      return static_cast<SbKey>(kSbKey0 + (code - KEY_NUMERIC_0));

    case KEY_KP0:
      return kSbKeyNumpad0;
    case KEY_KP1:
      return kSbKeyNumpad1;
    case KEY_KP2:
      return kSbKeyNumpad2;
    case KEY_KP3:
      return kSbKeyNumpad3;
    case KEY_KP4:
      return kSbKeyNumpad4;
    case KEY_KP5:
      return kSbKeyNumpad5;
    case KEY_KP6:
      return kSbKeyNumpad6;
    case KEY_KP7:
      return kSbKeyNumpad7;
    case KEY_KP8:
      return kSbKeyNumpad8;
    case KEY_KP9:
      return kSbKeyNumpad9;

    case KEY_KPASTERISK:
      return kSbKeyMultiply;
    case KEY_KPDOT:
      return kSbKeyDecimal;
    case KEY_KPSLASH:
      return kSbKeyDivide;
    case KEY_KPPLUS:
    case KEY_EQUAL:
      return kSbKeyOemPlus;
    case KEY_COMMA:
      return kSbKeyOemComma;
    case KEY_KPMINUS:
    case KEY_MINUS:
      return kSbKeyOemMinus;
    case KEY_DOT:
      return kSbKeyOemPeriod;
    case KEY_SEMICOLON:
      return kSbKeyOem1;
    case KEY_SLASH:
      return kSbKeyOem2;
    case KEY_GRAVE:
      return kSbKeyOem3;
    case KEY_LEFTBRACE:
      return kSbKeyOem4;
    case KEY_BACKSLASH:
      return kSbKeyOem5;
    case KEY_RIGHTBRACE:
      return kSbKeyOem6;
    case KEY_APOSTROPHE:
      return kSbKeyOem7;
    case KEY_LEFTSHIFT:
    case KEY_RIGHTSHIFT:
      return kSbKeyShift;
    case KEY_LEFTCTRL:
    case KEY_RIGHTCTRL:
      return kSbKeyControl;
    case KEY_LEFTMETA:
    case KEY_RIGHTMETA:
    case KEY_LEFTALT:
    case KEY_RIGHTALT:
      return kSbKeyMenu;
    case KEY_PAUSE:
      return kSbKeyPause;
    case KEY_CAPSLOCK:
      return kSbKeyCapital;
    case KEY_NUMLOCK:
      return kSbKeyNumlock;
    case KEY_SCROLLLOCK:
      return kSbKeyScroll;
    case KEY_SELECT:
      return kSbKeySelect;
    case KEY_PRINT:
      return kSbKeyPrint;
    case KEY_INSERT:
      return kSbKeyInsert;
    case KEY_HELP:
      return kSbKeyHelp;
    case KEY_MENU:
      return kSbKeyApps;
    case KEY_FN_F1:
    case KEY_FN_F2:
    case KEY_FN_F3:
    case KEY_FN_F4:
    case KEY_FN_F5:
    case KEY_FN_F6:
    case KEY_FN_F7:
    case KEY_FN_F8:
    case KEY_FN_F9:
    case KEY_FN_F10:
    case KEY_FN_F11:
    case KEY_FN_F12:
      return static_cast<SbKey>(kSbKeyF1 + (code - KEY_FN_F1));

    // For supporting multimedia buttons on a USB keyboard.
    case KEY_BACK:
      return kSbKeyBrowserBack;
    case KEY_FORWARD:
      return kSbKeyBrowserForward;
    case KEY_REFRESH:
      return kSbKeyBrowserRefresh;
    case KEY_STOP:
      return kSbKeyBrowserStop;
    case KEY_SEARCH:
      return kSbKeyBrowserSearch;
    case KEY_FAVORITES:
      return kSbKeyBrowserFavorites;
    case KEY_HOMEPAGE:
      return kSbKeyBrowserHome;
    case KEY_MUTE:
      return kSbKeyVolumeMute;
    case KEY_VOLUMEDOWN:
      return kSbKeyVolumeDown;
    case KEY_VOLUMEUP:
      return kSbKeyVolumeUp;
    case KEY_NEXTSONG:
      return kSbKeyMediaNextTrack;
    case KEY_PREVIOUSSONG:
      return kSbKeyMediaPrevTrack;
    case KEY_STOPCD:
      return kSbKeyMediaStop;
    case KEY_PLAYPAUSE:
      return kSbKeyMediaPlayPause;
    case KEY_MAIL:
      return kSbKeyMediaLaunchMail;
    case KEY_CALC:
      return kSbKeyMediaLaunchApp2;
    case KEY_WLAN:
      return kSbKeyWlan;
    case KEY_POWER:
      return kSbKeyPower;
    case KEY_BRIGHTNESSDOWN:
      return kSbKeyBrightnessDown;
    case KEY_BRIGHTNESSUP:
      return kSbKeyBrightnessUp;

    case KEY_INFO_BUTTON:
      return kSbKeyF1;
  }
  SB_DLOG(WARNING) << "Unknown code: 0x" << std::hex << code;
  return kSbKeyUnknown;
}  // NOLINT(readability/fn_size)

// Get a SbKeyLocation from an input_event.code.
SbKeyLocation KeyCodeToSbKeyLocation(uint16_t code) {
  switch (code) {
    case KEY_LEFTALT:
    case KEY_LEFTCTRL:
    case KEY_LEFTMETA:
    case KEY_LEFTSHIFT:
      return kSbKeyLocationLeft;
    case KEY_RIGHTALT:
    case KEY_RIGHTCTRL:
    case KEY_RIGHTMETA:
    case KEY_RIGHTSHIFT:
      return kSbKeyLocationRight;
  }

  return kSbKeyLocationUnspecified;
}

void KeyboardHandleKeyMap(void* data,
                          struct wl_keyboard* keyboard,
                          uint32_t format,
                          int fd,
                          uint32_t size) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleKeyMap(keyboard, format, fd, size);
}

void KeyboardHandleEnter(void* data,
                         struct wl_keyboard* keyboard,
                         uint32_t serial,
                         struct wl_surface* surface,
                         struct wl_array* keys) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleEnter(keyboard, serial, surface, keys);
}

void KeyboardHandleLeave(void* data,
                         struct wl_keyboard* keyboard,
                         uint32_t serial,
                         struct wl_surface* surface) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleLeave(keyboard, serial, surface);
}

void KeyboardHandleKey(void* data,
                       struct wl_keyboard* keyboard,
                       uint32_t serial,
                       uint32_t time,
                       uint32_t key,
                       uint32_t state) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleKey(keyboard, serial, time, key, state);
}

void KeyboardHandleModifiers(void* data,
                             struct wl_keyboard* keyboard,
                             uint32_t serial,
                             uint32_t mods_depressed,
                             uint32_t mods_latched,
                             uint32_t mods_locked,
                             uint32_t group) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleModifiers(keyboard, serial, mods_depressed,
                                       mods_latched, mods_locked, group);
}

const struct wl_keyboard_listener keyboard_listener = {
    &KeyboardHandleKeyMap, &KeyboardHandleEnter,     &KeyboardHandleLeave,
    &KeyboardHandleKey,    &KeyboardHandleModifiers,
};

}  // namespace

DevInput::DevInput()
    : wl_seat_(NULL),
      wl_keyboard_(NULL),
      key_repeat_event_id_(kSbEventIdInvalid),
      key_repeat_interval_(kKeyHoldTime),
      key_modifiers_(0),
      window_(kSbWindowInvalid) {}

bool DevInput::OnGlobalObjectAvailable(struct wl_registry* registry,
                                       uint32_t name,
                                       const char* interface,
                                       uint32_t version) {
  if (strcmp(interface, "wl_seat") == 0) {
    wl_seat_ = static_cast<wl_seat*>(
        wl_registry_bind(registry, name, &wl_seat_interface, 1));
    SB_DCHECK(wl_seat_);
    wl_seat_add_listener(wl_seat_, &seat_listener, this);
    return true;
  }
  return false;
}

void DevInput::OnSeatCapabilitiesChanged(struct wl_seat* seat,
                                         unsigned int caps) {
  SB_DLOG(INFO) << "[Key] seat_handle_capabilities caps: " << caps;
  if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
    wl_keyboard_ = static_cast<wl_keyboard*>(wl_seat_get_keyboard(seat));
    if (wl_keyboard_)
      wl_keyboard_add_listener(wl_keyboard_, &keyboard_listener, this);
  } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
    if (wl_keyboard_)
      wl_keyboard_destroy(wl_keyboard_);
    wl_keyboard_ = NULL;
  }
}

void DevInput::OnKeyboardHandleKeyMap(struct wl_keyboard* keyboard,
                                      uint32_t format,
                                      int fd,
                                      uint32_t size) {
  SB_DLOG(INFO) << "[Key] Keyboard keymap";
}

void DevInput::OnKeyboardHandleEnter(struct wl_keyboard* keyboard,
                                     uint32_t serial,
                                     struct wl_surface* surface,
                                     struct wl_array* keys) {
  SB_DLOG(INFO) << "[Key] Keyboard gained focus";
}

void DevInput::OnKeyboardHandleLeave(struct wl_keyboard* keyboard,
                                     uint32_t serial,
                                     struct wl_surface* surface) {
  SB_DLOG(INFO) << "[Key] Keyboard lost focus";
  DeleteRepeatKey();
}

void DevInput::OnKeyboardHandleModifiers(struct wl_keyboard* keyboard,
                                         uint32_t serial,
                                         uint32_t mods_depressed,
                                         uint32_t mods_latched,
                                         uint32_t mods_locked,
                                         uint32_t group) {
  // Convert to SbKeyModifiers.
  unsigned int modifiers = kSbKeyModifiersNone;

  if (mods_depressed & 1)
    modifiers |= kSbKeyModifiersShift;
  if (mods_depressed & 4)
    modifiers |= kSbKeyModifiersCtrl;
  if (mods_depressed & 8)
    modifiers |= kSbKeyModifiersAlt;

  SB_DLOG(INFO) << "[Key] Modifiers depressed " << mods_depressed
                << ", latched " << mods_latched << ", locked " << mods_locked
                << ", group " << group << ", key modifiers " << modifiers;

  key_modifiers_ = modifiers;
}

void DevInput::OnKeyboardHandleKey(struct wl_keyboard* keyboard,
                                   uint32_t serial,
                                   uint32_t time,
                                   uint32_t key,
                                   uint32_t state) {
  bool repeatable =
      (key == KEY_LEFT || key == KEY_RIGHT || key == KEY_UP || key == KEY_DOWN);
  SB_DLOG(INFO) << "[Key] Key :" << key << ", state:" << state << " repeatable "
                << repeatable << " key_repeat_key_ " << key_repeat_key_
                << " key_repeat_state_ " << key_repeat_state_;
  if (state && repeatable && key == key_repeat_key_ && key_repeat_state_)
    return;

  if (repeatable) {
    CreateKey(key, state, true);
  } else {
    CreateKey(key, state, false);
  }
}

void DevInput::CreateRepeatKey() {
  if (!key_repeat_state_) {
    return;
  }

  if (key_repeat_interval_) {
    key_repeat_interval_ = kKeyRepeatTime;
  }

  CreateKey(key_repeat_key_, key_repeat_state_, true);
}

void DevInput::CreateKey(int key, int state, bool is_repeat) {
  SbInputData* data = new SbInputData();
  SbMemorySet(data, 0, sizeof(*data));
  data->window = window_;
  data->type = (state == 0 ? kSbInputEventTypeUnpress : kSbInputEventTypePress);
  data->device_type = kSbInputDeviceTypeRemote;
  data->device_id = 1;  // kKeyboardDeviceId;
  data->key = KeyCodeToSbKey(key);
  data->key_location = KeyCodeToSbKeyLocation(key);
  data->key_modifiers = key_modifiers_;
  ApplicationWayland::Get()->InjectInputEvent(data);

  DeleteRepeatKey();

  if (is_repeat && state) {
    key_repeat_key_ = key;
    key_repeat_state_ = state;
    key_repeat_event_id_ = SbEventSchedule(
        [](void* data) {
          DevInput* dev_input = reinterpret_cast<DevInput*>(data);
          dev_input->CreateRepeatKey();
        },
        this, key_repeat_interval_);
  } else {
    key_repeat_interval_ = kKeyHoldTime;
  }
}

void DevInput::DeleteRepeatKey() {
  key_repeat_state_ = 0;
  if (key_repeat_event_id_ != kSbEventIdInvalid) {
    SbEventCancel(key_repeat_event_id_);
    key_repeat_event_id_ = kSbEventIdInvalid;
  }
}

}  // namespace wayland
}  // namespace shared
}  // namespace starboard
