/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.plugin;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import net.sf.jaxodraw.graph.JaxoGraph;
import net.sf.jaxodraw.gui.JaxoDialogs;
import net.sf.jaxodraw.util.JaxoLanguage;

/** An abstract superclass for all import plugins.
 * @since 2.0
 */
public abstract class JaxoImportPlugin extends AbstractJaxoPlugin {
    private String charsetName;
    private static final JComponent CONF_PANEL = new JLabel(" ");

    /**
     * Returns the current charset name. Defaults to null, which means
     * the system default encoding will be used for reading files.
     *
     * @return The current charset name.
     */
    public String getCharsetName() {
        return charsetName;
    }

    /**
     * Sets the charset name.
     *
     * @param name The charset to use. No check is done here whether the
     * given charset name is valid or the corresponding Charset is supported.
     * Set this to null to use the system default encoding.
     */
    public void setCharsetName(final String name) {
        this.charsetName = name;
    }

    /** Imports a graph from the given file.
     * @param fileName The absolute path to the file to be imported
     * @return The imported JaxoGraph or null, if no file was imported
     */
    public JaxoGraph importGraph(final String fileName) {
        return importGraph(new File(fileName));
    }

    /** Imports a graph from the given file.
     * @param f The file to be imported
     * @return The imported JaxoGraph or null, if no file was imported
     */
    public JaxoGraph importGraph(final File f) {

        InputStream inputStream = null;

        try {
            inputStream = new FileInputStream(f);
        } catch (FileNotFoundException e) {
            try {
                if (f.exists()) {
                    showImportError(f, "JaxoIO.read%0OpenFailed");
                } else {
                    showImportError(f, "JaxoIO.read%0NotFound");
                }
                getLog().debug(e);
            } finally {
                close(inputStream);
            }
            return null;
        }

        JaxoGraph openedGraph = null;

        try {
            openedGraph = importGraph(inputStream);
        } catch (JaxoPluginExecutionException e) {
            final String msg = e.getMessage();
            getLog().warn(msg);
            setFailure(e); // this logs in debug mode
            if (e.getSource() != null) {
                getLog().debug("Source: " + e.getSource().toString());
            }
            showImportError(f, msg, "JaxoImport.import%0ImportFailed%1Message");
        } finally {
            close(inputStream);
        }

        if (openedGraph != null) {
            openedGraph.setSaveFileName(f.getAbsolutePath());
        }

        return openedGraph;
    }

    /**
     * Returns a panel that allows to configure optional
     * parameters of this import format. By default, an empty component
     * is returned, implementing classes should override this
     * to provide a custom component.
     *
     * @return an empty component by default.
     */
    public JComponent getConfigurationPanel() {
        return CONF_PANEL;
    }

    /**
     * Apply the changes made in the configuration panel.
     * By default does nothing, implementing classes should override this
     * to provide a custom behavior.
     */
    public void commitConfiguration() {
        // do nothing by default
    }

      //
     // private methods
    //

    private void showError(final File f, final String key, final String title) {
        JOptionPane.showMessageDialog(getParentComponent(), JaxoLanguage.message(key, f),
            JaxoDialogs.translatedWindowTitle(title), JOptionPane.ERROR_MESSAGE);
    }

    private void showImportError(final File f, final String key) {
        showError(f, key,
            JaxoLanguage.message("JaxoIO.import%0ErrorTitle", new Object[]{f}));
    }

    private void showImportError(final File f, final String msg, final String key) {
        JOptionPane.showMessageDialog(getParentComponent(),
            JaxoLanguage.message(key, new Object[]{f, msg}),
            errorDialogTitle(f), JOptionPane.ERROR_MESSAGE);
    }

    private String errorDialogTitle(final File f) {
        return JaxoDialogs.translatedWindowTitle(
            JaxoLanguage.message("JaxoIO.import%0ErrorTitle", new Object[]{f}));
    }

      //
     // Abstract methods
    //

    /**
     * Import a graph from a Reader.
     *
     * @param inputStream An InputStream to supply the input data.
     * @return The imported JaxoGraph or null, if importing failed.
     * @throws JaxoPluginExecutionException if the graph could not be imported.
     *  Note that the message of the Exception should be
     *  an internationalized String.
     */
    protected abstract JaxoGraph importGraph(InputStream inputStream)
        throws JaxoPluginExecutionException;

}
