module NativeBindings.Keys

open BiMap

// Taken from https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
let private keyCodes = 
    BiMap.empty
        |> BiMap.add "VK_LBUTTON" 0x01
        |> BiMap.add "VK_RBUTTON" 0x02
        |> BiMap.add "VK_CANCEL" 0x03
        |> BiMap.add "VK_MBUTTON" 0x04
        |> BiMap.add "VK_XBUTTON1" 0x05
        |> BiMap.add "VK_XBUTTON2" 0x06
        |> BiMap.add "VK_BACK" 0x08
        |> BiMap.add "VK_TAB" 0x09
        |> BiMap.add "VK_CLEAR" 0x0C
        |> BiMap.add "VK_RETURN" 0x0D
        |> BiMap.add "VK_SHIFT" 0x10
        |> BiMap.add "VK_CONTROL" 0x11
        |> BiMap.add "VK_MENU" 0x12
        |> BiMap.add "VK_PAUSE" 0x13
        |> BiMap.add "VK_CAPITAL" 0x14
        |> BiMap.add "VK_KANA" 0x15
        |> BiMap.add "VK_HANGUEL" 0x15
        |> BiMap.add "VK_HANGUL" 0x15
        |> BiMap.add "VK_JUNJA" 0x17
        |> BiMap.add "VK_FINAL" 0x18
        |> BiMap.add "VK_HANJA" 0x19
        |> BiMap.add "VK_KANJI" 0x19
        |> BiMap.add "VK_ESCAPE" 0x1B
        |> BiMap.add "VK_CONVERT" 0x1C
        |> BiMap.add "VK_NONCONVERT" 0x1D
        |> BiMap.add "VK_ACCEPT" 0x1E
        |> BiMap.add "VK_MODECHANGE" 0x1F
        |> BiMap.add "VK_SPACE" 0x20
        |> BiMap.add "VK_PRIOR" 0x21
        |> BiMap.add "VK_NEXT" 0x22
        |> BiMap.add "VK_END" 0x23
        |> BiMap.add "VK_HOME" 0x24
        |> BiMap.add "VK_LEFT" 0x25
        |> BiMap.add "VK_UP" 0x26
        |> BiMap.add "VK_RIGHT" 0x27
        |> BiMap.add "VK_DOWN" 0x28
        |> BiMap.add "VK_SELECT" 0x29
        |> BiMap.add "VK_PRINT" 0x2A
        |> BiMap.add "VK_EXECUTE" 0x2B
        |> BiMap.add "VK_SNAPSHOT" 0x2C
        |> BiMap.add "VK_INSERT" 0x2D
        |> BiMap.add "VK_DELETE" 0x2E
        |> BiMap.add "VK_HELP" 0x2F
        |> BiMap.add "0" 0x30
        |> BiMap.add "1" 0x31
        |> BiMap.add "2" 0x32
        |> BiMap.add "3" 0x33
        |> BiMap.add "4" 0x34
        |> BiMap.add "5" 0x35
        |> BiMap.add "6" 0x36
        |> BiMap.add "7" 0x37
        |> BiMap.add "8" 0x38
        |> BiMap.add "9" 0x39
        |> BiMap.add "a" 0x41
        |> BiMap.add "b" 0x42
        |> BiMap.add "c" 0x43
        |> BiMap.add "d" 0x44
        |> BiMap.add "e" 0x45
        |> BiMap.add "f" 0x46
        |> BiMap.add "g" 0x47
        |> BiMap.add "h" 0x48
        |> BiMap.add "i" 0x49
        |> BiMap.add "j" 0x4A
        |> BiMap.add "k" 0x4B
        |> BiMap.add "l" 0x4C
        |> BiMap.add "m" 0x4D
        |> BiMap.add "n" 0x4E
        |> BiMap.add "o" 0x4F
        |> BiMap.add "p" 0x50
        |> BiMap.add "q" 0x51
        |> BiMap.add "r" 0x52
        |> BiMap.add "s" 0x53
        |> BiMap.add "t" 0x54
        |> BiMap.add "u" 0x55
        |> BiMap.add "v" 0x56
        |> BiMap.add "w" 0x57
        |> BiMap.add "x" 0x58
        |> BiMap.add "y" 0x59
        |> BiMap.add "z" 0x5A
        |> BiMap.add "VK_LWIN" 0x5B
        |> BiMap.add "VK_RWIN" 0x5C
        |> BiMap.add "VK_APPS" 0x5D
        |> BiMap.add "VK_SLEEP" 0x5F
        |> BiMap.add "VK_NUMPAD0" 0x60
        |> BiMap.add "VK_NUMPAD1" 0x61
        |> BiMap.add "VK_NUMPAD2" 0x62
        |> BiMap.add "VK_NUMPAD3" 0x63
        |> BiMap.add "VK_NUMPAD4" 0x64
        |> BiMap.add "VK_NUMPAD5" 0x65
        |> BiMap.add "VK_NUMPAD6" 0x66
        |> BiMap.add "VK_NUMPAD7" 0x67
        |> BiMap.add "VK_NUMPAD8" 0x68
        |> BiMap.add "VK_NUMPAD9" 0x69
        |> BiMap.add "VK_MULTIPLY" 0x6A
        |> BiMap.add "VK_ADD" 0x6B
        |> BiMap.add "VK_SEPARATOR" 0x6C
        |> BiMap.add "VK_SUBTRACT" 0x6D
        |> BiMap.add "VK_DECIMAL" 0x6E
        |> BiMap.add "VK_DIVIDE" 0x6F
        |> BiMap.add "VK_F1" 0x70
        |> BiMap.add "VK_F2" 0x71
        |> BiMap.add "VK_F3" 0x72
        |> BiMap.add "VK_F4" 0x73
        |> BiMap.add "VK_F5" 0x74
        |> BiMap.add "VK_F6" 0x75
        |> BiMap.add "VK_F7" 0x76
        |> BiMap.add "VK_F8" 0x77
        |> BiMap.add "VK_F9" 0x78
        |> BiMap.add "VK_F10" 0x79
        |> BiMap.add "VK_F11" 0x7A
        |> BiMap.add "VK_F12" 0x7B
        |> BiMap.add "VK_F13" 0x7C
        |> BiMap.add "VK_F14" 0x7D
        |> BiMap.add "VK_F15" 0x7E
        |> BiMap.add "VK_F16" 0x7F
        |> BiMap.add "VK_F17" 0x80
        |> BiMap.add "VK_F18" 0x81
        |> BiMap.add "VK_F19" 0x82
        |> BiMap.add "VK_F20" 0x83
        |> BiMap.add "VK_F21" 0x84
        |> BiMap.add "VK_F22" 0x85
        |> BiMap.add "VK_F23" 0x86
        |> BiMap.add "VK_F24" 0x87
        |> BiMap.add "VK_NUMLOCK" 0x90
        |> BiMap.add "VK_SCROLL" 0x91
        |> BiMap.add "VK_LSHIFT" 0xA0
        |> BiMap.add "VK_RSHIFT" 0xA1
        |> BiMap.add "VK_LCONTROL" 0xA2
        |> BiMap.add "VK_RCONTROL" 0xA3
        |> BiMap.add "VK_LMENU" 0xA4
        |> BiMap.add "VK_RMENU" 0xA5
        |> BiMap.add "VK_LALT" 0xA4 // LALT/RALT are actually LMENU/RMENU, but those are silly names
        |> BiMap.add "VK_RALT" 0xA5
        |> BiMap.add "VK_BROWSER_BACK" 0xA6
        |> BiMap.add "VK_BROWSER_FORWARD" 0xA7
        |> BiMap.add "VK_BROWSER_REFRESH" 0xA8
        |> BiMap.add "VK_BROWSER_STOP" 0xA9
        |> BiMap.add "VK_BROWSER_SEARCH" 0xAA
        |> BiMap.add "VK_BROWSER_FAVORITES" 0xAB
        |> BiMap.add "VK_BROWSER_HOME" 0xAC
        |> BiMap.add "VK_VOLUME_MUTE" 0xAD
        |> BiMap.add "VK_VOLUME_DOWN" 0xAE
        |> BiMap.add "VK_VOLUME_UP" 0xAF
        |> BiMap.add "VK_MEDIA_NEXT_TRACK" 0xB0
        |> BiMap.add "VK_MEDIA_PREV_TRACK" 0xB1
        |> BiMap.add "VK_MEDIA_STOP" 0xB2
        |> BiMap.add "VK_MEDIA_PLAY_PAUSE" 0xB3
        |> BiMap.add "VK_LAUNCH_MAIL" 0xB4
        |> BiMap.add "VK_LAUNCH_MEDIA_SELECT" 0xB5
        |> BiMap.add "VK_LAUNCH_APP1" 0xB6
        |> BiMap.add "VK_LAUNCH_APP2" 0xB7
        |> BiMap.add "VK_OEM_1" 0xBA
        |> BiMap.add "VK_OEM_PLUS" 0xBB
        |> BiMap.add "VK_OEM_COMMA" 0xBC
        |> BiMap.add "VK_OEM_MINUS" 0xBD
        |> BiMap.add "VK_OEM_PERIOD" 0xBE
        |> BiMap.add "VK_OEM_2" 0xBF
        |> BiMap.add "VK_OEM_3" 0xC0
        |> BiMap.add "VK_OEM_4" 0xDB
        |> BiMap.add "VK_OEM_5" 0xDC
        |> BiMap.add "VK_OEM_6" 0xDD
        |> BiMap.add "VK_OEM_7" 0xDE
        |> BiMap.add "VK_OEM_8" 0xDF
        |> BiMap.add "VK_OEM_102" 0xE2
        |> BiMap.add "VK_PROCESSKEY" 0xE5
        |> BiMap.add "VK_PACKET" 0xE7
        |> BiMap.add "VK_ATTN" 0xF6
        |> BiMap.add "VK_CRSEL" 0xF7
        |> BiMap.add "VK_EXSEL" 0xF8
        |> BiMap.add "VK_EREOF" 0xF9
        |> BiMap.add "VK_PLAY" 0xFA
        |> BiMap.add "VK_ZOOM" 0xFB
        |> BiMap.add "VK_NONAME" 0xFC
        |> BiMap.add "VK_PA1" 0xFD
        |> BiMap.add "VK_OEM_CLEAR" 0xFE

let convertStringKeyToCode (keyString: string) = Map.tryFind keyString (BiMap.mappings keyCodes)

let convertCodeToStringKey (code: int) = Map.tryFind code (BiMap.reverseMappings keyCodes)

