import { Events } from '../coreUtils/events';
import type { TranslatedText } from '../coreUtils/i18n';
/**
 * Represents an atomic change to the state tracked by the command history,
 * which could be performed and reverted later if needed.
 *
 * @category Core
 * @see {@link CommandHistory}
 */
export interface Command {
    /**
     * Command title to display in the UI.
     */
    readonly title?: TranslatedText | string;
    /**
     * Performs the command action.
     *
     * @returns Inverse command to reverse changes done by the action.
     */
    invoke(): Command;
}
/**
 * Command action which can be executed for its effect.
 *
 * @returns Inverse command
 */
export type CommandAction = () => Command;
/**
 * Utility functions to create commands of different kinds.
 *
 * @category Core
 */
export declare namespace Command {
    /**
     * Creates a basic reversible command.
     *
     * **Example**:
     * ```ts
     * function changeFoo(store: FooStore, foo: Foo): Command {
     *     return Command.create('Set foo', () => {
     *         const previous = store.foo;
     *         store.setFoo(foo);
     *         return changeFoo(store, previous);
     *     });
     * }
     * ```
     */
    function create(title: TranslatedText | string, action: CommandAction): Command;
    /**
     * Creates a command which only does its action in one direction,
     * i.e. performs an effect on the execution but skips it when being undone
     * or vice-versa.
     */
    function effect(title: TranslatedText | string, body: () => void): Command;
    /**
     * Creates a command composed of multiple other commands.
     *
     * When executed, sub-commands in be executed in the same order,
     * and the inverse command will use a reversed order of the sub-command inverses.
     */
    function compound(title: TranslatedText | string | undefined, commands: ReadonlyArray<Command>): Command;
}
/**
 * Event data for {@link CommandHistory} events.
 *
 * @see {@link CommandHistory}
 */
export interface CommandHistoryEvents {
    /**
     * Triggered when command history changes after a command is executed,
     * undone, redone or the history is cleared.
     */
    historyChanged: CommandHistoryChangedEvent;
}
/**
 * Event data for command history changed event.
 */
export interface CommandHistoryChangedEvent {
    /**
     * `true` if there are any changes which could be reverted.
     */
    readonly hasChanges: boolean;
}
/**
 * Provides an undo/redo mechanism to the diagram model and components.
 *
 * To make it possible to undo/redo the changes, all state modifications
 * are organized in a form of atomic commands. These commands can be
 * combined into a command batch to be presented to user as a single
 * meaningful operation.
 *
 * @category Core
 */
export interface CommandHistory {
    /**
     * Events for the command history.
     */
    readonly events: Events<CommandHistoryEvents>;
    /**
     * Current stack of operation which could be undone (reverted).
     *
     * Latest executed (or redone) commands are put at the end of the stack.
     */
    readonly undoStack: ReadonlyArray<Command>;
    /**
     * Current stack of operation which could be redone (performed again after being undone).
     *
     * Latest undone commands are put at the end of the stack.
     */
    readonly redoStack: ReadonlyArray<Command>;
    /**
     * Clears undo and redo stacks of commands.
     */
    reset(): void;
    /**
     * Undoes (reverts) the latest executed command and puts it into redo stack.
     *
     * If undo stack is empty, does nothing.
     */
    undo(): void;
    /**
     * Redoes (performs again) the latest undone command.
     *
     * If redo stack is empty, does nothing.
     */
    redo(): void;
    /**
     * Executes the specified command and puts its inverse into undo stack.
     */
    execute(command: Command): void;
    /**
     * Puts the inverse command directly into undo stack.
     */
    registerToUndo(command: Command): void;
    /**
     * Starts a new command batch which will be active either stored or discarded.
     *
     * When a batch is active, all executed or registered to undo commands will be put
     * into the batch instead of the undo stack, so it could be undo as whole later.
     *
     * Starting a new batch when there is an active command batch already
     * causes the new batch to become nested, which allows to use operations creating
     * command batches as part of a larger operation having its own top-level batch.
     */
    startBatch(title?: TranslatedText | string): CommandBatch;
}
/**
 * Provide the means to store or discard command batch.
 *
 * @category Core
 * @see {@link CommandHistory.startBatch}
 */
export interface CommandBatch {
    /**
     * Command history which owns this batch.
     */
    readonly history: CommandHistory;
    /**
     * Stores the batch, combining the nested command sequence
     * into a single revertible command.
     */
    store(): void;
    /**
     * Discards the batch, throwing away all nested commands, so they cannot be undone.
     *
     * This is useful when performing state changes on temporary items to
     * avoid being able to revert it.
     */
    discard(): void;
}
/**
 * Implements command history which stores all commands in memory.
 *
 * @category Core
 */
export declare class InMemoryHistory implements CommandHistory {
    private readonly source;
    readonly events: Events<CommandHistoryEvents>;
    private readonly _undoStack;
    private readonly _redoStack;
    private readonly batches;
    get undoStack(): ReadonlyArray<Command>;
    get redoStack(): ReadonlyArray<Command>;
    private hasChanges;
    reset(): void;
    undo(): void;
    redo(): void;
    execute(command: Command): void;
    registerToUndo(command: Command): void;
    private topBatch;
    startBatch(title?: TranslatedText | string): CommandBatch;
}
//# sourceMappingURL=history.d.ts.map