# -*- coding: utf-8 -*-
#
# reference:
#   + https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
#
# fmt: off

NO = '\x00'
TRANSPARENT = '\x01'

# NONE = 0x00  # No key pressed
# Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key")
# ROLLOVER = 0x01
# 0x02 #  Keyboard POST Fail
# 0x03 #  Keyboard Error Undefined

# A = 0x04  # Keyboard a and A
# B = 0x05  # Keyboard b and B
# C = 0x06  # Keyboard c and C
# D = 0x07  # Keyboard d and D
# E = 0x08  # Keyboard e and E
# F = 0x09  # Keyboard f and F
# G = 0x0a  # Keyboard g and G
# H = 0x0b  # Keyboard h and H
# I = 0x0c  # Keyboard i and I
# J = 0x0d  # Keyboard j and J
# K = 0x0e  # Keyboard k and K
# L = 0x0f  # Keyboard l and L
# M = 0x10  # Keyboard m and M
# N = 0x11  # Keyboard n and N
# O = 0x12  # Keyboard o and O
# P = 0x13  # Keyboard p and P
# Q = 0x14  # Keyboard q and Q
# R = 0x15  # Keyboard r and R
# S = 0x16  # Keyboard s and S
# T = 0x17  # Keyboard t and T
# U = 0x18  # Keyboard u and U
# V = 0x19  # Keyboard v and V
# W = 0x1a  # Keyboard w and W
# X = 0x1b  # Keyboard x and X
# Y = 0x1c  # Keyboard y and Y
# Z = 0x1d  # Keyboard z and Z

A = 'a'
B = 'b'
C = 'c'
D = 'd'
E = 'e'
F = 'f'
G = 'g'
H = 'h'
I = 'i'
J = 'j'
K = 'k'
L = 'l'
M = 'm'
N = 'n'
O = 'o'
P = 'p'
Q = 'q'
R = 'r'
S = 's'
T = 't'
U = 'u'
V = 'v'
W = 'w'
X = 'x'
Y = 'y'
Z = 'z'

# 1 = 0x1e # Keyboard 1 and !
# 2 = 0x1f # Keyboard 2 and @
# 3 = 0x20 # Keyboard 3 and #
# 4 = 0x21 # Keyboard 4 and $
# 5 = 0x22 # Keyboard 5 and %
# 6 = 0x23 # Keyboard 6 and ^
# 7 = 0x24 # Keyboard 7 and &
# 8 = 0x25 # Keyboard 8 and *
# 9 = 0x26 # Keyboard 9 and (
# 0 = 0x27 # Keyboard 0 and )

ENTER = 0x28  # Keyboard Return (ENTER)
ESCAPE = 0x29 # Keyboard ESCAPE
ESC = ESCAPE
BACKSPACE = 0x2a  # Keyboard DELETE (Backspace)
TAB = 0x2b  # Keyboard Tab
SPACE = 0x2c  # Keyboard Spacebar
MINUS = 0x2d  # Keyboard - and _
EQUAL = 0x2e  # Keyboard = and +
LEFTBRACE = 0x2f  # Keyboard [ and {
RIGHTBRACE = 0x30  # Keyboard ] and }
BACKSLASH = 0x31  # Keyboard \ and |
HASHTILDE = 0x32  # Keyboard Non-US # and ~
SEMICOLON = 0x33  # Keyboard ; and :
APOSTROPHE = 0x34  # Keyboard ' and "
QUOTE = 0x34
GRAVE = 0x35  # Keyboard ` and ~
COMMA = 0x36  # Keyboard , and <
DOT = 0x37  # Keyboard . and >
SLASH = 0x38  # Keyboard / and ?
CAPSLOCK = 0x39  # Keyboard Caps Lock
CAPS = CAPSLOCK

