/*
 * Created on 06.02.2004 by Joern Schumacher
 *
 */
package CH.ifa.draw;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import CH.ifa.draw.application.DrawApplication;
import CH.ifa.draw.framework.DrawingTypeManager;
import CH.ifa.draw.io.CombinationFileFilter;
import CH.ifa.draw.io.DrawingFileHelper;
import CH.ifa.draw.io.ImportHolder;
import CH.ifa.draw.io.PositionedDrawing;
import CH.ifa.draw.io.SimpleFileFilter;
import CH.ifa.draw.io.importFormats.ImportFormat;
import CH.ifa.draw.io.importFormats.ImportFormatMulti;
import de.renew.draw.storables.api.StorableApi;
import de.renew.draw.storables.ontology.Drawing;
import de.renew.draw.ui.api.ApplicationApi;
import de.renew.draw.ui.api.EditorApi;
import de.renew.ioontology.ExtensionFileFilter;
import de.renew.ioontology.FileFilter;
import de.renew.ioontology.MultiExtensionFileFilter;
import de.renew.ioontology.MultiExtensionFileFilterImpl;
import de.renew.util.StringUtil;


/**
 * This class was designed to extract load/save operations from the
 * DrawPlugin class. This was meant to do two things:
 * <ul>
 * <li>to slim down the DrawPlugin class by providing a delegation target.</li>
 * <li>to facilitate the creation of a I/O plugin.</li>
 * </ul>
 *
 * @author Joern Schumacher
 *
 */
public class IOHelper {
    /**
     * Logger instance for logging messages related to IOHelper operations.
     */
    public static org.apache.log4j.Logger logger =
        org.apache.log4j.Logger.getLogger(IOHelper.class);
    private static IOHelper _instance;
    private File lastPath = new File(System.getProperty("user.dir"));
    private ExtensionFileFilter lastSelectedFileFilter;


    private IOHelper() {
        lastSelectedFileFilter = DrawingTypeManager.getInstance().getDefaultFileFilter();
    }

    /**
     * Gets an instance of IOHelper.
     * @return instance
     */
    public static IOHelper getInstance() {
        if (_instance == null) {
            _instance = new IOHelper();
        }
        return _instance;
    }

