#ifndef HUSH_KEYMAP_H
#define HUSH_KEYMAP_H
#include <SDL.h>
#include <stdbool.h>
/* Every user-rebindable shortcut. Plain text-editing keys (arrows, Enter, Backspace, Home/End,
the mouse) are deliberately not in here -- they're not "shortcuts" in the chord sense, and
letting them be rebound risks silently breaking normal typing. */
typedef enum {
ACTION_SAVE,
ACTION_OPEN,
ACTION_COPY,
ACTION_PASTE,
ACTION_UNDO,
ACTION_REDO,
ACTION_QUIT,
ACTION_HELP,
ACTION_SOURCE_VIEW,
ACTION_ZOOM_IN,
ACTION_ZOOM_OUT,
ACTION_ZOOM_RESET,
ACTION_COUNT
} Action;
typedef struct {
int key; /* an SDL_Keycode (SDLK_*) -- layout-aware, not a physical scancode */
bool ctrl, shift, alt;
} KeyBinding;
/* Fills out[ACTION_COUNT] with hush's built-in default bindings. */
void keymap_set_defaults(KeyBinding *out);
/* Parses a binding spec like "ctrl+s", "ctrl+shift+z", "ctrl+/", or "f1" into `out`. Modifier
names ("ctrl", "shift", "alt") are case-insensitive and may appear in any order, joined by
'+'; the remaining token is the key name (single letters/digits, f1-f12, punctuation like
"/" or "slash", or names like "enter"/"escape"/"tab"/"space"/"home"/"end"/"up"/"down"/
"left"/"right"/"pageup"/"pagedown"/"insert" -- see keymap.c for the full list). Returns false
(leaving `out` untouched) for an empty spec or an unrecognized key name. */
bool keymap_parse_spec(const char *spec, int len, KeyBinding *out);
/* If `key` names one of the actions above (its config-file key, e.g. "key.save"), parses
`value` as a binding spec and stores it into keymap[that action]. Returns whether it matched
and parsed -- used by config.c to dispatch "key.*" lines. */
bool keymap_parse_config_line(const char *key, int keyLen, const char *value, int valueLen, KeyBinding *keymap);
/* The bindings actually used by main.c's input loop: defaulted at startup, then overlaid by
config_load() from the user's config file. */
extern KeyBinding g_keymap[ACTION_COUNT];
/* Clears the per-frame keydown buffer -- call once at the top of each frame, before draining
SDL's event queue. */
void keymap_begin_frame(void);
/* Records one non-repeat SDL_KEYDOWN event's keycode into the per-frame buffer -- call once per
such event while draining SDL_PollEvent (skip events where event.key.repeat is set, since
that's OS-level auto-repeat, not a fresh press). */
void keymap_note_keydown(SDL_Keycode key);
/* True if `key` was recorded via keymap_note_keydown this frame. Used both by keymap_pressed
(below) and by main.c's own ad-hoc fixed-key checks (F1, Escape, Enter, Home/End, ...) so
there's a single source of truth for "was this keycode just pressed" rather than two parallel
per-frame buffers. */
bool keymap_key_pressed_raw(SDL_Keycode key);
/* True on the frame `a`'s bound chord was just pressed (ctrl/shift/alt must match exactly). */
bool keymap_pressed(Action a, bool ctrl, bool shift, bool alt);
/* Same, but true again at a steady repeat rate while held. */
bool keymap_repeat(Action a, bool ctrl, bool shift, bool alt, double now, double *nextRepeatAt);
/* Shared scancode-based "is held, repeating at a steady rate" primitive: true on the frame `sc`
goes down, then again every ~0.03s after an initial ~0.4s delay while still held, false (and
resets `*nextRepeatAt`) once released. Backs keymap_repeat above; also exposed directly for
main.c's fixed-scancode repeat needs (arrows, backspace, delete, the numpad zoom fallback) so
there's one repeat-timer implementation, not two. */
bool keymap_repeat_scancode(SDL_Scancode sc, double now, double *nextRepeatAt);
#endif