package de.renew.export.io.exportFormats;

import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Rectangle;
import java.io.File;

import org.apache.log4j.Logger;
import org.freehep.graphics2d.VectorGraphics;
import org.freehep.graphicsbase.util.UserProperties;
import org.freehep.graphicsio.AbstractVectorGraphicsIO;
import org.freehep.graphicsio.ps.AbstractPSGraphics2D;
import org.freehep.graphicsio.ps.EPSGraphics2D;

import CH.ifa.draw.util.ColorMap;
import de.renew.draw.storables.ontology.Drawing;
import de.renew.draw.storables.ontology.exporting.AbstractDrawingExportFormat;
import de.renew.io.api.FileApi;
import de.renew.ioontology.FileType;
import de.renew.plugin.PluginProperties;

/**
 * The EPSExportFormat class is a concrete implementation of an export format for
 * Encapsulated PostScript (EPS) files. It extends the ExportFormatAbstract class
 * and provides specific functionality and attributes for EPS file exports.
 * This class defines an EPSFileFilter to filter files with the EPS extension and
 * sets the export format name to "EPS".
 *
 * @link ExportFormatAbstract
 * @link EPSFileFilter
 */
public class EPSExportFormat extends AbstractDrawingExportFormat {

    /**
     * A logger for this class to log messages and events related to EPS file exports.
     */
    public static final Logger LOGGER = Logger.getLogger(EPSExportFormat.class);

    //Hotkey property names
    public static final String EPS_EXPORT_HOTKEY_PROP_NAME =
        "de.renew.hotkeymap.export.exportcurrentdrawingeps";

    private PluginProperties _plugincfg;

    /**
     * Constructs an EPSExportFormat object with the format name set to "EPS" and
     * an EPSFileFilter to filter EPS files during export.
     */
    public EPSExportFormat() {
        super("EPS", FileApi.createExtensionFileFilter(FileType.EPS));
    }

    /**
     * Constructs an EPSExportFormat object with the given format name and
     * an EPSFileFilter to filter EPS files during export.
     * @param formatName the given name for the format
     */
    public EPSExportFormat(String formatName) {
        super(formatName, FileApi.createExtensionFileFilter(FileType.EPS));
    }

    /**
     * Constructs an EPSExportFormat object with the format name set to "EPS" and
     * an EPSFileFilter to filter EPS files during export.
     * @param plugincfg the config for this Format, containing hotkeys
     */
    public EPSExportFormat(PluginProperties plugincfg) {
        super("EPS", FileApi.createExtensionFileFilter(FileType.EPS));
        this._plugincfg = plugincfg;
    }


    // Methods

    /**
     * @return boolean always returns false
     */
    @Override
    public boolean canExportNto1() {
        return false;
    }

    /**
     * Exports an array of drawings to an EPS (Encapsulated PostScript) file at the specified path.
     *
     * @param drawings An array of drawings to be exported.
     * @param path The file path where the EPS file will be saved.
     * @return The File object representing the exported EPS file.
     * @throws Exception If any error occurs during the export process.
     */
    @Override
    public File export(Drawing[] drawings, File path) throws Exception {
        File result = null;
        assert (result != null) : "Failure in EPSExportFormat: result == null";
        return result;
    }

    /**
     * Export drawing as eps image.
     * The full canvas is exported.
     *
     * @param drawing -- the drawing to be exported
     * @param file -- the file to contain the exported image
     */
    @Override
    public File export(Drawing drawing, File file) throws Exception {
        Rectangle bounds = drawing.getBounds();

        return internalExport(drawing, file, bounds, true);
    }