    /**
     * Getter for last path.
     * @return last path
     * @deprecated This method is not to be used externally. Please use the method {@link ApplicationApi#getLastPath()}  instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public File getLastPath() {
        return lastPath;
    }

    /**
     * Opens the JFileChooser dialog to get the savePath
     *
     * @param file initial file name/path where to start the dialog, if it is null first tries to get the filename of the current drawing. If that does not work the last path is used.
     * @param ff file filter for the JFileChooser. if null, null is returned
     * @return returns the chosen file or null
     * @deprecated This method is only for internal usage and will later be made private.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public File getSavePath(File file, SimpleFileFilter ff) {
        if (DrawPlugin.getGui() == null) {
            logger.debug("could not open save dialog: no gui!");
        }
        JFileChooser dialog = new JFileChooser();
        if (ff == null) {
            return null;
        }
        if (file == null) {
            file = DrawPlugin.getGui().drawing().getFilename();
        }
        if (file == null) {
            file = lastPath;
        }


        // prepare the dialog
        dialog.setAcceptAllFileFilterUsed(false);
        dialog.setFileFilter(ff);


        // change this
        dialog.setCurrentDirectory(getCurrentDirectory(file));
        file = new File(StringUtil.extendFileNameBy(file.getPath(), ff.getExtension()));
        dialog.setSelectedFile(file);
        int check = dialog.showSaveDialog(DrawPlugin.getGui().getFrame());

        if (check == JFileChooser.APPROVE_OPTION) {
            lastPath = dialog.getCurrentDirectory();
            return dialog.getSelectedFile();
        }
        return null;
    }

    /**
     * Opens the JFileChooser dialog to get the savePath
     *
     * @param file initial file name/path where to start the dialog, if it is null first tries to get the filename of the current drawing. If that does not work the lastpath is used.
     * @param fileFilter file filter for the JFileChooser. if null, null is returned
     * @return returns the chosen file or null
     * @deprecated This method is not to be used externally. Please use the method
     * {@link de.renew.draw.ui.api.DialogApi#showSaveFileDialog(File, FileFilter)} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public File getSavePath(File file, FileFilter fileFilter) {

        if (file == null) {
            return null;
        }

        return getSavePath(file, mapFileFilterToSimpleFileFilter(fileFilter));
    }

    private Collection<SimpleFileFilter> getInputFileFilters() {
        List<SimpleFileFilter> fileFilters = new LinkedList<>();
        Enumeration<String> enumeration = getDrawingTypeManager().getDrawingTypes().keys();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            ExtensionFileFilter filter = getDrawingTypeManager().getFilter(name);
            fileFilters.add(new SimpleFileFilter(filter.getExtension(), filter.getDescription()));
        }
        return fileFilters;
    }

    /**
     * Creates and returns a file filter that includes all supported input file types.
     * The preferred file filter is set to the last one selected by the user.
     *
     * @return file filter for all known input file types
     * @deprecated This method is not to be anymore.
     * Please use the method {@link StorableApi#getKnownDrawingTypesFileFilter()} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public CombinationFileFilter getFileFilter() {
        CombinationFileFilter result = new CombinationFileFilter("All known input file types");
        result.addAll(getInputFileFilters());
        result.setPreferedFileFilter(lastSelectedFileFilter);
        return result;
    }

    /**
     * Creates and returns a file filter that includes all supported input file types.
     * The preferred file filter is set to the last one selected by the user.
     *
     * @return file filter for all known input file types
     * @deprecated This method is not to be used externally.
     * Please use the method {@link StorableApi#getKnownDrawingTypesFileFilter()} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public MultiExtensionFileFilterImpl getFileFilterKnownTypes() {
        MultiExtensionFileFilterImpl result =
            new MultiExtensionFileFilterImpl("All known input file types");
        result.addAll(getInputFileFilters());
        result.setPreferredFileFilter(lastSelectedFileFilter);
        return result;
    }

    /**
     * Creates and returns a file filter that includes all supported input file types
     * as well as file types from available import formats (including nested multi-formats).
     * The preferred file filter is set to the last one selected by the user.
     *
     * @return file filter for all known input file types including import formats
     * @deprecated This method will be removed in a later version. Please use the method {@link #getKnownFileFiltersWithImportFormats()} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public CombinationFileFilter getFileFilterWithImportFormats() {
        CombinationFileFilter result =
            new CombinationFileFilter("All known input file types including import formats");

        // add input file types
        result.addAll(getInputFileFilters());

        // add import format file types
        ImportHolder importHolder =
            Objects.requireNonNull(DrawPlugin.getCurrent()).getImportHolder();
        Queue<ImportFormat> importFormats =
            new LinkedList<>(Arrays.asList(importHolder.allImportFormats()));
        while (!importFormats.isEmpty()) {
            ImportFormat format = importFormats.remove();
            if (format instanceof ImportFormatMulti multiFormat) {
                importFormats.addAll(Arrays.asList(multiFormat.allImportFormats()));
            } else {
                javax.swing.filechooser.FileFilter filter = format.fileFilter();
                if (filter instanceof ExtensionFileFilter) {
                    result.add((ExtensionFileFilter) filter);
                }
            }
        }

        result.setPreferedFileFilter(lastSelectedFileFilter);
        return result;
    }

    /**
     * Creates and returns a file filter that includes all supported input file types
     * as well as file types from available import formats (including nested multi-formats).
     * The preferred file filter is set to the last one selected by the user.
     *
     * @return file filter for all known input file types including import formats
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public MultiExtensionFileFilter getKnownFileFiltersWithImportFormats() {
        MultiExtensionFileFilter result =
            new MultiExtensionFileFilterImpl("All known input file types including import formats");

        // add input file types
        result.addAll(getInputFileFilters());

        // add import format file types
        ImportHolder importHolder =
            Objects.requireNonNull(DrawPlugin.getCurrent()).getImportHolder();
        Queue<ImportFormat> importFormats =
            new LinkedList<>(Arrays.asList(importHolder.allImportFormats()));
        while (!importFormats.isEmpty()) {
            ImportFormat format = importFormats.remove();
            if (format instanceof ImportFormatMulti multiFormat) {
                importFormats.addAll(Arrays.asList(multiFormat.allImportFormats()));
            } else {
                javax.swing.filechooser.FileFilter filter = format.fileFilter();
                if (filter instanceof ExtensionFileFilter) {
                    result.add((ExtensionFileFilter) filter);
                }
            }
        }

        result.setPreferredFileFilter(lastSelectedFileFilter);
        return result;
    }

    /**
     * Returns the singleton instance of the DrawingTypeManager.
     *
     * @return the instance of the DrawingTypeManager
     * @deprecated This method is not to be used externally and will later be hidden.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    protected DrawingTypeManager getDrawingTypeManager() {
        return DrawingTypeManager.getInstance();
    }


    /**
     * Opens a file dialog according to the parameters and returns the
     * selected/entered files.
     *
     * @param file     The default file name of the drawing to be proposed
     *                 to the user. The file name is checked and completed
     *                 to end with one of the default Extensions before.
     *                 If the file name is prefixed with a directory, the
     *                 dialog initially switches its actual directory to
     *                 this prefix. In the other case, the actual directory
     *                 is set to the last directory used for files with the
     *                 file's extension.
     * @param ff       The array of FileFilter that determines the selectable file
     *                 types in the JFileChooser.
     * @return         The file name that was selected or entered by the
     *                 user. Returns <code>null</code>, if the dialog was
     *                 cancelled.
     * @deprecated This method is only for internal usage and will later be made private.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public File getSavePath(File file, SimpleFileFilter[] ff) {
        if (DrawPlugin.getGui() == null) {
            logger.debug("could not open save dialog: no gui!");
        }
        JFileChooser dialog = new JFileChooser();
        if (ff == null) {
            return null;
        }
        if (file == null) {
            file = DrawPlugin.getGui().drawing().getFilename();
        }
        if (file == null) {
            file = lastPath;
        }


        // prepare the dialog
        dialog.setAcceptAllFileFilterUsed(false);
        for (SimpleFileFilter simpleFileFilter : ff) {
            dialog.addChoosableFileFilter(simpleFileFilter);
        }
        dialog.setFileFilter(ff[0]);

        // change this
        dialog.setCurrentDirectory(getCurrentDirectory(file));

        file = new File(StringUtil.extendFileNameBy(file.getPath(), ff[0].getExtension()));

        dialog.setSelectedFile(file);
        int check = dialog.showSaveDialog(DrawPlugin.getGui().getFrame());

        if (check == JFileChooser.APPROVE_OPTION) {
            lastPath = dialog.getCurrentDirectory();
            return DrawingFileHelper.checkAndAddExtension(
                dialog.getSelectedFile(), (SimpleFileFilter) dialog.getFileFilter());
        }
        return null;
    }

    /**
     * Opens a file dialog according to the parameters and returns the
     * selected/entered files.
     *
     * @param file     The default file name of the drawing to be proposed
     *                 to the user. The file name is checked and completed
     *                 to end with one of the default Extensions before.
     *                 If the file name is prefixed with a directory, the
     *                 dialog initially switches its actual directory to
     *                 this prefix. In the other case, the actual directory
     *                 is set to the last directory used for files with the
     *                 file's extension.
     * @param fileFilters The array of FileFilter that determines the selectable file
     *                 types in the JFileChooser.
     * @return         The file name that was selected or entered by the
     *                 user. Returns <code>null</code>, if the dialog was
     *                 cancelled.
     * @deprecated This method is only for internal usage and will later be made private.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public File getSavePath(File file, FileFilter[] fileFilters) {

        if (fileFilters == null) {
            return null;
        }

        return getSavePath(file, mapFilters(fileFilters));

    }

    /**
     * Returns the directory to propose for the next file open or save
     * operation.
     *
     * @param file  a file to get the directory from.
     *              May be <code>null</code>.
     * @return the directory where the given file resides, if it exists.
     *         Returns the last directory used in any file dialog,
     *         otherwise.
     * @deprecated This method is not to be used externally.
     * Please use the method {@link ApplicationApi#getLastPath()} to access the last directory instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public File getCurrentDirectory(File file) {
        File f;
        if (file != null && (f = file.getParentFile()) != null && f.exists()) {
            return f;
        }
        return lastPath;
    }

    /**
     * Opens a file dialog according to the parameters
     * and returns the selected/entered files.
     * @param filename     File name to propose to the user.
     *                     The file name is checked and completed
     *                     to end with one of the default Extensions.
     *                     If the file name is prefixed with a
     *                     directory, the dialog initially switches
     *                     its actual directory to this prefix.
     *                     In the other case, the actual directory is
     *                     set to the last directory used for files
     *                     with the file's extension.
     * @param ff           The FileFilter that determines the
     *                     selectable file types in the JFileChooser.
     *                     Usually a CombinationFileFilter to be able to choose
     *                     a specific file type or a SimpleFileFilter if the
     *                     file type shall be fixed.
     * @param multiSelection Multiselection can be chosen.
     *                     When turned off the method returns an array
     *                     of File with only one element.
     * @return             Array of <code>File</code> objects or <code>null</code>, if
     *                     the dialog was cancelled.
     *                     The files are <i>not</i> checked and completed to
     *                     end with one of the default extensions
     *                     before they get returned.
     * @see #getLoadPath
     * @see #getSavePath
     * @see javax.swing.JFileChooser
     * @deprecated This method is not to be used externally. Please use the method
     * {@link de.renew.draw.ui.api.DialogApi#showSelectFilesDialog(File, FileFilter, boolean)} instead.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public File[] getLoadPath(
        File filename, javax.swing.filechooser.FileFilter ff, boolean multiSelection)
    {
        File currentDir = getCurrentDirectory(filename);

        JFileChooser dialog = new JFileChooser(currentDir);

        // do not provide the *
        dialog.setAcceptAllFileFilterUsed(false);
        dialog.setMultiSelectionEnabled(multiSelection);


        // but add all the FileFilter that are available
        //dialog.setCurrentDirectory(new File("projects"));
        if (ff != null) {
            // SimpleFileFilter can be combined to a new one with a new description add 
            // if so add also all the internal SimpleFilFilter
            if (ff instanceof CombinationFileFilter cff) {

                // Setting the current file filter first avoids bug #6189.
                dialog.setFileFilter(cff.getPreferedFileFilter());

                // sort the filters alphabetically
                List<SimpleFileFilter> filters = new ArrayList<>(cff.getFileFilters());
                filters.sort(Comparator.comparing(SimpleFileFilter::getExtension));

                for (SimpleFileFilter simpleFileFilter : filters) {
                    dialog.addChoosableFileFilter(simpleFileFilter);
                }
            } else if (ff instanceof MultiExtensionFileFilter multiff) {

                // Setting the current file filter first avoids bug #6189.
                dialog.setFileFilter(mapToSwingFileFilter(multiff.getPreferredFileFilter()));

                // sort the filters alphabetically
                List<ExtensionFileFilter> filters = new ArrayList<>(multiff.getFileFilters());
                filters.sort(Comparator.comparing(ExtensionFileFilter::getExtension));

                for (ExtensionFileFilter simpleFileFilter : filters) {
                    dialog.addChoosableFileFilter(mapToSwingFileFilter(simpleFileFilter));
                }
            } else {
                dialog.addChoosableFileFilter(ff);
            }
        } else {
            // not sure what to do so add * // this should not happen
            dialog.setAcceptAllFileFilterUsed(true);
        }
        if (filename != null) {
            dialog.setCurrentDirectory(filename);
        }
        int check;
        check = dialog.showOpenDialog(DrawPlugin.getGui().getFrame());
        if (check == JFileChooser.APPROVE_OPTION) {
            lastPath = dialog.getCurrentDirectory();
            javax.swing.filechooser.FileFilter simpleff = dialog.getFileFilter();
            if (simpleff instanceof ExtensionFileFilter
                && DrawingTypeManager.getInstance().getDrawingTypes().containsValue(simpleff)) {
                lastSelectedFileFilter = (ExtensionFileFilter) simpleff;
            }
            if (multiSelection) {
                return dialog.getSelectedFiles();
            } else {
                return new File[] { dialog.getSelectedFile() };
            }
        }
        return null;
    }

    /**
     * Opens a file dialog according to the parameters
     * and returns the selected/entered file. The user will not be able to
     * select more than one file.
     *
     * @param filename     a file name to propose to the user.
     *                     The file name is checked and completed
     *                     to end with one of the default Extensions.
     *                     If the file name is prefixed with a
     *                     directory, the dialog initially switches
     *                     its actual directory to this prefix.
     *                     In the other case, the actual directory is
     *                     set to the last directory used for files
     *                     with the file's extension.
     * @param ff           The FileFilter that determines the
     *                     selectable file types in the JFileChooser.
     * @return             The chosen <code>File</code> object. <br>
     *                     Returns <code>null</code>, if the dialog was cancelled.
     *                     The file name is <i>not</i> checked and completed to
     *                     end with one of the default extensions
     *                     before it gets returned.
     * @see #getLoadPath(File, javax.swing.filechooser.FileFilter)
     * @see JFileChooser
     * @deprecated This method is not to be used externally. Please use the method
     * {@link de.renew.draw.ui.api.DialogApi#showSelectFilesDialog(File, FileFilter)} instead.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public File getLoadPath(File filename, javax.swing.filechooser.FileFilter ff) {
        File[] files = getLoadPath(filename, ff, false);
        if (files == null) {
            return null;
        }
        return files[0];
    }

    /**
      * Returns the files to be imported.
      * @param filter the FileFilter which is used
      * @return File[] an array of files to be imported.
      * @deprecated This method is not to be used externally. Please use the method
      * {@link de.renew.draw.ui.api.DialogApi#showSelectFilesDialog(FileFilter)} instead.
      */
    @Deprecated(since = "5.0", forRemoval = true)
    public File[] getLoadPath(javax.swing.filechooser.FileFilter filter) {
        File[] result;
        result = getLoadPath(null, filter, true);
        if (result == null) {
            result = new File[0];
        }
        return result;
    }