F1 = 0x3a  # Keyboard F1
F2 = 0x3b  # Keyboard F2
F3 = 0x3c  # Keyboard F3
F4 = 0x3d  # Keyboard F4
F5 = 0x3e  # Keyboard F5
F6 = 0x3f  # Keyboard F6
F7 = 0x40  # Keyboard F7
F8 = 0x41  # Keyboard F8
F9 = 0x42  # Keyboard F9
F10 = 0x43  # Keyboard F10
F11 = 0x44  # Keyboard F11
F12 = 0x45  # Keyboard F12

PRINTSCREEN = 0x46  # Keyboard Print Screen
PRTSCN = PRINTSCREEN
SCROLLLOCK = 0x47  # Keyboard Scroll Lock
PAUSE = 0x48  # Keyboard Pause
INSERT = 0x49  # Keyboard Insert
HOME = 0x4a  # Keyboard Home
PAGEUP = 0x4b  # Keyboard Page Up
PGUP = PAGEUP
DELETE = 0x4c  # Keyboard Delete Forward
DEL = DELETE
END = 0x4d  # Keyboard End
PAGEDOWN = 0x4e  # Keyboard Page Down
PGDN = PAGEDOWN
RIGHT = 0x4f  # Keyboard Right Arrow
LEFT = 0x50  # Keyboard Left Arrow
DOWN = 0x51  # Keyboard Down Arrow
UP = 0x52  # Keyboard Up Arrow

NUMLOCK = 0x53  # Keyboard Num Lock and Clear
KPSLASH = 0x54  # Keypad /
KPASTERISK = 0x55  # Keypad *
KPMINUS = 0x56  # Keypad -
KPPLUS = 0x57  # Keypad +
KPENTER = 0x58  # Keypad ENTER
KP1 = 0x59  # Keypad 1 and End
KP2 = 0x5a  # Keypad 2 and Down Arrow
KP3 = 0x5b  # Keypad 3 and PageDn
KP4 = 0x5c  # Keypad 4 and Left Arrow
KP5 = 0x5d  # Keypad 5
KP6 = 0x5e  # Keypad 6 and Right Arrow
KP7 = 0x5f  # Keypad 7 and Home
KP8 = 0x60  # Keypad 8 and Up Arrow
KP9 = 0x61  # Keypad 9 and Page Up
KP0 = 0x62  # Keypad 0 and Insert
KPDOT = 0x63  # Keypad . and Delete

# 102ND = 0x64 # Keyboard Non-US \ and |
APPLICATION = 0x65  # Keyboard Application
MENU = APPLICATION
POWER = 0x66  # Keyboard Power
KPEQUAL = 0x67  # Keypad =

F13 = 0x68  # Keyboard F13
F14 = 0x69  # Keyboard F14
F15 = 0x6a  # Keyboard F15
F16 = 0x6b  # Keyboard F16
F17 = 0x6c  # Keyboard F17
F18 = 0x6d  # Keyboard F18
F19 = 0x6e  # Keyboard F19
F20 = 0x6f  # Keyboard F20
F21 = 0x70  # Keyboard F21
F22 = 0x71  # Keyboard F22
F23 = 0x72  # Keyboard F23
F24 = 0x73  # Keyboard F24

OPEN = 0x74  # Keyboard Execute
HELP = 0x75  # Keyboard Help
# PROPS = 0x76  # Keyboard Menu
SELECT = 0x77  # Keyboard Select
STOP = 0x78  # Keyboard Stop
AGAIN = 0x79  # Keyboard Again
UNDO = 0x7a  # Keyboard Undo
CUT = 0x7b  # Keyboard Cut
COPY = 0x7c  # Keyboard Copy
PASTE = 0x7d  # Keyboard Paste
FIND = 0x7e  # Keyboard Find
MUTE = 0x7f  # Keyboard Mute
# VOLUMEUP = 0x80  # Keyboard Volume Up
# VOLUMEDOWN = 0x81  # Keyboard Volume Down
# 0x82  Keyboard Locking Caps Lock
# 0x83  Keyboard Locking Num Lock
# 0x84  Keyboard Locking Scroll Lock
KPCOMMA = 0x85  # Keypad Comma
# 0x86  Keypad Equal Sign