    /**
     * Exports the specified drawing to an EPS (Encapsulated PostScript) file at the given path.
     *
     * @param drawing The drawing to be exported.
     * @param path The file path where the EPS file will be saved.
     * @param bounds The rectangular bounds of the area to be exported within the drawing.
     * @param removeWhiteSpace Flag indicating whether to remove white space around the exported image.
     * @return The File object representing the exported EPS file.
     * @throws Exception If any error occurs during the export process.
     */
    public File internalExport(
        Drawing drawing, File path, Rectangle bounds, boolean removeWhiteSpace) throws Exception
    {
        File result = null;

        //JPanel drawingPanel = (JPanel) DrawPlugin.getGui().getView(drawing);
        //Rectangle r = drawing.displayBox();
        int x = bounds.x;
        int y = bounds.y;
        int width = bounds.width;
        int height = bounds.height;

        Dimension d = new Dimension(width, height);

        VectorGraphics graphics = new EPSGraphics2D(path, d);

        //Remove unnecessary margins and don't scale to international paper size
        final UserProperties defaultProperties = new UserProperties();
        defaultProperties.setProperty(EPSGraphics2D.PAGE_MARGINS, new Insets(00, 00, 00, 00));
        defaultProperties.setProperty(EPSGraphics2D.FIT_TO_PAGE, true);
        String fontHandling = ExportPlugin.EPS_FONT_HANDLING_SHAPES;
        ExportPlugin exportPlugin = ExportPlugin.getCurrent();
        if (exportPlugin != null) {
            fontHandling = exportPlugin.getEpsFontHandling();
        }
        if (ExportPlugin.EPS_FONT_HANDLING_EMBED.equals(fontHandling)) {
            defaultProperties.setProperty(AbstractPSGraphics2D.EMBED_FONTS, true);
            defaultProperties.setProperty(AbstractVectorGraphicsIO.TEXT_AS_SHAPES, false);
        } else if (ExportPlugin.EPS_FONT_HANDLING_NONE.equals(fontHandling)) {
            defaultProperties.setProperty(AbstractPSGraphics2D.EMBED_FONTS, false);
            defaultProperties.setProperty(AbstractVectorGraphicsIO.TEXT_AS_SHAPES, false);
        } else {
            if (!ExportPlugin.EPS_FONT_HANDLING_SHAPES.equals(fontHandling)) {
                LOGGER.warn("Unknown EPS font handling configured: " + fontHandling);
            }
            defaultProperties.setProperty(AbstractPSGraphics2D.EMBED_FONTS, false);
            defaultProperties.setProperty(AbstractVectorGraphicsIO.TEXT_AS_SHAPES, true);
        }
        //        if (exportPlugin != null) {
        //            defaultProperties.setProperty(AbstractPSGraphics2D.TRANSPARENT,
        //                                          exportPlugin.getEpsTransparency());
        //        } else {
        //            defaultProperties.setProperty(AbstractPSGraphics2D.TRANSPARENT, true);
        //        }
        defaultProperties.setProperty(AbstractPSGraphics2D.CLIP, true);
        defaultProperties
            .setProperty(AbstractPSGraphics2D.PAGE_SIZE, AbstractPSGraphics2D.CUSTOM_PAGE_SIZE);
        defaultProperties.setProperty(AbstractPSGraphics2D.CUSTOM_PAGE_SIZE, d);
        defaultProperties.setProperty(AbstractPSGraphics2D.BACKGROUND, false);
        defaultProperties.setProperty(AbstractPSGraphics2D.BACKGROUND_COLOR, ColorMap.NONE);
        graphics.setProperties(defaultProperties);

        //Start exporting image to eps
        graphics.startExport();

        if (removeWhiteSpace) {
            //Move to coordinates 0,0 
            graphics.translate(x * -1, y * -1);
        }
        //Set clipping to the region that was the original image
        //Otherwise we would export white regions around the image
        graphics.clipRect(x, y, width, height);
        //Paint the picture
        //drawingPanel.print(graphics);
        drawing.draw(graphics);
        //End exporting
        graphics.endExport();

        result = path;
        assert (result != null) : "Failure in EPSExportFormat: result == null";
        return result;
    }

    /**
     * Determines whether the given drawing can be exported using this export format.
     *
     * @param drawing The drawing to be checked for exportability.
     * @return {@code true} if the drawing can be exported, {@code false} otherwise.
     */
    @Override
    public boolean canExportDrawing(Drawing drawing) {
        boolean result = false;
        result = true;
        return result;
    }

    /**
     * Returns the keyboard shortcut associated with triggering the export action for this export format.
     *
     * @return The integer value representing the keyboard shortcut, using constants from the KeyEvent class.
     */
    @Override
    public int getShortCut() {
        if (_plugincfg != null) {
            return PluginProperties.getUserProperties()
                .getHotkeyProperty(
                    EPS_EXPORT_HOTKEY_PROP_NAME,
                    _plugincfg.getHotkeyProperty(EPS_EXPORT_HOTKEY_PROP_NAME))
                .getKeyCode();
        }
        return PluginProperties.getUserProperties().getHotkeyProperty(EPS_EXPORT_HOTKEY_PROP_NAME)
            .getKeyCode();
    }

    @Override
    public int getModifier() {
        if (_plugincfg != null) {
            return PluginProperties.getUserProperties()
                .getHotkeyProperty(
                    EPS_EXPORT_HOTKEY_PROP_NAME,
                    _plugincfg.getHotkeyProperty(EPS_EXPORT_HOTKEY_PROP_NAME))
                .getModifiers();
        }
        return PluginProperties.getUserProperties().getHotkeyProperty(EPS_EXPORT_HOTKEY_PROP_NAME)
            .getModifiers();

    }
}