    /**
      * Returns the files to be imported.
      * @param filters an array of FileFilters that are used.
      * @return File[] an array of files to be imported.
     * @deprecated This method is only for internal usage and will later be made private.
      */
    @Deprecated(since = "5.0", forRemoval = true)
    public File[] getLoadPath(javax.swing.filechooser.FileFilter[] filters) {
        File[] result;
        MultiExtensionFileFilterImpl filter = new MultiExtensionFileFilterImpl("All");
        for (javax.swing.filechooser.FileFilter fileFilter : filters) {
            filter.add((SimpleFileFilter) fileFilter);
        }
        result = getLoadPath(filter);
        assert (result != null) : "Failure in GuiPlugin: result == null";
        return result;
    }

    /**
     * TODO: JSC: put into DrawApplication
     * Loads drawings from the given URL and opens them in the editor.
     *
     * @param url  the location where to retrieve the drawings.
     * @deprecated This method is not to be used externally. Please use the method {@link EditorApi#loadAndOpenDrawings(URL)} instead.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public synchronized void loadAndOpenDrawings(URL url) {
        List<PositionedDrawing> posDrawings =
            DrawingFileHelper.loadPositionedDrawingList(url, null);
        for (PositionedDrawing d : posDrawings) {
            DrawPlugin.getGui().openDrawing(d);
        }
    }

    /**
     * Loads drawings from the given stream with the given name.
     *
     * @param stream stream containing the drawing
     * @param name name of the drawing
     * @throws FileNotFoundException file not found
     * @throws IOException any other IO exception
     * @deprecated This method is not to be used externally. Please use the method {@link EditorApi#loadAndOpenDrawings(InputStream, String)} instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public synchronized void loadAndOpenDrawings(InputStream stream, String name)
        throws FileNotFoundException, IOException
    {
        PositionedDrawing posDrawing = DrawingFileHelper.loadPositionedDrawing(stream, name);
        if (posDrawing != null) {
            try {
                DrawApplication gui = DrawPlugin.getGui();
                if (gui != null) {
                    gui.openDrawing(posDrawing);
                }
            } catch (Exception e) {
                logger.error(e);
            }
        }
    }

    /**
     * Loads a positioned drawing into a view container
     *
     * @param drawing drawing which should be loaded
     * @deprecated This method is currently not used and will be removed in a later version.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public synchronized void loadInViewContainer(PositionedDrawing drawing) {
        DrawApplication gui = DrawPlugin.getGui();
        if (gui != null) {
            gui.openDrawing(drawing);
        }
    }

    /**
     * TODO: JSC: put into DrawApplication
     * Loads drawings from the given file and opens them in the editor.
     *
     * @param file  the file name where to retrieve the drawings.
     * @deprecated This method is only for internal usage and will later be made private.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public synchronized void loadAndOpenDrawings(File file) {
        List<PositionedDrawing> posDrawings =
            DrawingFileHelper.loadPositionedDrawingList(file, null);

        for (PositionedDrawing d : posDrawings) {
            DrawPlugin.getGui().openDrawing(d);
            d.getDrawing().init();
        }
    }

    /**
     * Queries the user to choose a file name to save the drawing into.
     *
     * @param file     the previous file name of the drawing or another file
     *                 name to propose to the user.
     * @param filter   an array of <code>SimpleFileFilter</code>s denoting
     *                 the available file formats and their extensions.
     * @param drawing  the <code>Drawing</code> to save.
     * @return  the file name chosen by the user.
     *          Returns <code>null</code> if the action was cancelled by
     *          the user.
     * @deprecated This method is only for internal usage and will later be made private.
     **/
    @Deprecated(since = "5.0", forRemoval = true)
    public File getSaveFile(File file, SimpleFileFilter[] filter, Drawing drawing) {
        File result = null;
        if (file == null) {
            file = drawing.getFilename();
            if (file == null) {
                file = new File(getLastPath(), drawing.getName());
                file = DrawingFileHelper.checkAndAddExtension(file, filter[0]);
            }
        }
        File path = getSavePath(file, filter);
        if (path != null) {
            // If the file exists already, ask for permission to overwrite
            if (path.exists()) {
                DrawApplication app = DrawPlugin.getGui();

                // new Swing confirm dialog
                int answer = JOptionPane.showConfirmDialog(
                    app.getFrame(),
                    "The file \"" + path + "\"" + " does already exist."
                        + "\nDo you want do proceed?",
                    "Renew: Confirm overwrite.", JOptionPane.YES_NO_OPTION);

                if (answer == JOptionPane.OK_OPTION) {
                    result = path;
                }
            } else {
                result = path;
            }
        }
        return result;
    }

