package de.renew.draw.ui.ontology.undoredo;

import de.renew.draw.storables.ontology.Drawing;

/**
 * Manages undo and redo histories for each drawing.
 * <p>
 * The undo support works as follows:
 * </p>
 * <p>
 * If a drawing is created/loaded, an undo history
 * should immediately be created by {@link #newUndoHistory}.
 * The {@code DrawApplication} does this by default when a drawing is added.
 * </p>
 * <p>
 * Each action/command/tool/handle/... which modifies
 * the drawing should <UL>
 * <LI> prepare an undo snapshot <b>before</b> the modifications
 *      are applied to the drawing ({@link #prepareUndoSnapshot}) </LI>
 * <LI> commit the snapshot after the changes took place
 *      ({@link #commitUndoSnapshot}) </LI>
 * <LI> just omit the 2nd step if no changes were made. </LI>
 * </UL>
 * <p>
 * For commands and tools, there exist classes which can be
 * inherited ({@code UndoableCommand}, {@code UndoableTool}).
 * They provide a default behavior which implements the steps above.
 * For Handles, the implementation of {@code AbstractHandle}
 * also provides a default undo support.
 * </p>
 * <p>
 * Undo and redo snapshots are restored by the methods
 * {@link #restoreUndoSnapshot} and {@link #restoreRedoSnapshot}.
 * The {@code UndoRedoCommand} uses these methods.
 * </p>
 * @author Clara von Bargen
 */
public interface UndoRedoManager {

    /**
     * Takes a snapshot of the given drawing and
     * remembers it until it will be added by {@link #commitUndoSnapshot}.
     * Any previously prepared snapshot will be forgotten.
     * @param drawing drawing to snapshotted
     */
    void prepareUndoSnapshot(Drawing drawing);

    /**
     * Takes the last prepared snapshot and
     * appends it to the undo history of the given drawing.
     * The redo history is cleared.
     */
    void commitUndoSnapshot(Drawing drawing);

    /**
     * Restores the drawing to the state saved by the last
     * call to {@link #commitUndoSnapshot}.
     * Additional calls to this method will restore more
     * undo snapshots step by step, until the history is empty.
     * @param drawing drawing whose undo history should be used for restoration.
     * The effect can be undone by a call to {@link #restoreUndoSnapshot}.
     */
    void restoreUndoSnapshot(Drawing drawing);

    /**
     * Restores the drawing to the state it had before the last undo.
     * @param drawing drawing to be restored
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void restoreRedoSnapshot(Drawing drawing);

    /**
     * Returns the undo history for the given drawing.
     * May return <code>null</code> if there is no history kept for the drawing.
     * @param drawing drawing with undo history
     * @return undo history for given drawing
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    SnapshotHistory getUndoHistory(Drawing drawing);

    /**
     * Returns the redo history for the given drawing.
     * May return <code>null</code> if there is no history kept for the drawing.
     * @param drawing drawing with redo history
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    SnapshotHistory getRedoHistory(Drawing drawing);

    /**
     * Clears undo <b>and</b> redo history for the given drawing.
     * @param drawing drawing with undo and redo history
     */
    void clearUndoHistory(Drawing drawing);

    /**
     * Enables the undo/redo history management for the given drawing.
     * @param drawing drawing given
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void newUndoHistory(Drawing drawing);

    /**
     * Prohibits the management of undo and redo snapshots
     * for the given drawing.
     * @param drawing drawing with enabled management
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void removeUndoHistory(Drawing drawing);

    /**
     * Prepares an undo snapshot only if no snapshot commit task is pending.
     * @param drawing drawing with snapshot
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void prepareAccumulatedUndoSnapshot(Drawing drawing);

    /**
     * Triggers an accumulated undo snapshot for scheduled commitment. If this
     * method is called multiple times in a certain time range
     * (800 ms), a previously scheduled commit task is canceled.
     * @param drawing drawing with snapshot
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void triggerAccumulatedUndoSnapshot(final Drawing drawing);
}