/*
 * @(#)DrawingEditor.java 5.1
 *
 */

package de.renew.draw.ui.ontology;

import java.awt.Image;
import java.awt.event.KeyEvent;
import java.io.File;

import de.renew.draw.storables.ontology.Drawing;
import de.renew.draw.storables.ontology.TextHolder;
import de.renew.draw.ui.api.ApplicationApi;
import de.renew.draw.ui.api.UndoRedoApi;
import de.renew.draw.ui.ontology.undoredo.UndoRedoManager;

/**
 * DrawingEditor defines the interface for coordinating
 * the different objects that participate in a drawing editor.
 *
 * <hr>
 * <b>Design Patterns</b><P>
 * <img src="images/red-ball-small.gif" width=6 height=6 alt=" o ">
 * <b><a href=../pattlets/sld022.htm>Mediator</a></b><br>
 * DrawingEditor is the mediator. It decouples the participants
 * of a drawing editor.
 * <hr>
 *
 * See {@link Tool}, {@link DrawingView}, {@link Drawing}.
 */
public interface DrawingEditor {

    /**
     * Gets the editor's current drawing view.
     *
     * @return editor's current drawing view
     */
    DrawingView view();

    /**
     * Gets the drawing view that was active before the current drawing view.
     *
     * @return the drawing view that was active before the current drawing view
     */
    DrawingView previousView();

    /**
     * Gets the editor's current drawing.
     *
     * @return current drawing
     */
    Drawing drawing();

    /**
     * Gets the editor's current tool.
     *
     * @return current tool
     */
    Tool tool();

    /**
     * Gets the editor's default tool.
     * This is usually the selection tool.
     *
     * @return editor default tool
     */
    Tool defaultTool();

    /**
     * Sets the sticky tool mode.
     *
     * @param sticky if the tool mode is to be sticky (<code>true</code>) or not (<code>false</code>)
     */
    void setStickyTools(boolean sticky);

    /**
     * Gets the sticky tool mode.
     *
     * @return sticky tool mode
     */
    boolean isStickyTools();

    /**
     * Retrieves an Image from the editor, which can be used as the standard icon image.
     *
     * @return the image from the editor
     * @deprecated This method is not to be used externally. Please use the method {@link ApplicationApi#getIconImage()} instead.
     */
    @Deprecated
    Image getIconImage();

    /**
     * Processes a single event
     *
     * @param evt the event
     */
    void dispatchEvent(KeyEvent evt);

    /**
     * Informs the editor that a tool has done its interaction.
     * This method can be used to switch back to the default tool.
     */
    void toolDone();

    /**
     * Informs that the current selection has changed.
     * Override this method to handle selection changes.
     *
     * @param view that has changed
     */
    void selectionChanged(DrawingView view);

    /**
     * Informs that the menu entries should be rechecked
     * if they are enabled.
     */
    void menuStateChanged();

    /**
     * Shows a status message in the editor's user interface.
     *
     * @param string the message to show
     */
    void showStatus(String string);

    /**
     * Takes a snapshot of the drawing currently active and
     * remembers it until it will be added by commitUndoSnapshot().
     * Any previously prepared snapshot will be forgotten.
     * <p>
     * Convenience method, equivalent to <code>
     * getUndoRedoManager().prepareUndoSnapshot(drawing())</code>.
     * @deprecated This method is not to be used externally.
     * Please use the method {@link UndoRedoApi#prepareUndoSnapshot()} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void prepareUndoSnapshot();

    /**
     * Takes the last prepared snapshot and
     * appends it to the undo history of the drawing.
     * The redo history is cleared.
     * <p>
     * Convenience method, equivalent to <code>
     * getUndoRedoManager().commitUndoSnapshot(drawing())</code>.
     * @deprecated This method is not to be used externally.
     * Please use the method {@link UndoRedoApi#commitUndoSnapshot()} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void commitUndoSnapshot();

    /**
     * Takes a snapshot of the drawing currently active only if no other
     * accumulated snapshot is already triggered.
     *
     * <p>
     * Convenience method, equivalent to <code>
     * getUndoRedoManager().prepareAccumulatedUndoSnapshot(drawing())</code>.
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void prepareAccumulatedUndoSnapshot();

    /**
     * Triggers the commit of the last prepared snapshot to be executed after
     * some time of inactivity (no further changes).
     * <p>
     * Convenience method, equivalent to <code>
     * getUndoRedoManager().triggerAccumulatedUndoSnapshot(drawing())</code>.
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    void triggerAccumulatedUndoSnapshot();

    /**
     * Returns the undo and redo history manager.
     * <p>
     *    If possible, the UndoRedoApi is to be used instead of this methods.
     * </p>
     *
     * @return the undo and redo history manager
     */
    UndoRedoManager getUndoRedoManager();

    /**
     * Activated a specific drawing view in the editor.
     *
     * @param viewContainer the container where the drawing to be closed
     */
    void drawingViewContainerActivated(DrawingViewContainer viewContainer);

    /**
     * Close a specific drawing view in the editor.
     *
     * @param viewContainer the container where the drawing to be closed
     */
    void drawingViewContainerClosing(DrawingViewContainer viewContainer);

    /**
     * Sets the current drawing which the editor chooses.
     *
     * @param dvc the container where the drawing is located
     */
    void setCurrentDrawing(DrawingViewContainer dvc);

    /**
     * Edit a given TextFigure.
     *
     * @param textfigure the figure to edit
     */
    void doTextEdit(TextHolder textfigure);

    /**
     * Return the editors current toolbar.
     *
     * @return the toolbar
     */
    Toolbar getToolbar();

    /**
     * Register a factory ID. When a new drawing is created, the factory with the given ID is used.
     * 
     * @param key use "Drawing.getClass().getName()"
     * @param id the id of the factory registered at the {@link de.renew.windowmanagement.Workbench}
     * @deprecated This method is not to be used externally. Please use the method {@link ApplicationApi#registerDrawingViewFactory(Class, String)} instead.
     */
    @Deprecated
    void registerDrawingViewFactoryID(Class key, String id);

    /**
     * Opens the drawing from the given file. If it is not in the drawing list, it
     * will be loaded.
     *
     * @param file the file containing the drawing
     */
    default void openOrLoadDrawing(File file) {}

    /**
     * Opens the drawing from the given file. If it is not in the drawing list, it
     * will be loaded. The drawing will be moved to the same location as the given drawingView.
     *
     * @param file the file containing the drawing
     * @param drawingView the drawing view, which location shall be used for the new drawing
     */
    default void openOrLoadDrawing(File file, DrawingView drawingView) {}
}