// GPIO dpad + ABXY
#include "input.hpp"

#include "hardware/gpio.h"

#include "pico/binary_info.h"

#include "class/hid/hid.h"

#include "engine/api_private.hpp"
#include "engine/input.hpp"

// from USB code
extern uint32_t hid_gamepad_id;
extern bool hid_keyboard_detected;
extern uint8_t hid_joystick[2];
extern uint8_t hid_hat;
extern uint32_t hid_buttons;
extern uint8_t hid_keys[6];

struct GamepadMapping {
  uint32_t id; // vid:pid
  uint8_t a, b, x, y;
  uint8_t up, down, left, right; // if no hat
  uint8_t menu, home, joystick;
};

#define NO 0xFF

static const GamepadMapping gamepad_mappings[]{
  {0x15320705,  0,  1,  3,  4, NO, NO, NO, NO, 16, 15, 13}, // Razer Raiju Mobile
  {0x20D6A711,  2,  1,  3,  0, NO, NO, NO, NO,  8, 12, 10}, // PowerA wired Switch pro controller
  {0x2DC89018,  0,  1,  3,  4, NO, NO, NO, NO, 10, 11, NO}, // 8BitDo Zero 2
  {0x00000000,  0,  1,  2,  3, NO, NO, NO, NO,  4,  5,  6}  // probably wrong fallback
};

#undef NO

// hat -> dpad
const uint32_t dpad_map[]{
  blit::Button::DPAD_UP,
  blit::Button::DPAD_UP | blit::Button::DPAD_RIGHT,
  blit::Button::DPAD_RIGHT,
  blit::Button::DPAD_DOWN | blit::Button::DPAD_RIGHT,
  blit::Button::DPAD_DOWN,
  blit::Button::DPAD_DOWN | blit::Button::DPAD_LEFT,
  blit::Button::DPAD_LEFT,
  blit::Button::DPAD_UP | blit::Button::DPAD_LEFT,
  0
};

void init_usb_hid() {
}

void update_usb_hid(uint32_t &new_buttons, blit::Vec2 &new_joystick) {
  using namespace blit;

  if(!hid_keyboard_detected && !hid_gamepad_id)
    return;

  // keyboard
  if(hid_keyboard_detected) {

    for(int i = 0; i < 6; i++) {
      switch(hid_keys[i]) {
        case HID_KEY_ARROW_UP:
        case HID_KEY_W:
          new_buttons |= uint32_t(Button::DPAD_UP);
          break;
        case HID_KEY_ARROW_DOWN:
        case HID_KEY_S:
          new_buttons |= uint32_t(Button::DPAD_DOWN);
          break;
        case HID_KEY_ARROW_LEFT:
        case HID_KEY_A:
          new_buttons |= uint32_t(Button::DPAD_LEFT);
          break;
        case HID_KEY_ARROW_RIGHT:
        case HID_KEY_D:
          new_buttons |= uint32_t(Button::DPAD_RIGHT);
          break;

        case HID_KEY_Z:
        case HID_KEY_U:
          new_buttons |= uint32_t(Button::A);
          break;
        case HID_KEY_X:
        case HID_KEY_I:
          new_buttons |= uint32_t(Button::B);
          break;
        case HID_KEY_C:
        case HID_KEY_O:
          new_buttons |= uint32_t(Button::X);
          break;
        case HID_KEY_V:
        case HID_KEY_P:
          new_buttons |= uint32_t(Button::Y);
          break;

        case HID_KEY_1:
          new_buttons |= uint32_t(Button::HOME);
          break;

        case HID_KEY_2:
        case HID_KEY_ESCAPE:
          new_buttons |= uint32_t(Button::MENU);
          break;

        case HID_KEY_3:
          new_buttons |= uint32_t(Button::JOYSTICK);
          break;
      }
    }
  }

  if(!hid_gamepad_id)
    return;

  // gamepad
  auto mapping = gamepad_mappings;
  while(mapping->id && mapping->id != hid_gamepad_id)
    mapping++;

  new_buttons = new_buttons
              | dpad_map[hid_hat > 8 ? 8 : hid_hat]
              | (hid_buttons & (1 << mapping->left)     ? uint32_t(Button::DPAD_LEFT) : 0)
              | (hid_buttons & (1 << mapping->right)    ? uint32_t(Button::DPAD_RIGHT) : 0)
              | (hid_buttons & (1 << mapping->up)       ? uint32_t(Button::DPAD_UP) : 0)
              | (hid_buttons & (1 << mapping->down)     ? uint32_t(Button::DPAD_DOWN) : 0)
              | (hid_buttons & (1 << mapping->a)        ? uint32_t(Button::A) : 0)
              | (hid_buttons & (1 << mapping->b)        ? uint32_t(Button::B) : 0)
              | (hid_buttons & (1 << mapping->x)        ? uint32_t(Button::X) : 0)
              | (hid_buttons & (1 << mapping->y)        ? uint32_t(Button::Y) : 0)
              | (hid_buttons & (1 << mapping->menu)     ? uint32_t(Button::MENU) : 0)
              | (hid_buttons & (1 << mapping->home)     ? uint32_t(Button::HOME) : 0)
              | (hid_buttons & (1 << mapping->joystick) ? uint32_t(Button::JOYSTICK) : 0);

  new_joystick.x = (float(hid_joystick[0]) - 0x80) / 0x80;
  new_joystick.y = (float(hid_joystick[1]) - 0x80) / 0x80;
}

extern const InputDriver usb_hid_driver {
  init_usb_hid, update_usb_hid
};
