package de.renew.draw.ui.api.services;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

import de.renew.draw.storables.ontology.Drawing;
import de.renew.draw.storables.ontology.DrawingListener;
import de.renew.draw.ui.api.EditorApi;
import de.renew.draw.ui.ontology.DrawingEditor;
import de.renew.draw.ui.ontology.DrawingView;

/**
 * Service class that provides methods for the {@link EditorApi} to call.
 */
public interface EditorService {

    /**
     * Loads drawings from the given URL and opens them in the editor.
     * @param url Url of the drawing that will be opened
     */
    void loadAndOpenDrawings(URL url);

    /**
     * Loads drawings from the given stream with the given name.
     * @param stream given input stream
     * @param fileName name of the file that will be opened in the editor
     */
    void loadAndOpenDrawings(InputStream stream, String fileName) throws IOException;

    /**
     * Opens the drawing from the given file. If it is not in the drawing list, it
     * will be loaded.
     * @param file that will be opened or loaded
     */
    void openOrLoadDrawing(File file);

    /**
     * Checks whether the drawing has some accumulated damage
     * and informs all views about the required update,
     * if necessary.
     */
    void checkDamage();

    /**
     * Repair the damaged area of the current view.
     */
    void repairDamage();

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

    /**
     * Adds the specified mouse listener to receive mouse events from the current view.
     * If the listener is null, no exception is thrown and no action is performed.
     * @param mouseListener Listener that is added
     */
    void addMouseListener(MouseListener mouseListener);


    /**
     * Removes the specified mouse listener to receive mouse events from the current view.
     * If the listener is null, no exception is thrown and no action is performed.
     * @param mouseListener Listener that is removed
     */
    void removeMouseListener(MouseListener mouseListener);

    /**
     * Get the current drawing editor. If no DrawPlugin or no GUI is available, the NullDrawingEditor is returned.
     * <p>
     *     If possible, an interaction with the Editor should not be implemented by working with the result of this method,
     *     but by calling the other methods provided by this service.
     * </p>
     *
     * @return the current drawing editor
     */
    DrawingEditor getCurrentEditor();


    /**
     * Gets the NullDrawingEditor.
     * <p>
     *     If the goal is accessing the NullDrawingEditor when no DrawPlugin or GUI is available, please use {@link #getCurrentEditor()} instead.
     * </p>
     *
     * @return the null drawing editor
     */
    DrawingEditor getNullDrawingEditor();

    /**
     * Gets the NullDrawingView.
     *
     * @return the null drawing view
     */
    DrawingView getNullDrawingView();

    /**
     * Get the current drawing.
     *
     * @return the current drawing
     */
    Drawing getCurrentDrawing();

    /**
     * Get all currently open drawings of the application
     *
     * @return all drawing that are opened
     */
    Enumeration<Drawing> getCurrentDrawings();

    /**
     * Opens the given drawing in the editor.
     * The view frame is created with default position and size.
     *
     * @param drawing the {@code Drawing} to open
     * @return the drawing, which will be opened
     **/
    Drawing openDrawing(Drawing drawing);

    /**
     * Opens the given drawing in the editor at its specified position with specified dimension.
     *
     * @param drawing the drawing that will be opened
     * @param point the position where the drawing will be opened
     * @param dimension the dimension of the drawing
     */
    void openDrawing(Drawing drawing, Point point, Dimension dimension);

    /**
     * Closes the given drawing.
     *
     * @param drawing the drawing to close
     */
    void closeDrawing(Drawing drawing);

    /**
     * Adds a drawing listener to the list of drawing listeners.
     *
     * @param listener the listener to add
     */
    void addDrawingListener(DrawingListener listener);

    /**
     * Removes drawing listener from the list of drawing listeners.
     *
     * @param listener the listener to remove
     */
    void removeDrawingListener(DrawingListener listener);

}
