#pragma once

#include <Core/Common/CoreTypes.h>

namespace Juliet
{
    // Represents a Virtual Key corresponding to the Physical key, but localized using the keyboard layout
    // ScanCode reprensent US ASCII Keyboard
    // WASD Scan codes are ZQSD in KeyCode for French keyboard
    // We use the ASCII value of the generated character as value, when possible.
    // Keys that do not produce a character are converted to an abritrary value high enough to not conflict
    // Reference: https://www.asciitable.com/
    // Reference: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa299374(v=vs.60)
    enum class KeyCode : uint32
    {
        Unknown          = 0x0,   // 0
        Unsupported      = 0x0,   // 0
        Return           = 0X0Du, // '\r'
        Escape           = 0X1Bu, // '\X1B'
        Backspace        = 0X08u, // '\b'
        Tab              = 0X09u, // '\t'
        Space            = 0X20u, // ' '
        ExclamationPoint = 0X21u, // '!'
        DoubleApostrophe = 0X22u, // '"'
        Hash             = 0X23u, // '#'
        Dollar           = 0X24u, // '$'
        Percent          = 0X25u, // '%'
        Ampersand        = 0X26u, // '&'
        Apostrophe       = 0X27u, // '\''
        LeftParenthesis  = 0X28u, // '('
        RightParenthesis = 0X29u, // ')'
        Asterisk         = 0X2Au, // '*'
        Plus             = 0X2Bu, // '+'
        Comma            = 0X2Cu, // ','
        Minus            = 0X2Du, // '-'
        Period           = 0X2Eu, // '.'
        Slash            = 0X2Fu, // '/'
        Num0             = 0X30u, // '0'
        Num1             = 0X31u, // '1'
        Num2             = 0X32u, // '2'
        Num3             = 0X33u, // '3'
        Num4             = 0X34u, // '4'
        Num5             = 0X35u, // '5'
        Num6             = 0X36u, // '6'
        Num7             = 0X37u, // '7'
        Num8             = 0X38u, // '8'
        Num9             = 0X39u, // '9'
        Colon            = 0X3Au, // ':'
        Semicolon        = 0X3Bu, // ';'
        LessThan         = 0X3Cu, // '<'
        Equals           = 0X3Du, // '='
        GreaterThan      = 0X3Eu, // '>'
        QuestionMark     = 0X3Fu, // '?'
        CommercialAt     = 0x40u, // '@'
        LeftBracket      = 0X5Bu, // '['
        Backslash        = 0X5Cu, // '\\'
        RightBracket     = 0X5DU, // ']'
        Caret            = 0X5Eu, // '^'
        Underscore       = 0X5Fu, // '_'
        GraveAccent      = 0X60u, // '`'
        A                = 0x61u, // 'a'
        B                = 0x62u, // 'b'
        C                = 0x63u, // 'c'
        D                = 0x64u, // 'd'
        E                = 0x65u, // 'e'
        F                = 0x66u, // 'f'
        G                = 0x67u, // 'g'
        H                = 0x68u, // 'h'
        I                = 0x69u, // 'i'
        J                = 0x6Au, // 'j'
        K                = 0x6Bu, // 'k'
        L                = 0x6CU, // 'l'
        M                = 0x6DU, // 'm'
        N                = 0x6Eu, // 'n'
        O                = 0x6Fu, // 'o'
        P                = 0x70u, // 'p'
        Q                = 0x71u, // 'q'
        R                = 0x72u, // 'r'
        S                = 0x73u, // 's'
        T                = 0x74u, // 't'
        U                = 0x75u, // 'y'
        V                = 0x76u, // 'v'
        W                = 0x77u, // 'w'
        X                = 0x78u, // 'x'
        Y                = 0x79u, // 'y'
        Z                = 0x7Au, // 'z'
        LeftBrace        = 0x7BU, // '{'
        Pipe             = 0x7CU, // '|'
        RightBrace       = 0x7DU, // '}'
        Tilde            = 0x7Eu, // '~'
        Delete           = 0x7Fu, // '\x7F'
        PlusMinus        = 0xb1u, // '\xB1'