INT1 = 0x87
INT2 = 0x88
INT3 = 0x89
INT4 = 0x8a
INT5 = 0x8b
INT6 = 0x8c
INT7 = 0x8d
INT8 = 0x8e
INT9 = 0x8f

RO = 0x87  # Keyboard International1
KATAKANAHIRAGANA = 0x88  # Keyboard International2
YEN = 0x89  # Keyboard International3
HENKAN = 0x8a  # Keyboard International4
MUHENKAN = 0x8b  # Keyboard International5
KPJPCOMMA = 0x8c  # Keyboard International6
# 0x8d  Keyboard International7
# 0x8e  Keyboard International8
# 0x8f  Keyboard International9

LANG1 = 0x90
LANG2 = 0x91
LANG3 = 0x92
LANG4 = 0x93
LANG5 = 0x94
LANG6 = 0x95
LANG7 = 0x96
LANG8 = 0x97
LANG9 = 0x98

HANGEUL = 0x90  # Keyboard LANG1
HANJA = 0x91  # Keyboard LANG2
KATAKANA = 0x92  # Keyboard LANG3
HIRAGANA = 0x93  # Keyboard LANG4
ZENKAKUHANKAKU = 0x94  # Keyboard LANG5
# 0x95  Keyboard LANG6
# 0x96  Keyboard LANG7
# 0x97  Keyboard LANG8
# 0x98  Keyboard LANG9

# 0x99  Keyboard Alternate Erase
# 0x9a  Keyboard SysReq/Attention
# 0x9b  Keyboard Cancel
# 0x9c  Keyboard Clear
# 0x9d  Keyboard Prior
# 0x9e  Keyboard Return
# 0x9f  Keyboard Separator
# 0xa0  Keyboard Out
# 0xa1  Keyboard Oper
# 0xa2  Keyboard Clear/Again
# 0xa3  Keyboard CrSel/Props
# 0xa4  Keyboard ExSel

# 0xb0  Keypad 00
# 0xb1  Keypad 000
# 0xb2  Thousands Separator
# 0xb3  Decimal Separator
# 0xb4  Currency Unit
# 0xb5  Currency Sub-unit
KPLEFTPAREN = 0xb6  # Keypad (
KPRIGHTPAREN = 0xb7  # Keypad )
# 0xb8  Keypad {
# 0xb9  Keypad }
# 0xba  Keypad Tab
# 0xbb  Keypad Backspace
# 0xbc  Keypad A
# 0xbd  Keypad B
# 0xbe  Keypad C
# 0xbf  Keypad D
# 0xc0  Keypad E
# 0xc1  Keypad F
# 0xc2  Keypad XOR
# 0xc3  Keypad ^
# 0xc4  Keypad %
# 0xc5  Keypad <
# 0xc6  Keypad >
# 0xc7  Keypad &
# 0xc8  Keypad &&
# 0xc9  Keypad |
# 0xca  Keypad ||
# 0xcb  Keypad :
# 0xcc  Keypad #
# 0xcd  Keypad Space
# 0xce  Keypad @
# 0xcf  Keypad !
# 0xd0  Keypad Memory Store
# 0xd1  Keypad Memory Recall
# 0xd2  Keypad Memory Clear
# 0xd3  Keypad Memory Add
# 0xd4  Keypad Memory Subtract
# 0xd5  Keypad Memory Multiply
# 0xd6  Keypad Memory Divide
# 0xd7  Keypad +/-
# 0xd8  Keypad Clear
# 0xd9  Keypad Clear Entry
# 0xda  Keypad Binary
# 0xdb  Keypad Octal
# 0xdc  Keypad Decimal
# 0xdd  Keypad Hexadecimal

