/**
 *  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.awt.Dimension;
import java.awt.Graphics2D;

import javax.swing.JComponent;

import net.sf.jaxodraw.graph.JaxoGraph;
import net.sf.jaxodraw.gui.JaxoDialogs;
import net.sf.jaxodraw.io.JaxoPreview;
import net.sf.jaxodraw.util.JaxoLanguage;
import net.sf.jaxodraw.util.graphics.JaxoGraphics2D;

/** An abstract superclass for all export plugins.
 * @since 2.0
 */
public abstract class JaxoExportPlugin extends AbstractJaxoPlugin {
    private JaxoGraph graph;
    private Dimension canvasSize;

    /** Sets the graph to export. Makes a backup of the
     * original graph and breaks all groups.
     * @param newGraph The graph to export.
     */
    public final void setGraph(final JaxoGraph newGraph) {
        this.graph = newGraph.copyOf();
        graph.breakAllGroups();
    }

    /** Returns the current graph to export.
     * @return The graph to export.
     */
    public final JaxoGraph getGraph() {
        return graph;
    }

    /**
     * Set the canvas size. In general, the canvas size is not needed.
     * @param value The canvas size.
     * @deprecated this is not used, exports should not depend on the canvas size!
     */
    @Deprecated
    public void setCanvasSize(final Dimension value) {
        if (canvasSize == null) {
            canvasSize = new Dimension();
        }
        canvasSize.setSize(value);
    }

    /**
     * Returns the canvas size.
     * @return The canvas size, or null, if it hasn't been set.
     * @deprecated this is not used, exports should not depend on the canvas size!
     */
    @Deprecated
    protected Dimension getCanvasSize() {
        return canvasSize;
    }

    /**
     * Export the current graph to the given nonempty file name.
     * Checks if fileName is empty, if yes, does nothing.
     * @param fileName The file to export to.
     */
    public final void export(final String fileName) {
        setFailure(null);

        if (fileName.length() == 0) {
            return;
        }

        try {
            exportTo(fileName);
        } catch (JaxoPluginExecutionException e) {
            setFailure(e); // this logs in debug mode
            if (e.getMessage() != null) {
                showErrorDialog(e.getMessage());
            }
        }
    }

    /**
     * Export a graph to a file.
     * @param exportGraph The graph to export.
     * @param fileName Absolute path of the file to export to.
     */
    public void export(final JaxoGraph exportGraph, final String fileName) {
        setGraph(exportGraph);
        export(fileName);
    }

    /**
     * Show a preview in a new window.
     * @param p The JaxoPreview to use.
     */
    public void preview(final JaxoPreview p) {
        preview(p, false);
    }

    /**
     * Paint the graph.
     *
     * @param g2d the graphics context to paint to.
     * @param printing set to true to suppress any UI-elements or aids.
     */
    protected void paintGraph(final Graphics2D g2d, final boolean printing) {
        final JaxoGraphics2D g = new JaxoGraphics2D(g2d);
        g.setPrinting(printing);

        getGraph().paint(g);
    }

      //
     // Utility methods
    //

    /**
     * Show an error message window, unless silent.
     *
     * @param message The message to display.
     */
    protected void showErrorDialog(final String message) {
        if (!isSilent()) {
            JaxoDialogs.showErrorDialog(getParentComponent(), message,
                JaxoDialogs.windowTitle("JaxoExport.exportErrorTitle"));
        }
    }

    /**
     * Returns a default error message for exporting to 'fileName'.
     *
     * @param fileName The file name to insert in the message.
     * @return a default error message.
     */
    protected String errorDialogMessage(final String fileName) {
        return JaxoLanguage.message("JaxoExport.export%0Error", fileName);
    }

    /**
     * Returns an internationalized warning when
     * latex texts are present in the graph.
     * @return A translated warning.
     */
    public String getLaTeXTextWarning() {
        return JaxoLanguage.translate("JaxoExport.warning.LaTeXText");
    }

    /**
     * Returns an internationalized warning when postscript
     * texts are present in the graph.
     * @return A translated warning.
     */
    public String getPSTextWarning() {
        return JaxoLanguage.translate("JaxoExport.warning.PSText");
    }

    /**
     * Returns an internationalized warning when postscript
     * texts are present in the graph.
     * @return A translated warning.
     */
    public String getPSTextWarningForLaTeX() {
        return JaxoLanguage.translate("JaxoExport.warning.PSTextForLaTeX");
    }

    /**
     * Returns an internationalized warning when the color space
     * is the complete one.
     * @return A translated warning.
     */
    public String getColorSpaceWarningForLaTeX() {
        return JaxoLanguage.translate("JaxoExport.warning.ColorSpaceForLaTeX");
    }

      //
     // Abstract methods
    //

    /**
     * Export a graph to a file.
     * @param graph The graph to export.
     * @param fileName An absolute path to the file to export to.
     */
    //protected abstract void export(JaxoGraph graph, String fileName);

    /** Apply the changes made in the configuration panel. */
    public abstract void commitConfiguration();

    /** Returns a panel that allows to configure optional
     * parameters of this export format.
     * @return Null by default, no options to configure.
     */
    public abstract JComponent getConfigurationPanel();

    /**
     * Export the graph to the given nonempty file name.
     *
     * @param fileName The file to export to.
     * @throws JaxoPluginExecutionException if exporting fails.
     * The exception message sould be displayable in error dialogs,
     * so it should be an internationalized string.
     */
    protected abstract void exportTo(final String fileName)
        throws JaxoPluginExecutionException;

    /**
     * Show a preview.
     *
     * @param p The JaxoPreview to show.
     * @param sameWindow If false, a new window will be opened for the preview.
     * If true, and if a preview window for the current format is open already,
     * the same window will be used for the preview.
     * Not all implementations may support this feature.
     */
    public abstract void preview(final JaxoPreview p, final boolean sameWindow);

    /**
     * Returns a warning, eg if a part of the graph cannot be exported
     * to the current format.
     * @return An (internationalized) String, or null for no warning.
     */
    public abstract String getWarningForGraph();
}
