from dataclasses import dataclass
from enum import Enum, auto


class KeyEventType(Enum):
    """Enum describing keyboard input event types.

    The enum integer values are arbitrary and may change in the future.
    """

    PRESS = auto()
    """A key was pressed"""

    AUTO_REPEAT = auto()
    """A key was automatically repeated from being held"""

    RELEASE = auto()
    """A key was released"""


@dataclass(frozen=True)
class KeyEvent:
    """A keyboard input event.

    For printable keys, the easiest way to read a key press is by the ``text``
    field. For non-printing keys like arrow keys, you can check the pressed key with the
    ``code`` field.
    """

    event_type: KeyEventType
    """The type of the event"""

    code: int
    """The platform-independent key code for the pressed key.
    
    This key code corresponds to `Qt's platform-independent key map
    <https://doc.qt.io/qt-5/qt.html#Key-enum>`_. For convenience, a few common key codes
    are provided here:

    +---------------+-------------+
    | Key           | Code (hex)  |
    +===============+=============+
    | <Left Arrow>  | 0x01000012  |
    +---------------+-------------+
    | <Up Arrow>    | 0x01000013  |
    +---------------+-------------+
    | <Right Arrow> | 0x01000014  |
    +---------------+-------------+
    | <Down Arrow>  | 0x01000015  |
    +---------------+-------------+
    | <Space>       | 0x20        |
    +---------------+-------------+
    | <Enter>       | 0x01000004  |
    +---------------+-------------+
    | <Escape>      | 0x01000000  |
    +---------------+-------------+

    Note that this does not differentiate letter capitalization; check the active
    modifier keys or the ``text`` field to determine capitalization.
    """

    modifiers: int
    """A bitmask of key modifiers active during this event.

    The modifier flags in this bitmask correspond to
    `Qt's modifier map <https://doc.qt.io/qt-5/qt.html#KeyboardModifier-enum>`_.
    """

    text: str
    """The unicode text generated by this key.

    This may be empty for keystrokes that do not emit text, such as modifiers.
    """