LEFT_CTRL = 0xe0  # Keyboard Left Control
LEFT_SHIFT = 0xe1  # Keyboard Left Shift
LEFT_ALT = 0xe2  # Keyboard Left Alt
LEFT_GUI = 0xe3  # Keyboard Left GUI
RIGHT_CTRL = 0xe4  # Keyboard Right Control
RIGHT_SHIFT = 0xe5  # Keyboard Right Shift
RIGHT_ALT = 0xe6  # Keyboard Right Alt
RIGHT_GUI = 0xe7  # Keyboard Right GUI

LCTRL = LEFT_CTRL
LSHIFT = LEFT_SHIFT
LALT = LEFT_ALT
LGUI = LEFT_GUI
RCTRL = RIGHT_CTRL
RSHIFT = RIGHT_SHIFT
RALT = RIGHT_ALT
RGUI = RIGHT_GUI

CTRL = LEFT_CTRL
SHIFT = LEFT_SHIFT
ALT = LEFT_ALT
GUI = LEFT_GUI


ASCII_TO_KEYCODE = (
    b'\x00'  # NUL
    b'\x01'  # SOH as TRANSPARENT
    b'\x00'  # STX
    b'\x00'  # ETX
    b'\x00'  # EOT
    b'\x00'  # ENQ
    b'\x00'  # ACK
    b'\x00'  # BEL \a
    b'\x2a'  # BS BACKSPACE \b
    b'\x2b'  # TAB \t
    b'\x28'  # LF \n RETURN / ENTER
    b'\x00'  # VT \v
    b'\x00'  # FF \f
    b'\x28'  # CR \r as RETURN
    b'\x00'  # SO
    b'\x00'  # SI
    b'\x00'  # DLE
    b'\x00'  # DC1
    b'\x00'  # DC2
    b'\x00'  # DC3
    b'\x00'  # DC4
    b'\x00'  # NAK
    b'\x00'  # SYN
    b'\x00'  # ETB
    b'\x00'  # CAN
    b'\x00'  # EM
    b'\x00'  # SUB
    b'\x29'  # ESC
    b'\x00'  # FS
    b'\x00'  # GS
    b'\x00'  # RS
    b'\x00'  # US
    b'\x2c'  # SPACE
    b'\x9e'  # ! (shift 1)
    b'\xb4'  # ' (shift ')
    b'\xa0'  # # (shift 3)
    b'\xa1'  # $ (shift 4)
    b'\xa2'  # % (shift 5)
    b'\xa4'  # & (shift 7)
    b'\x34'  # '
    b'\xa6'  # ( (shift 9)
    b'\xa7'  # ) (shift 0)
    b'\xa5'  # * (shift 8)
    b'\xae'  # + (shift =)
    b'\x36'  # ,
    b'\x2d'  # -
    b'\x37'  # .
    b'\x38'  # /
    b'\x27'  # 0
    b'\x1e'  # 1
    b'\x1f'  # 2
    b'\x20'  # 3
    b'\x21'  # 4
    b'\x22'  # 5
    b'\x23'  # 6
    b'\x24'  # 7
    b'\x25'  # 8
    b'\x26'  # 9
    b'\xb3'  # : (shift ;)
    b'\x33'  # ;
    b'\xb6'  # < (shift ,)
    b'\x2e'  # =
    b'\xb7'  # > (shift .)
    b'\xb8'  # ? (shift /)
    b'\x9f'  # @ (shift 2)
    b'\x84'  # A
    b'\x85'  # B
    b'\x86'  # C
    b'\x87'  # D
    b'\x88'  # E
    b'\x89'  # F
    b'\x8a'  # G
    b'\x8b'  # H
    b'\x8c'  # I
    b'\x8d'  # J
    b'\x8e'  # K
    b'\x8f'  # L
    b'\x90'  # M
    b'\x91'  # N
    b'\x92'  # O
    b'\x93'  # P
    b'\x94'  # Q
    b'\x95'  # R
    b'\x96'  # S
    b'\x97'  # T
    b'\x98'  # U
    b'\x99'  # V
    b'\x9a'  # W
    b'\x9b'  # X
    b'\x9c'  # Y
    b'\x9d'  # Z
    b'\x2f'  # [
    b'\x31'  # \ backslash
    b'\x30'  # ]
    b'\xa3'  # ^ (shift 6)
    b'\xad'  # _ (shift -)
    b'\x35'  # `
    b'\x04'  # a
    b'\x05'  # b
    b'\x06'  # c
    b'\x07'  # d
    b'\x08'  # e
    b'\x09'  # f
    b'\x0a'  # g
    b'\x0b'  # h
    b'\x0c'  # i
    b'\x0d'  # j
    b'\x0e'  # k
    b'\x0f'  # l
    b'\x10'  # m
    b'\x11'  # n
    b'\x12'  # o
    b'\x13'  # p
    b'\x14'  # q
    b'\x15'  # r
    b'\x16'  # s
    b'\x17'  # t
    b'\x18'  # u
    b'\x19'  # v
    b'\x1a'  # w
    b'\x1b'  # x
    b'\x1c'  # y
    b'\x1d'  # z
    b'\xaf'  # { (shift [)
    b'\xb1'  # | (shift \)
    b'\xb0'  # } (shift ])
    b'\xb5'  # ~ (shift `)
    b'\x4c'  # DEL DELETE Forward
)


