-module(etui@undo).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/etui/undo.gleam").
-export([undo_new/2, current/1, can_undo/1, can_redo/1, undo_depth/1, push/2, undo/1, redo/1, reset/2]).
-export_type([undo_stack/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type undo_stack(FCD) :: {undo_stack, list(FCD), FCD, list(FCD), integer()}.
-file("src/etui/undo.gleam", 42).
?DOC(
" Create a new stack with an initial `present` value.\n"
" `max_size` limits how many past entries are retained (0 = unlimited).\n"
).
-spec undo_new(FCE, integer()) -> undo_stack(FCE).
undo_new(Initial, Max_size) ->
{undo_stack, [], Initial, [], Max_size}.
-file("src/etui/undo.gleam", 50).
?DOC(" The current value.\n").
-spec current(undo_stack(FCG)) -> FCG.
current(Stack) ->
erlang:element(3, Stack).
-file("src/etui/undo.gleam", 55).
?DOC(" `True` if there is at least one past state to undo to.\n").
-spec can_undo(undo_stack(any())) -> boolean().
can_undo(Stack) ->
not gleam@list:is_empty(erlang:element(2, Stack)).
-file("src/etui/undo.gleam", 60).
?DOC(" `True` if there is at least one future state to redo to.\n").
-spec can_redo(undo_stack(any())) -> boolean().
can_redo(Stack) ->
not gleam@list:is_empty(erlang:element(4, Stack)).
-file("src/etui/undo.gleam", 65).
?DOC(" Number of past entries available to undo.\n").
-spec undo_depth(undo_stack(any())) -> integer().
undo_depth(Stack) ->
erlang:length(erlang:element(2, Stack)).
-file("src/etui/undo.gleam", 74).
?DOC(
" Record `new_value` as the new present, moving the old present into past.\n"
" Clears the future (redo history) since the branch diverged.\n"
).
-spec push(undo_stack(FCO), FCO) -> undo_stack(FCO).
push(Stack, New_value) ->
Past = [erlang:element(3, Stack) | erlang:element(2, Stack)],
Trimmed = case (erlang:element(5, Stack) > 0) andalso (erlang:length(Past) > erlang:element(
5,
Stack
)) of
true ->
gleam@list:take(Past, erlang:element(5, Stack));
false ->
Past
end,
{undo_stack, Trimmed, New_value, [], erlang:element(5, Stack)}.
-file("src/etui/undo.gleam", 90).
?DOC(
" Undo: move present to future, restore the most-recent past as present.\n"
" No-op if there is nothing to undo.\n"
).
-spec undo(undo_stack(FCR)) -> undo_stack(FCR).
undo(Stack) ->
case erlang:element(2, Stack) of
[] ->
Stack;
[Prev | Rest] ->
{undo_stack,
Rest,
Prev,
[erlang:element(3, Stack) | erlang:element(4, Stack)],
erlang:element(5, Stack)}
end.
-file("src/etui/undo.gleam", 105).
?DOC(
" Redo: move present to past, restore the most-recent future as present.\n"
" No-op if there is nothing to redo.\n"
).
-spec redo(undo_stack(FCU)) -> undo_stack(FCU).
redo(Stack) ->
case erlang:element(4, Stack) of
[] ->
Stack;
[Next | Rest] ->
{undo_stack,
[erlang:element(3, Stack) | erlang:element(2, Stack)],
Next,
Rest,
erlang:element(5, Stack)}
end.
-file("src/etui/undo.gleam", 119).
?DOC(" Reset to initial state, clearing all history.\n").
-spec reset(undo_stack(FCX), FCX) -> undo_stack(FCX).
reset(Stack, Initial) ->
{undo_stack, [], Initial, [], erlang:element(5, Stack)}.