#pragma once

#include <variant>

#include "core/point.h"

namespace kku
{

struct SystemEvent
{
    enum class Type
    {
        None = 0,

        Resize = 1,

        KeyPress = 2,
        KeyRelease = 3,

        MouseWheelScroll = 4,
        MouseMove = 5,
        MousePress = 6,
        MouseRelease = 7
    };

    struct Size
    {
        std::size_t width = 0;
        std::size_t height = 0;
    };

    struct Key
    {
        enum class Code
        {
            Unknown = -1,
            A = 0,
            B,
            C,
            D,
            E,
            F,
            G,
            H,
            I,
            J,
            K,
            L,
            M,
            N,
            O,
            P,
            Q,
            R,
            S,
            T,
            U,
            V,
            W,
            X,
            Y,
            Z,
            Num0,
            Num1,
            Num2,
            Num3,
            Num4,
            Num5,
            Num6,
            Num7,
            Num8,
            Num9,
            Escape,
            LControl,
            LShift,
            LAlt,
            LSystem,
            RControl,
            RShift,
            RAlt,
            RSystem,
            Menu,
            LBracket,
            RBracket,
            Semicolon,
            Comma,
            Period,
            Quote,
            Slash,
            Backslash,
            Tilde,
            Equal,
            Hyphen,
            Space,
            Enter,
            Backspace,
            Tab,
            PageUp,
            PageDown,
            End,
            Home,
            Insert,
            Delete,
            Add,
            Subtract,
            Multiply,
            Divide,
            Left,
            Right,
            Up,
            Down,
            Numpad0,
            Numpad1,
            Numpad2,
            Numpad3,
            Numpad4,
            Numpad5,
            Numpad6,
            Numpad7,
            Numpad8,
            Numpad9,
            F1,
            F2,
            F3,
            F4,
            F5,
            F6,
            F7,
            F8,
            F9,
            F10,
            F11,
            F12,
            F13,
            F14,
            F15,
            Pause
        };

        Code view = Code::Unknown;
        bool alt = false;
        bool control = false;
        bool shift = false;
    };

    struct Mouse
    {
        Point position;

        bool scrolled_up = false;

        enum class Button
        {
            None = 0,
            Wheel = 1,
            Left = 2,
            Right = 3
        };

        Button button = Button::Left;
    };

    struct None
    {
    };

    Type type = Type::None;
    std::variant<Size, Key, Mouse, None> data;
};

} // namespace kku