#     /* Key Actions */
#     ACT_MODS            = 0b0000,
#     ACT_LMODS           = 0b0000,
#     ACT_RMODS           = 0b0001,
#     ACT_MODS_TAP        = 0b0010,
#     ACT_LMODS_TAP       = 0b0010,
#     ACT_RMODS_TAP       = 0b0011,
#     /* Other Keys */
#     ACT_USAGE           = 0b0100,
#     ACT_MOUSEKEY        = 0b0101,
#     /* Layer Actions */
#     ACT_LAYER           = 0b1000,
#     ACT_LAYER_TAP       = 0b1010, /* Layer  0-15 */
#     ACT_LAYER_TAP_EXT   = 0b1011, /* Layer 16-31 */
#     /* Extensions */
#     ACT_MACRO           = 0b1100,
#     ACT_BACKLIGHT       = 0b1101,
#     ACT_COMMAND         = 0b1110,
#     ACT_FUNCTION        = 0b1111
# };

ACT_MODS            = 0b0000
ACT_MODS_TAP        = 0b0010
ACT_USAGE           = 0b0100
ACT_MOUSEKEY        = 0b0101
ACT_LAYER           = 0b1000
ACT_LAYER_TAP       = 0b1010    # Layer  0-15
ACT_LAYER_TAP_EXT   = 0b1011    # Layer 16-31
ACT_MACRO           = 0b1100
ACT_BACKLIGHT       = 0b1101
ACT_COMMAND         = 0b1110
ACT_FUNCTION        = 0b1111


OP_BIT_AND = 0
OP_BIT_OR  = 1
OP_BIT_XOR = 2
OP_BIT_SET = 3

ON_PRESS    = 1
ON_RELEASE  = 2
ON_BOTH     = 3


OP_TAP_TOGGLE = 0xF0



# convert keyname to action code
def get_action_code(x):
    if type(x) is int:
        return x if x > 9 else ASCII_TO_KEYCODE[ord(str(x))]
    if type(x) is str and len(x) == 1:
        return ASCII_TO_KEYCODE[ord(x)] & 0x7F
    if x is None:
        return 0
    raise ValueError('Invalid keyname {}'.format(x))

def MODS(*args):
    MAP = { LCTRL: 1, LSHIFT: 2, LALT: 4, LGUI: 8, RCTRL: 0x11, RSHIFT: 0x12, RALT: 0x14, RGUI: 0x18 }
    mods = 0
    for m in args:
        if m not in MAP:
            raise ValueError('Invalid modifier {}'.format(m))
        mods |= MAP[m]
    return mods