    /**
     * Queries the user to choose a file name to save the drawing into.
     *
     * @param file     the previous file name of the drawing or another file
     *                 name to propose to the user.
     * @param fileFilters an array of <code>FileFilter</code>s denoting
     *                 the available file formats and their extensions.
     * @param drawing  the <code>Drawing</code> to save.
     * @return  the file name chosen by the user.
     *          Returns <code>null</code> if the action was cancelled by
     *          the user.
     **/
    public File getSaveFile(File file, FileFilter[] fileFilters, Drawing drawing) {

        if (fileFilters == null) {
            return null;
        }

        return getSaveFile(file, mapFilters(fileFilters), drawing);

    }

    /**
     * sets the last path
     * @param lp new last path
     */
    public void setLastPath(File lp) {
        this.lastPath = lp;
    }

    private SimpleFileFilter[] mapFilters(FileFilter[] fileFilters) {

        SimpleFileFilter[] filters = Arrays.stream(fileFilters)
            .map(IOHelper::mapFileFilterToSimpleFileFilter).toArray(SimpleFileFilter[]::new);

        return filters;

    }

    private static SimpleFileFilter mapFileFilterToSimpleFileFilter(FileFilter original) {
        if (original == null) {
            return null;
        }
        if (original instanceof SimpleFileFilter) {
            return (SimpleFileFilter) original;
        } else if (original instanceof MultiExtensionFileFilter multiFileFilter) {
            return new SimpleFileFilter(
                multiFileFilter.getPreferredFileFilter().getExtension(),
                multiFileFilter.getDescription())
            {
                @Override
                public boolean accept(File f) {
                    return multiFileFilter.accept(f);
                }
            };
        } else if (original instanceof de.renew.ioontology.ExtensionFileFilter extensionFileFilter) {
            return new SimpleFileFilter(
                extensionFileFilter.getExtension(), extensionFileFilter.getDescription());
        }
        SimpleFileFilter simpleFileFilter = new SimpleFileFilter() {

            @Override
            public boolean accept(File f) {
                return original.accept(f);
            }
        };
        simpleFileFilter.setDescription(original.getDescription());
        return simpleFileFilter;
    }

    /**
     * Maps a renew IO file filter to a Swing File filter.
     * It offers a temporary solution to allow using existing functionality with objects of the new ontology type.
     *
     * @param fileFilter the file filter to be mapped
     * @return the file filter as a {@link javax.swing.filechooser.FileFilter} object.
     * @deprecated This method is not to be used if possible.
     * If you are using swing file filters to create swing dialogs,
     * please use the methods of the {@link de.renew.draw.ui.api.DialogApi} to create the dialogs instead.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public static javax.swing.filechooser.FileFilter mapToSwingFileFilter(FileFilter fileFilter) {
        return new javax.swing.filechooser.FileFilter() {

            @Override
            public boolean accept(File f) {
                return fileFilter.accept(f);
            }

            @Override
            public String getDescription() {
                return fileFilter.getDescription();
            }
        };
    }
}