/**
 *  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.io.imports;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import net.sf.jaxodraw.graph.JaxoGraph;
import net.sf.jaxodraw.plugin.JaxoPluginExecutionException;
import net.sf.jaxodraw.util.JaxoDictionary;
import net.sf.jaxodraw.util.JaxoLog;


/** The class responsible for importing JaxoGraphs from axodraw files.
 * @since 2.0
 */
public final class JaxoImportAxodraw extends JaxoImport {
    private final JaxoDictionary language = new JaxoDictionary(JaxoImportAxodraw.class);
    /** The unique plugin id. */
    private static final String PLUGIN_ID = JaxoImportAxodraw.class.getName();

    private String fileDescription = language.value("fileDescription");
    private String description = language.value("description");

    /** {@inheritDoc} */
    public String getFormatName() {
        return "LaTeX (axodraw4j)";
    }

    /** {@inheritDoc} */
    public String getFileExtension() {
        return "tex";
    }

    /** {@inheritDoc} */
    public String getFileExtensionDescription() {
        return fileDescription;
    }

    /** {@inheritDoc} */
    public String getShortName() {
        return "axodraw-import";
    }

    /** {@inheritDoc} */
    public String pluginId() {
        return PLUGIN_ID;
    }

    /** {@inheritDoc} */
    public void updateLanguage() {
        fileDescription = language.value("fileDescription");
        description = language.value("description");
    }

    /** {@inheritDoc} */
    public JaxoGraph importGraph(final InputStream inputStream)
        throws JaxoPluginExecutionException {

        final JaxoGraph openedGraph = new JaxoGraph();

        final JaxoAxodraw4J axo = new JaxoAxodraw4J();

        BufferedReader in = null;
        final String charsetName = getCharsetName();

        if (charsetName == null) {
            in = new BufferedReader(new InputStreamReader(inputStream));
        } else {
            try {
                in = new BufferedReader(new InputStreamReader(inputStream, charsetName));
            } catch (UnsupportedEncodingException ex) {
                if (JaxoLog.isLoggable(JaxoLog.DEBUG)) {
                    JaxoLog.debug("Unsupported encoding: " + charsetName
                        + ", using system default.");
                }

                in = new BufferedReader(new InputStreamReader(inputStream));
            }
        }

        try {
            String str;

            boolean[] isValid = axo.getValid();

            // first run: check required commands and set bounding box
            while ((str = in.readLine()) != null) {
                str = str.trim();
                axo.checkRequired(str);
                isValid = axo.getValid();

                if (isValid[2]) {
                    break;
                }
            }

            openedGraph.setPackageList(axo.getPackages());

            isValid = axo.getValid();
            final boolean somethingMissing =
                !(isValid[0] && isValid[1] && isValid[2]);

            if (somethingMissing) {
                String missing = "";
                if (!isValid[0]) {
                    missing = "\\documentclass";
                } else if (!isValid[1]) {
                    missing = "\\begin{document}";
                } else if (!isValid[2]) {
                    missing = "\\begin{picture}";
                }

                final String msg = language.message(
                    "missingCommand%0", missing);
                throw new JaxoPluginExecutionException(msg, this);

            } else {
                // second run: read axodraw commands
                while ((str = in.readLine()) != null) {
                    openedGraph.addObject(axo.getJaxoObject(str.trim()));
                }
            }

            openedGraph.setDescription(axo.getComment());
        } catch (IOException e) {
            throw new JaxoPluginExecutionException(
                language.value("parsingFailed"),
                    e, in);
        } finally {
            close(in);
        }

        openedGraph.setSaved(false);

        return openedGraph;
    }

    /** {@inheritDoc} */
    public String description() {
        return description;
    }
}
