// 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_input() {
}

void update_input() {
  using namespace blit;

  if(!hid_keyboard_detected && !hid_gamepad_id) {
    blit::api_data.buttons = 0;
    return;
  }

  uint32_t new_buttons = 0;

  // 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);

  api_data.buttons = new_buttons;

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