#include <stdio.h>

#ifdef __AVR__
 #include <avr/io.h>
 #include <avr/pgmspace.h>
#else
 #define PROGMEM
#endif

#define NUM_USB_HID_KEYCODES 255
#define LEN_KEYCODE_STR 4

char keylog[22] = {"KC:       ID: "};

// Quick and dirty way to display USB HID keycodes used in QMK
// USB HID keycodes from 0x0000 to 0x00FF are stored in a 4x256+1 length char
const char code_to_name[] PROGMEM = {
  "NO  " //0x00
  "TRNS"
  "?   "
  "?   "
  "A   "
  "B   "
  "C   "
  "D   "
  "E   "
  "F   "
  "G   "
  "H   "
  "I   "
  "J   "
  "K   "
  "L   "
  "M   " //0x10
  "N   "
  "O   "
  "P   "
  "Q   "
  "R   "
  "S   "
  "T   "
  "U   "
  "V   "
  "W   "
  "X   "
  "Y   "
  "Z   "
  "1   "
  "2   "
  "3   "  //0x20
  "4   "
  "5   "
  "6   "
  "7   "
  "8   "
  "9   "
  "0   "
  "ENT "
  "ESC "
  "BSPC"
  "TAB "
  "SPC "
  "MINS"
  "EQL "
  "LBRC"
  "RBRC" //0x30
  "BSLS"
  "NUHS"
  "SCLN"
  "QUOT"
  "GRV "
  "COMM"
  "DOT "
  "SLSH"
  "CAPS"
  "F1  "
  "F2  "
  "F3  "
  "F4  "
  "F5  "
  "F6  "
  "F7  " //0x40
  "F8  "
  "F9  "
  "F10 "
  "F11 "
  "F12 "
  "PSCR"
  "SLCK"
  "PAUS"
  "INS "
  "HOME"
  "PGUP"
  "DEL "
  "END "
  "PGDN"
  "RGHT"
  "LEFT" //0x50
  "DOWN"
  "UP  "
  "NLCK"
  "PSLS"
  "PAST"
  "PMNS"
  "PPLS"
  "PENT"
  "P1  "
  "P2  "
  "P3  "
  "P4  "
  "P5  "
  "P6  "
  "P7  "
  "P8  " //0x60
  "P9  "
  "P0  "
  "PDOT"
  "NUBS"
  "APP "
  "POW "
  "PEQL"
  "F13 "
  "F14 "
  "F15 "
  "F16 "
  "F17 "
  "F18 "
  "F19 "
  "F20 "
  "F21 " //0x70
  "F22 "
  "F23 "
  "F24 "
  "EXEC"
  "HELP"
  "MENU"
  "SLCT"
  "STOP"
  "AGIN"
  "UNDO"
  "CUT "
  "COPY"
  "PSTE"
  "FIND"
  "_MUT"
  "_VUP" //0x80
  "_VDN"
  "LCAP"
  "LNUM"
  "LSCR"
  "PCMM"
  "PEQA"
  "INT1"
  "INT2"
  "INT3"
  "INT4"
  "INT5"
  "INT6"
  "INT7"
  "INT8"
  "INT9"
  "LAN1" //0x90
  "LAN2"
  "LAN3"
  "LAN4"
  "LAN5"
  "LAN6"
  "LAN7"
  "LAN8"
  "LAN9"
  "ERAS"
  "SYSR"
  "CNCL"
  "CLR "
  "PRIR"
  "RTRN"
  "SEP "
  "OUT " //0xA0
  "OPER"
  "CLRA"
  "CSEL"
  "ESEL"
  "PWR " //0xA5
  "SLEP"
  "WAKE"
  "MUTE"
  "VOLU"
  "VOLD"
  "MNXT"
  "MPRV"
  "MSTP"
  "MPLY"
  "MSEL"
  "EJCT" //0xB0
  "MAIL"
  "CALC"
  "MYCM"
  "WSCH"
  "WHOM"
  "WBAK"
  "WFWD"
  "WSTP"
  "WREF"
  "WFAV"
  "MFFD"
  "MRWD"
  "BRIU"
  "BRID"
  "?   "
  "FN0 " //0xC0
  "FN1 "
  "FN2 "
  "FN3 "
  "FN4 "
  "FN5 "
  "FN6 "
  "FN7 "
  "FN8 "
  "FN9 "
  "FN10"
  "FN11"
  "FN12"
  "FN13"
  "FN14"
  "FN15"
  "FN16" //0xD0
  "FN17"
  "FN18"
  "FN19"
  "FN20"
  "FN21"
  "FN22"
  "FN23"
  "FN24"
  "FN25"
  "FN26"
  "FN27"
  "FN28"
  "FN29"
  "FN30"
  "FN31"
  "LCTL" //0xE0
  "LSFT"
  "LALT"
  "LGUI"
  "RCTL"
  "RSFT"
  "RALT"
  "RGUI"
  "?   "
  "?   "
  "?   "
  "?   "
  "?   "
  "?   "
  "?   "
  "?   "
  "MS_U" //0xF0
  "MS_D"
  "MS_L"
  "MS_R"
  "BTN1"
  "BTN2"
  "BTN3"
  "BTN4"
  "BTN5"
  "WH_U"
  "WH_D"
  "WH_L"
  "WH_R"
  "ACL0"
  "ACL1"
  "ACL2"
};

void set_keylog(uint16_t keycode)
{
  char name[LEN_KEYCODE_STR+1] = "?   ";

  if (keycode <= NUM_USB_HID_KEYCODES) {
    for (uint8_t k = 0; k < LEN_KEYCODE_STR; k++) {
      name[k] =  pgm_read_byte_near(code_to_name + keycode * LEN_KEYCODE_STR + k);
    }
  } else if (keycode > NUM_USB_HID_KEYCODES) {
    snprintf(name, sizeof(name), "QMK ");
  }

  // update keylog
  snprintf(keylog, sizeof(keylog), "KC: %s  ID: %d", name, keycode);
}

const char *read_keylog(void) {
  return keylog;
}