#ifndef HUSH_UNDO_H
#define HUSH_UNDO_H
#include "document.h"
#include <stdbool.h>
typedef struct {
Document doc;
int cursorBlock, cursorOffset;
} Snapshot;
typedef struct {
Snapshot *items;
int count, cap;
int limit; /* max entries kept; oldest evicted beyond this */
} SnapshotStack;
void snapshot_stack_init(SnapshotStack *s, int limit);
void snapshot_stack_free(SnapshotStack *s);
void snapshot_stack_clear(SnapshotStack *s);
void snapshot_stack_push(SnapshotStack *s, const Document *doc, int cursorBlock, int cursorOffset);
/* Pops the most recent snapshot into *out (transfers Document ownership -- caller must
eventually document_free it). Returns false if the stack is empty. */
bool snapshot_stack_pop(SnapshotStack *s, Snapshot *out);
typedef enum { EDIT_NONE, EDIT_TYPE, EDIT_BACKSPACE, EDIT_DELETE_FWD, EDIT_ENTER, EDIT_PASTE, EDIT_TOGGLE_TASK,
EDIT_QUICK_INSERT, EDIT_TURN_INTO, EDIT_INSERT_TABLE } EditKind;
typedef struct {
SnapshotStack undo, redo;
EditKind lastKind;
int lastBlock, lastOffset;
} UndoManager;
void undo_manager_init(UndoManager *m, int limit);
void undo_manager_free(UndoManager *m);
/* Clears both stacks and coalescing state -- call when a brand new document is loaded. */
void undo_manager_reset(UndoManager *m);
/* Call BEFORE mutating the document. Pushes a pre-edit snapshot (and clears the redo stack)
unless this edit coalesces with the immediately preceding one (same kind, cursor unmoved
since the last edit). */
void undo_manager_before_edit(UndoManager *m, EditKind kind, const Document *doc, int cursorBlock, int cursorOffset);
/* Call AFTER mutating, with the new cursor position, so the next call's coalescing check has
something to compare against. */
void undo_manager_after_edit(UndoManager *m, EditKind kind, int cursorBlock, int cursorOffset);
#endif