def mods_to_keycodes(mods):
    # if mods & 0x10:
    #     all_mods = (RCTRL, RSHIFT, RALT, RGUI)
    # else:
    #     all_mods = (LCTRL, LSHIFT, LALT, LGUI)
    # return list(filter(lambda k: mods & (1 << (k & 0x3)), all_mods))

    b = RCTRL if mods & 0x10 else LCTRL
    o = []
    for i in range(4):
        if (mods >> i) & 1:
            o.append(b + i)
    return o

ACTION = lambda kind, param: (kind << 12) | param

MODS_KEY = lambda mods, key: ACTION(ACT_MODS, (mods << 8) | get_action_code(key))
MODS_TAP = lambda mods, key: ACTION(ACT_MODS_TAP, (mods << 8) | get_action_code(key))
MOUSEKEY = lambda key: ACTION(ACT_MOUSEKEY, key)

LAYER_BITOP = lambda op, part, bits, on: ACTION(ACT_LAYER, op<<10|on<<8|part<<5|(bits&0x1f))
LAYER_BIT_XOR = lambda part, bits, on: LAYER_BITOP(OP_BIT_XOR, part, bits, on)
LAYER_INVERT = lambda layer, on: LAYER_BIT_XOR(layer/4,   1<<(layer%4),  on)
LAYER_TOGGLE = lambda layer: LAYER_INVERT(layer, ON_RELEASE)

LAYER_TAP = lambda layer, key=NO: ACTION(ACT_LAYER_TAP, (layer << 8) | get_action_code(key))
LAYER_TAP_TOGGLE = lambda layer: LAYER_TAP(layer, OP_TAP_TOGGLE)
LAYER_MODS = lambda layer, mods: LAYER_TAP(layer, 0xC0 | mods)

ACTION_USAGE_SYSTEM = lambda n: ACTION(ACT_USAGE, n)
ACTION_USAGE_CONSUMER = lambda n: ACTION(ACT_USAGE, 1 << 10 | (n))
ACTION_MOUSEKEY = lambda key: ACTION(ACT_MOUSEKEY, key)


MS_BTN1 = MOUSEKEY(1 << 0)
MS_BTN2 = MOUSEKEY(1 << 1)
MS_BTN3 = MOUSEKEY(1 << 2)
MS_BTN4 = MOUSEKEY(1 << 3)
MS_BTN5 = MOUSEKEY(1 << 4)
MS_UP   = MOUSEKEY(1 << 8)
MS_DN = MOUSEKEY(2 << 8)
MS_LT = MOUSEKEY(3 << 8)
MS_RT = MOUSEKEY(4 << 8)
MS_UL = MOUSEKEY(5 << 8)
MS_UR = MOUSEKEY(6 << 8)
MS_DL = MOUSEKEY(7 << 8)
MS_DR = MOUSEKEY(8 << 8)
MS_W_UP = MOUSEKEY(9 << 8)
MS_W_DN = MOUSEKEY(10 << 8)

MS_MOVEMENT = (
    (0, 0, 0),
    (0, -2, 0), (0, 2, 0), (-2, 0, 0), (2, 0, 0),
    (-1, -1, 0), (1, -1, 0), (-1, 1, 0), (1, 1, 0),
    (0, 0, 1), (0, 0, -1)
)

MACRO = lambda n: ACTION(ACT_MACRO, n)
BACKLIGHT = lambda n: ACTION(ACT_BACKLIGHT, n)

RGB_TOGGLE = BACKLIGHT(0)
RGB_MOD = BACKLIGHT(1)
MOD_RGB = BACKLIGHT(2)
RGB_HUE = BACKLIGHT(3)
HUE_RGB = BACKLIGHT(4)
RGB_SAT = BACKLIGHT(5)
SAT_RGB = BACKLIGHT(6)
RGB_VAL = BACKLIGHT(7)
VAL_RGB = BACKLIGHT(8)

