package de.renew.ioontology.exporting;

import java.awt.Toolkit;
import java.io.File;

import de.renew.ioontology.FileFilter;

/**
 * This interface must be implemented to define new ExportFormats.
 *
 * @param <T> The type of the Object that is exported
 */
public interface ExportFormat<T> {

    /**
     * Returns a name for the ExportFormat, e.g. PNML.
     * @return the name of the ExportFormat
     */
    String formatName();


    /**
     * Returns the FileFilter for the ExportFormat.
     * @return the FileFilter for the ExportFormat
     */
    FileFilter fileFilter();

    /**
     * Converts an object into a file (1 to 1 export).
     * @throws Exception to be caught by the ExportFormatHolder
     * @param object object to be exported
     * @param file file name to export to
     * @return the resulting file
     */
    File export(T object, File file) throws Exception;

    /**
     * Converts an array of objects into a file (n to 1 export).
     * Requires that n to 1 export is possible (see {@link #canExportNto1()}).
     * @throws Exception to be caught by the ExportFormatHolder
     * @param objects array of objects to be exported
     * @param file file name to export to
     * @return the resulting file
     */
    File export(T[] objects, File file) throws Exception;

    /**
     * Converts an array of objects into an array of files (n to n export).
     * @throws Exception to be caught by the ExportFormatHolder
     * @param objects array of objects to be exported
     * @param files array of file names to export to
     * @return the resulting files
     */
    File[] exportAll(T[] objects, File[] files) throws Exception;

    /**
     * Tells whether this {@code ExportFormat} supports files that comprise
     * multiple objects.
     * @return  {@code true} if this format can generate files
     *          including multiple objects.
     *          Returns {@code false}, otherwise.
     */
    boolean canExportNto1();

    /**
     * Tells whether this {@code ExportFormat} can export to a file
     * named {@code path}.
     * @param path  the file name of the exported object
     * @return  {@code true}, if {@code path} is an allowed file
     *          name for this export format.
     *          Returns {@code false}, otherwise.
     */
    ExportFormat<T>[] canExport(File path);

    /**
     * Tells whether this {@code ExportFormat} can export the given
     * {@code object}.
     * @param object  the object of question
     * @return  {@code true}, if this export format can handle the
     *          given {@code object}.
     *          Returns {@code false}, otherwise.
     */
    boolean canExportObject(Object object);

    /**
     * Returns the AWT shortcut key that would be appropriate when
     * including this {@code ExportFormat} in a menu.
     * @return  the {@code int} code of the shortcut key for the export
     *          menu entry associated with this format.
     *          Returns {@code -1} if no shortcut is desired.
     */
    int getShortCut();


    /**
     * Returns the AWT modifier key code.
     * Use {@link Toolkit#getMenuShortcutKeyMaskEx()} for Ctrl. Key.
     * See {@link javax.swing.KeyStroke},
     * {@link java.awt.Toolkit}.
     *
     * @return the {@code int} code of the modifier key for the export
     *          menu entry associated with this format.
     *          Returns {@code -1} if no shortcut is desired.
     */
    int getModifier();

    /**
     * Returns boolean if a given name is to be forced.
     *
     * @return allowance if the given name will be forced
     */
    boolean forceGivenName();
}