        // Keys not producing a character
        // Based on SDL Algo: ScanCode | 0x40000000
        CapsLock            = 0x40000039u,
        F1                  = 0x4000003Au,
        F2                  = 0x4000003Bu,
        F3                  = 0x4000003CU,
        F4                  = 0x4000003DU,
        F5                  = 0x4000003Eu,
        F6                  = 0x4000003Fu,
        F7                  = 0x40000040u,
        F8                  = 0x40000041u,
        F9                  = 0x40000042u,
        F10                 = 0x40000043u,
        F11                 = 0x40000044u,
        F12                 = 0x40000045u,
        PrintScreen         = 0x40000046u,
        ScrollLock          = 0x40000047u,
        Pause               = 0x40000048u,
        Insert              = 0x40000049u,
        Home                = 0x4000004Au,
        PageUp              = 0x4000004Bu,
        End                 = 0x4000004DU,
        PageDown            = 0x4000004Eu,
        RightArrow          = 0x4000004Fu,
        LeftArrow           = 0x40000050u,
        DownArrow           = 0x40000051u,
        UpArrow             = 0x40000052u,
        NumlockClear        = 0x40000053u,
        KeyPad_Divide       = 0x40000054u,
        KeyPad_Multiply     = 0x40000055u,
        KeyPad_Minus        = 0x40000056u,
        KeyPad_Plus         = 0x40000057u,
        KeyPad_Enter        = 0x40000058u,
        KeyPad_Num1         = 0x40000059u,
        KeyPad_Num2         = 0x4000005Au,
        KeyPad_Num3         = 0x4000005Bu,
        KeyPad_Num4         = 0x4000005Cu,
        KeyPad_Num5         = 0x4000005Du,
        KeyPad_Num6         = 0x4000005Eu,
        KeyPad_Num7         = 0x4000005Fu,
        KeyPad_Num8         = 0x40000060u,
        KeyPad_Num9         = 0x40000061u,
        KeyPad_Num0         = 0x40000062u,
        KeyPad_Period       = 0x40000063u,
        Power               = 0x40000066u,
        KeyPad_Equals       = 0x40000067u,
        F13                 = 0x40000068u,
        F14                 = 0x40000069u,
        F15                 = 0x4000006Au,
        F16                 = 0x4000006Bu,
        F17                 = 0x4000006Cu,
        F18                 = 0x4000006Du,
        F19                 = 0x4000006Eu,
        F20                 = 0x4000006Fu,
        F21                 = 0x40000070u,
        F22                 = 0x40000071u,
        F23                 = 0x40000072u,
        F24                 = 0x40000073u,
        Mute                = 0x4000007Fu,
        VolumeUp            = 0x40000080u,
        VolumeDown          = 0x40000081u,
        KeyPad_Comma        = 0x40000085u,
        LeftControl         = 0x400000E0u,
        LeftShift           = 0x400000E1u,
        LeftAlt             = 0x400000E2u,
        LeftOSCommand       = 0x400000E3u,
        RightControl        = 0x400000E4u,
        RightShift          = 0x400000E5u,
        RightAlt            = 0x400000E6u,
        RightOSCommand      = 0x400000E7u,
        Sleep               = 0x40000102u,
        WakeUp              = 0x40000103u,
        Media_NextTrack     = 0x4000010Bu,
        Media_PreviousTrack = 0x4000010Cu,
        Media_Stop          = 0x4000010Du,
        Media_Eject         = 0x4000010Eu,
        Media_PlayPause     = 0x4000010Fu,
        Media_Select        = 0x40000110u,
    };

    enum class KeyMod : uint16
    {
        None           = 0b0,
        LeftShift      = 0b0000'0000'0001u,
        RightShift     = 0b0000'0000'0010u,
        LeftControl    = 0b0000'0000'0100u,
        RightControl   = 0b0000'0000'1000u,
        LeftAlt        = 0b0000'0001'000u,
        RightAlt       = 0b0000'0010'0000u,
        LeftOSCommand  = 0b0000'0100'0000u,
        RightOSCommand = 0b0000'1000'0000u,
        NumLock        = 0b0001'0000'0000u,
        CapsLock       = 0b0010'0000'0000u,
        ScrollLock     = 0b0100'0000'0000u,
        Control        = LeftControl | RightControl,
        Shift          = LeftShift | RightShift,
        Alt            = LeftAlt | RightAlt,
        OSCommand      = LeftOSCommand | RightOSCommand,
    };
} // namespace Juliet