COMMAND = lambda opt, n: ACTION(ACT_COMMAND,  opt << 8 | n)

BOOTLOADER = COMMAND(0, 0)
HEATMAP = COMMAND(0, 1)
SUSPEND = COMMAND(0, 2)
SHUTDOWN = COMMAND(0, 3)
USB_TOGGLE = COMMAND(0, 4)

BT = lambda n: COMMAND(1, n)
BT0 = BT(0)
BT1 = BT(1)
BT2 = BT(2)
BT3 = BT(3)
BT4 = BT(4)
BT5 = BT(5)
BT6 = BT(6)
BT7 = BT(7)
BT8 = BT(8)
BT9 = BT(9)
BT_TOGGLE = BT(0xFF)
BT_ON = BT(0xFE)
BT_OFF = BT(0xFD)

# Consumer Page(0x0C)
AUDIO_MUTE =                ACTION_USAGE_CONSUMER(0x00E2)
AUDIO_VOL_UP =              ACTION_USAGE_CONSUMER(0x00E9)
AUDIO_VOL_DOWN =            ACTION_USAGE_CONSUMER(0x00EA)
TRANSPORT_NEXT_TRACK =      ACTION_USAGE_CONSUMER(0x00B5)
TRANSPORT_PREV_TRACK =      ACTION_USAGE_CONSUMER(0x00B6)
TRANSPORT_STOP =            ACTION_USAGE_CONSUMER(0x00B7)
TRANSPORT_STOP_EJECT =      ACTION_USAGE_CONSUMER(0x00CC)
TRANSPORT_PLAY_PAUSE =      ACTION_USAGE_CONSUMER(0x00CD)
# application launch
APPLAUNCH_CC_CONFIG =       ACTION_USAGE_CONSUMER(0x0183)
APPLAUNCH_EMAIL =           ACTION_USAGE_CONSUMER(0x018A)
APPLAUNCH_CALCULATOR =      ACTION_USAGE_CONSUMER(0x0192)
APPLAUNCH_LOCAL_BROWSER =   ACTION_USAGE_CONSUMER(0x0194)
# application control
APPCONTROL_SEARCH =         ACTION_USAGE_CONSUMER(0x0221)
APPCONTROL_HOME =           ACTION_USAGE_CONSUMER(0x0223)
APPCONTROL_BACK =           ACTION_USAGE_CONSUMER(0x0224)
APPCONTROL_FORWARD =        ACTION_USAGE_CONSUMER(0x0225)
APPCONTROL_STOP =           ACTION_USAGE_CONSUMER(0x0226)
APPCONTROL_REFRESH =        ACTION_USAGE_CONSUMER(0x0227)
APPCONTROL_BOOKMARKS =      ACTION_USAGE_CONSUMER(0x022A)
# supplement for Bluegiga iWRAP HID(not supported by Windows?)
APPLAUNCH_LOCK =            ACTION_USAGE_CONSUMER(0x019E)
TRANSPORT_RECORD =          ACTION_USAGE_CONSUMER(0x00B2)
TRANSPORT_FAST_FORWARD =    ACTION_USAGE_CONSUMER(0x00B3)
TRANSPORT_REWIND =          ACTION_USAGE_CONSUMER(0x00B4)
TRANSPORT_EJECT =           ACTION_USAGE_CONSUMER(0x00B8)
APPCONTROL_MINIMIZE =       ACTION_USAGE_CONSUMER(0x0206)
# https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/display-brightness-control
DISPLAY_BRIGHTNESS_UP =     ACTION_USAGE_CONSUMER(0x006F)
DISPLAY_BRIGHTNESS_DOWN =   ACTION_USAGE_CONSUMER(0x0070)