/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.cli;

// java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;

import javax.swing.UIManager;

import org.xml.sax.SAXException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.Version;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFEncryptionManager;
import org.apache.fop.pdf.PDFEncryptionParams;
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.awt.AWTRenderer;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFSerializer;
import org.apache.fop.render.pdf.PDFRenderer;
import org.apache.fop.render.print.PagesMode;
import org.apache.fop.render.print.PrintRenderer;
import org.apache.fop.render.xml.XMLRenderer;
import org.apache.fop.util.CommandLineLogger;

/**
 * Options parses the commandline arguments
 */
public class CommandLineOptions {

    /** Used to indicate that only the result of the XSL transformation should be output */
    public static final int RENDER_NONE = -1;

    /* These following constants are used to describe the input (either .FO, .XML/.XSL or
     * intermediate format)
     */

    /** (input) not set */
    public static final int NOT_SET = 0;
    /** input: fo file */
    public static final int FO_INPUT = 1;
    /** input: xml+xsl file */
    public static final int XSLT_INPUT = 2;
    /** input: Area Tree XML file */
    public static final int AREATREE_INPUT = 3;
    /** input: Intermediate Format XML file */
    public static final int IF_INPUT = 4;
    /** input: Image file */
    public static final int IMAGE_INPUT = 5;

    /* show configuration information */
    private Boolean showConfiguration = Boolean.FALSE;
    /* for area tree XML output, only down to block area level */
    private Boolean suppressLowLevelAreas = Boolean.FALSE;
    /* user configuration file */
    private File userConfigFile = null;
    /* input fo file */
    private File fofile = null;
    /* xsltfile (xslt transformation as input) */
    private File xsltfile = null;
    /* xml file (xslt transformation as input) */
    private File xmlfile = null;
    /* area tree input file */
    private File areatreefile = null;
    /* intermediate format input file */
    private File iffile = null;
    /* area tree input file */
    private File imagefile = null;
    /* output file */
    private File outfile = null;
    /* input mode */
    private int inputmode = NOT_SET;
    /* output mode */
    private String outputmode = null;
    /* true if System.in (stdin) should be used for the input file */
    private boolean useStdIn = false;
    /* true if System.out (stdout) should be used for the output file */
    private boolean useStdOut = false;
    /* true if a catalog resolver should be used for entity and uri resolution */ 
    private boolean useCatalogResolver = false;
    /* rendering options (for the user agent) */
    private Map renderingOptions = new java.util.HashMap();
    /* target resolution (for the user agent) */
    private int targetResolution = 0;
    /* control memory-conservation policy */
    private boolean conserveMemoryPolicy = false;

    private FopFactory factory = FopFactory.newInstance();
    private FOUserAgent foUserAgent;

    private InputHandler inputHandler;

    private Log log;

    private Vector xsltParams = null;

    private String mimicRenderer = null;

    /**
     * Construct a command line option object.
     */
    public CommandLineOptions() {
        LogFactory logFactory = LogFactory.getFactory();

        // Enable the simple command line logging when no other logger is
        // defined.
        if (System.getProperty("org.apache.commons.logging.Log") == null) {
            logFactory.setAttribute("org.apache.commons.logging.Log",
                                            CommandLineLogger.class.getName());
            setLogLevel("info");
        }

        log = LogFactory.getLog("FOP");
    }

    /**
     * Parses the command line arguments.
     *
     * @param args the command line arguments.
     * @throws FOPException for general errors
     * @throws IOException if the the configuration file could not be loaded
     * @return true if the processing can continue, false to abort
     */
    public boolean parse(String[] args)
            throws FOPException, IOException {
        boolean optionsParsed = true;

        try {
            optionsParsed = parseOptions(args);
            if (optionsParsed) {
                if (showConfiguration == Boolean.TRUE) {
                    dumpConfiguration();
                }
                checkSettings();
                setUserConfig();

                //Factory config is set up, now we can create the user agent
                foUserAgent = factory.newFOUserAgent();
                foUserAgent.getRendererOptions().putAll(renderingOptions);
                if (targetResolution != 0) {
                    foUserAgent.setTargetResolution(targetResolution);
                }
                addXSLTParameter("fop-output-format", getOutputFormat());
                addXSLTParameter("fop-version", Version.getVersion());
                foUserAgent.setConserveMemoryPolicy(conserveMemoryPolicy);
            } else {
                return false;
            }
        } catch (FOPException e) {
            printUsage(System.err);
            throw e;
        } catch (java.io.FileNotFoundException e) {
            printUsage(System.err);
            throw e;
        }

        inputHandler = createInputHandler();

        if (MimeConstants.MIME_FOP_AWT_PREVIEW.equals(outputmode)) {
            //set the system look&feel for the preview dialog
            try {
                UIManager.setLookAndFeel(
                    UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                System.err.println("Couldn't set system look & feel!");
            }

            AWTRenderer renderer = new AWTRenderer(true);
            renderer.setRenderable(inputHandler); //set before user agent!
            renderer.setUserAgent(foUserAgent);
            foUserAgent.setRendererOverride(renderer);
        } else if (MimeConstants.MIME_FOP_AREA_TREE.equals(outputmode)
               && mimicRenderer != null) {
            // render from FO to Intermediate Format
            Renderer targetRenderer = foUserAgent.getRendererFactory().createRenderer(
                   foUserAgent, mimicRenderer);
            XMLRenderer xmlRenderer = new XMLRenderer();
            xmlRenderer.setUserAgent(foUserAgent);

            //Tell the XMLRenderer to mimic the target renderer
            xmlRenderer.mimicRenderer(targetRenderer);

            //Make sure the prepared XMLRenderer is used
            foUserAgent.setRendererOverride(xmlRenderer);
        } else if (MimeConstants.MIME_FOP_IF.equals(outputmode)
                && mimicRenderer != null) {
            // render from FO to Intermediate Format
            IFSerializer serializer = new IFSerializer();
            serializer.setContext(new IFContext(foUserAgent));

            IFDocumentHandler targetHandler
                = foUserAgent.getRendererFactory().createDocumentHandler(
                        foUserAgent, mimicRenderer);
            serializer.mimicDocumentHandler(targetHandler);

            //Make sure the prepared serializer is used
            foUserAgent.setDocumentHandlerOverride(serializer);
        }
        return true;
    }

    /**
     * @return the InputHandler instance defined by the command-line options.
     */
    public InputHandler getInputHandler() {
        return inputHandler;
    }

    /**
     * Get the logger.
     * @return the logger
     */
    public Log getLogger() {
        return log;
    }

    private void addXSLTParameter(String name, String value) {
        if (xsltParams == null) {
            xsltParams = new Vector();
        }
        xsltParams.addElement(name);
        xsltParams.addElement(value);
    }

    /**
     * Parses the command line arguments.
     *
     * @return true if processing can continue, false if it should stop (nothing to do)
     * @exception FOPException if there was an error in the format of the options
     */
    private boolean parseOptions(String[] args) throws FOPException {
        // do not throw an exception for no args
        if (args.length == 0) {
            printVersion();
            printUsage(System.out);
            return false;
        }
        for (int i = 0; i < args.length; i++) {
            if (args[i].equals("-x")
                       || args[i].equals("--dump-config")) {
                showConfiguration = Boolean.TRUE;
            } else if (args[i].equals("-c")) {
                i = i + parseConfigurationOption(args, i);
            } else if (args[i].equals("-l")) {
                i = i + parseLanguageOption(args, i);
            } else if (args[i].equals("-s")) {
                suppressLowLevelAreas = Boolean.TRUE;
            } else if (args[i].equals("-d")) {
                setLogOption("debug", "debug");
            } else if (args[i].equals("-r")) {
                factory.setStrictValidation(false);
            } else if (args[i].equals("-conserve")) {
                conserveMemoryPolicy = true;
            } else if (args[i].equals("-dpi")) {
                i = i + parseResolution(args, i);
            } else if (args[i].equals("-q") || args[i].equals("--quiet")) {
                setLogOption("quiet", "error");
            } else if (args[i].equals("-fo")) {
                i = i + parseFOInputOption(args, i);
            } else if (args[i].equals("-xsl")) {
                i = i + parseXSLInputOption(args, i);
            } else if (args[i].equals("-xml")) {
                i = i + parseXMLInputOption(args, i);
            } else if (args[i].equals("-atin")) {
                i = i + parseAreaTreeInputOption(args, i);
            } else if (args[i].equals("-ifin")) {
                i = i + parseIFInputOption(args, i);
            } else if (args[i].equals("-imagein")) {
                i = i + parseImageInputOption(args, i);
            } else if (args[i].equals("-awt")) {
                i = i + parseAWTOutputOption(args, i);
            } else if (args[i].equals("-pdf")) {
                i = i + parsePDFOutputOption(args, i, null);
            } else if (args[i].equals("-pdfa1b")) {
                i = i + parsePDFOutputOption(args, i, "PDF/A-1b");
            } else if (args[i].equals("-mif")) {
                i = i + parseMIFOutputOption(args, i);
            } else if (args[i].equals("-rtf")) {
                i = i + parseRTFOutputOption(args, i);
            } else if (args[i].equals("-tiff")) {
                i = i + parseTIFFOutputOption(args, i);
            } else if (args[i].equals("-png")) {
                i = i + parsePNGOutputOption(args, i);
            } else if (args[i].equals("-print")) {
                // show print help
                if (i + 1 < args.length) {
                    if (args[i + 1].equals("help")) {
                        printUsagePrintOutput();
                        return false;
                    }
                }
                i = i + parsePrintOutputOption(args, i);
            } else if (args[i].equals("-copies")) {
                i = i + parseCopiesOption(args, i);
            } else if (args[i].equals("-pcl")) {
                i = i + parsePCLOutputOption(args, i);
            } else if (args[i].equals("-ps")) {
                i = i + parsePostscriptOutputOption(args, i);
            } else if (args[i].equals("-txt")) {
                i = i + parseTextOutputOption(args, i);
            } else if (args[i].equals("-svg")) {
                i = i + parseSVGOutputOption(args, i);
            } else if (args[i].equals("-afp")) {
                i = i + parseAFPOutputOption(args, i);
            } else if (args[i].equals("-foout")) {
                i = i + parseFOOutputOption(args, i);
            } else if (args[i].equals("-out")) {
                i = i + parseCustomOutputOption(args, i);
            } else if (args[i].equals("-at")) {
                i = i + parseAreaTreeOption(args, i);
            } else if (args[i].equals("-if")) {
                i = i + parseIntermediateFormatOption(args, i);
            } else if (args[i].equals("-v")) {
                /* Currently just print the version */
                printVersion();
            } else if (args[i].equals("-param")) {
                  if (i + 2 < args.length) {
                      String name = args[++i];
                      String expression = args[++i];
                      addXSLTParameter(name, expression);
                  } else {
                      throw new FOPException("invalid param usage: use -param <name> <value>");
                  }
            } else if (args[i].equals("-catalog")) {
                useCatalogResolver = true;
            } else if (args[i].equals("-o")) {
                i = i + parsePDFOwnerPassword(args, i);
            } else if (args[i].equals("-u")) {
                i = i + parsePDFUserPassword(args, i);
            } else if (args[i].equals("-pdfprofile")) {
                i = i + parsePDFProfile(args, i);
            } else if (args[i].equals("-noprint")) {
                getPDFEncryptionParams().setAllowPrint(false);
            } else if (args[i].equals("-nocopy")) {
                getPDFEncryptionParams().setAllowCopyContent(false);
            } else if (args[i].equals("-noedit")) {
                getPDFEncryptionParams().setAllowEditContent(false);
            } else if (args[i].equals("-noannotations")) {
                getPDFEncryptionParams().setAllowEditAnnotations(false);
            } else if (args[i].equals("-version")) {
                printVersion();
                return false;
            } else if (!isOption(args[i])) {
                i = i + parseUnknownOption(args, i);
            } else {
                printUsage(System.err);
                System.exit(1);
            }
        }
        return true;
    }    // end parseOptions

    private int parseConfigurationOption(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("if you use '-c', you must specify "
              + "the name of the configuration file");
        } else {
            userConfigFile = new File(args[i + 1]);
            return 1;
        }
    }

    private int parseLanguageOption(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("if you use '-l', you must specify a language");
        } else {
            Locale.setDefault(new Locale(args[i + 1], ""));
            return 1;
        }
    }

    private int parseResolution(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException(
                    "if you use '-dpi', you must specify a resolution (dots per inch)");
        } else {
            this.targetResolution = Integer.parseInt(args[i + 1]);
            return 1;
        }
    }

    private int parseFOInputOption(String[] args, int i) throws FOPException {
        setInputFormat(FO_INPUT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the fo file for the '-fo' option");
        } else {
            String filename = args[i + 1];
            if (isSystemInOutFile(filename)) {
                this.useStdIn = true;
            } else {
                fofile = new File(filename);
            }
            return 1;
        }
    }

    private int parseXSLInputOption(String[] args, int i) throws FOPException {
        setInputFormat(XSLT_INPUT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the stylesheet "
                            + "file for the '-xsl' option");
        } else {
            xsltfile = new File(args[i + 1]);
            return 1;
        }
    }

    private int parseXMLInputOption(String[] args, int i) throws FOPException {
        setInputFormat(XSLT_INPUT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the input file "
                            + "for the '-xml' option");
        } else {
            String filename = args[i + 1];
            if (isSystemInOutFile(filename)) {
                this.useStdIn = true;
            } else {
                xmlfile = new File(filename);
            }
            return 1;
        }
    }

    private int parseAWTOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_FOP_AWT_PREVIEW);
        return 0;
    }

    private int parsePDFOutputOption(String[] args, int i, String pdfAMode) throws FOPException {
        setOutputMode(MimeConstants.MIME_PDF);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the PDF output file");
        } else {
            setOutputFile(args[i + 1]);
            if (pdfAMode != null) {
                if (renderingOptions.get("pdf-a-mode") != null) {
                    throw new FOPException("PDF/A mode already set");
                }
                renderingOptions.put("pdf-a-mode", pdfAMode);
            }
            return 1;
        }
    }

    private void setOutputFile(String filename) {
        if (isSystemInOutFile(filename)) {
            this.useStdOut = true;
        } else {
            outfile = new File(filename);
        }
    }

    /**
     * Checks whether the given argument is the next option or the specification of
     * stdin/stdout.
     *
     * TODO this is very ad-hoc and should be better handled. Consider the adoption of
     * Apache Commons CLI.
     *
     * @param arg an argument
     * @return true if the argument is an option ("-something"), false otherwise
     */
    private boolean isOption(String arg) {
        return arg.length() > 1 && arg.startsWith("-");
    }

    private boolean isSystemInOutFile(String filename) {
        return "-".equals(filename);
    }

    private int parseMIFOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_MIF);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the MIF output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseRTFOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_RTF);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the RTF output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseTIFFOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_TIFF);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the TIFF output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parsePNGOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_PNG);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the PNG output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parsePrintOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_FOP_PRINT);
        if ((i + 1 <= args.length)
                && (args[i + 1].charAt(0) != '-')) {
            String arg = args[i + 1];
            String[] parts = arg.split(",");
            for (int j = 0; j < parts.length; j++) {
                String s = parts[j];
                if (s.matches("\\d+")) {
                    renderingOptions.put(PrintRenderer.START_PAGE, new Integer(s));
                } else if (s.matches("\\d+-\\d+")) {
                    String[] startend = s.split("-");
                    renderingOptions.put(PrintRenderer.START_PAGE, new Integer(startend[0]));
                    renderingOptions.put(PrintRenderer.END_PAGE, new Integer(startend[1]));
                } else {
                    PagesMode mode = PagesMode.byName(s);
                    renderingOptions.put(PrintRenderer.PAGES_MODE, mode);
                }
            }
            return 1;
        } else {
            return 0;
        }
    }

    private int parseCopiesOption(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the number of copies");
        } else {
            renderingOptions.put(PrintRenderer.COPIES, new Integer(args[i + 1]));
            return 1;
        }
    }

    private int parsePCLOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_PCL);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the PDF output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parsePostscriptOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_POSTSCRIPT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the PostScript output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseTextOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_PLAIN_TEXT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the text output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseSVGOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_SVG);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the SVG output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseAFPOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_AFP);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the AFP output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseFOOutputOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_XSL_FO);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the FO output file");
        } else {
            setOutputFile(args[i + 1]);
            return 1;
        }
    }

    private int parseCustomOutputOption(String[] args, int i) throws FOPException {
        String mime = null;
        if ((i + 1 < args.length)
                || (args[i + 1].charAt(0) != '-')) {
            mime = args[i + 1];
            if ("list".equals(mime)) {
                String[] mimes = factory.getRendererFactory().listSupportedMimeTypes();
                System.out.println("Supported MIME types:");
                for (int j = 0; j < mimes.length; j++) {
                    System.out.println("  " + mimes[j]);
                }
                System.exit(0);
            }
        }
        if ((i + 2 >= args.length)
                || (isOption(args[i + 1]))
                || (isOption(args[i + 2]))) {
            throw new FOPException("you must specify the output format and the output file");
        } else {
            setOutputMode(mime);
            setOutputFile(args[i + 2]);
            return 2;
        }
    }

    private int parseUnknownOption(String[] args, int i) throws FOPException {
        if (inputmode == NOT_SET) {
            inputmode = FO_INPUT;
            String filename = args[i];
            if (isSystemInOutFile(filename)) {
                this.useStdIn = true;
            } else {
                fofile = new File(filename);
            }
        } else if (outputmode == null) {
            outputmode = MimeConstants.MIME_PDF;
            setOutputFile(args[i]);
        } else {
            throw new FOPException("Don't know what to do with "
                           + args[i]);
        }
        return 0;
    }

    private int parseAreaTreeOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_FOP_AREA_TREE);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the area-tree output file");
        } else if ((i + 2 == args.length)
                || (isOption(args[i + 2]))) {
            // only output file is specified
            setOutputFile(args[i + 1]);
            return 1;
        } else {
            // mimic format and output file have been specified
            mimicRenderer = args[i + 1];
            setOutputFile(args[i + 2]);
            return 2;
        }
    }

    private int parseIntermediateFormatOption(String[] args, int i) throws FOPException {
        setOutputMode(MimeConstants.MIME_FOP_IF);
        if ((i + 1 == args.length)
                || (args[i + 1].charAt(0) == '-')) {
            throw new FOPException("you must specify the intermediate format output file");
        } else if ((i + 2 == args.length)
                || (args[i + 2].charAt(0) == '-')) {
            // only output file is specified
            setOutputFile(args[i + 1]);
            return 1;
        } else {
            // mimic format and output file have been specified
            mimicRenderer = args[i + 1];
            setOutputFile(args[i + 2]);
            return 2;
        }
    }

    private int parseAreaTreeInputOption(String[] args, int i) throws FOPException {
        setInputFormat(AREATREE_INPUT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the Area Tree file for the '-atin' option");
        } else {
            String filename = args[i + 1];
            if (isSystemInOutFile(filename)) {
                this.useStdIn = true;
            } else {
                areatreefile = new File(filename);
            }
            return 1;
        }
    }

    private int parseIFInputOption(String[] args, int i) throws FOPException {
        setInputFormat(IF_INPUT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the intermediate file for the '-ifin' option");
        } else {
            String filename = args[i + 1];
            if (isSystemInOutFile(filename)) {
                this.useStdIn = true;
            } else {
                iffile = new File(filename);
            }
            return 1;
        }
    }

    private int parseImageInputOption(String[] args, int i) throws FOPException {
        setInputFormat(IMAGE_INPUT);
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("you must specify the image file for the '-imagein' option");
        } else {
            String filename = args[i + 1];
            if (isSystemInOutFile(filename)) {
                this.useStdIn = true;
            } else {
                imagefile = new File(filename);
            }
            return 1;
        }
    }

    private PDFEncryptionParams getPDFEncryptionParams() throws FOPException {
        PDFEncryptionParams params = (PDFEncryptionParams)renderingOptions.get(
                        PDFRenderer.ENCRYPTION_PARAMS);
        if (params == null) {
            if (!PDFEncryptionManager.checkAvailableAlgorithms()) {
                throw new FOPException("PDF encryption requested but it is not available."
                        + " Please make sure MD5 and RC4 algorithms are available.");
            }
            params = new PDFEncryptionParams();
            renderingOptions.put(PDFRenderer.ENCRYPTION_PARAMS, params);
        }
        return params;
    }

    private int parsePDFOwnerPassword(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            getPDFEncryptionParams().setOwnerPassword("");
            return 0;
        } else {
            getPDFEncryptionParams().setOwnerPassword(args[i + 1]);
            return 1;
        }
    }

    private int parsePDFUserPassword(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            getPDFEncryptionParams().setUserPassword("");
            return 0;
        } else {
            getPDFEncryptionParams().setUserPassword(args[i + 1]);
            return 1;
        }
    }

    private int parsePDFProfile(String[] args, int i) throws FOPException {
        if ((i + 1 == args.length)
                || (isOption(args[i + 1]))) {
            throw new FOPException("You must specify a PDF profile");
        } else {
            String profile = args[i + 1];
            PDFAMode pdfAMode = PDFAMode.valueOf(profile);
            if (pdfAMode != null && pdfAMode != PDFAMode.DISABLED) {
                if (renderingOptions.get("pdf-a-mode") != null) {
                    throw new FOPException("PDF/A mode already set");
                }
                renderingOptions.put("pdf-a-mode", pdfAMode.getName());
                return 1;
            } else {
                PDFXMode pdfXMode = PDFXMode.valueOf(profile);
                if (pdfXMode != null && pdfXMode != PDFXMode.DISABLED) {
                    if (renderingOptions.get("pdf-x-mode") != null) {
                        throw new FOPException("PDF/X mode already set");
                    }
                    renderingOptions.put("pdf-x-mode", pdfXMode.getName());
                    return 1;
                }
            }
            throw new FOPException("Unsupported PDF profile: " + profile);
        }
    }

    private void setOutputMode(String mime) throws FOPException {
        if (outputmode == null) {
            outputmode = mime;
        } else {
            throw new FOPException("you can only set one output method");
        }
    }

    private void setLogOption (String option, String level) {
        if (log instanceof CommandLineLogger
            || System.getProperty("org.apache.commons.logging.Log") == null) {
            setLogLevel(level);
        } else if (log != null) {
            log.warn("The option " + option + " can only be used");
            log.warn("with FOP's command line logger,");
            log.warn("which is the default on the command line.");
            log.warn("Configure other loggers using Java system properties.");
        }
    }

    private void setLogLevel(String level) {
        // Set the level for future loggers.
        LogFactory.getFactory().setAttribute("level", level);
        if (log instanceof CommandLineLogger) {
            // Set the level for the logger created already.
            ((CommandLineLogger) log).setLogLevel(level);
        }
    }

    private void setInputFormat(int format) throws FOPException {
        if (inputmode == NOT_SET || inputmode == format) {
            inputmode = format;
        } else {
            throw new FOPException("Only one input mode can be specified!");
        }
    }

    /**
     * checks whether all necessary information has been given in a consistent way
     */
    private void checkSettings() throws FOPException, FileNotFoundException {
        if (inputmode == NOT_SET) {
            throw new FOPException("No input file specified");
        }

        if (outputmode == null) {
            throw new FOPException("No output file specified");
        }

        if ((outputmode.equals(MimeConstants.MIME_FOP_AWT_PREVIEW)
                || outputmode.equals(MimeConstants.MIME_FOP_PRINT))
                    && outfile != null) {
            throw new FOPException("Output file may not be specified "
                    + "for AWT or PRINT output");
        }

        if (inputmode == XSLT_INPUT) {
            // check whether xml *and* xslt file have been set
            if (xmlfile == null && !this.useStdIn) {
                throw new FOPException("XML file must be specified for the transform mode");
            }
            if (xsltfile == null) {
                throw new FOPException("XSLT file must be specified for the transform mode");
            }

            // warning if fofile has been set in xslt mode
            if (fofile != null) {
                log.warn("Can't use fo file with transform mode! Ignoring.\n"
                                       + "Your input is " + "\n xmlfile: "
                                       + xmlfile.getAbsolutePath()
                                       + "\nxsltfile: "
                                       + xsltfile.getAbsolutePath()
                                       + "\n  fofile: "
                                       + fofile.getAbsolutePath());
            }
            if (xmlfile != null && !xmlfile.exists()) {
                throw new FileNotFoundException("Error: xml file "
                                                + xmlfile.getAbsolutePath()
                                                + " not found ");
            }
            if (!xsltfile.exists()) {
                throw new FileNotFoundException("Error: xsl file "
                                                + xsltfile.getAbsolutePath()
                                                + " not found ");
            }

        } else if (inputmode == FO_INPUT) {
            if (outputmode.equals(MimeConstants.MIME_XSL_FO)) {
                throw new FOPException(
                        "FO output mode is only available if you use -xml and -xsl");
            }
            if (fofile != null && !fofile.exists()) {
                throw new FileNotFoundException("Error: fo file "
                                                + fofile.getAbsolutePath()
                                                + " not found ");
            }
        } else if (inputmode == AREATREE_INPUT) {
            if (outputmode.equals(MimeConstants.MIME_XSL_FO)) {
                throw new FOPException(
                        "FO output mode is only available if you use -xml and -xsl");
            } else if (outputmode.equals(MimeConstants.MIME_FOP_AREA_TREE)) {
                throw new FOPException(
                        "Area Tree Output is not available if Area Tree is used as input!");
            }
            if (areatreefile != null && !areatreefile.exists()) {
                throw new FileNotFoundException("Error: area tree file "
                                              + areatreefile.getAbsolutePath()
                                              + " not found ");
            }
        } else if (inputmode == IF_INPUT) {
            if (outputmode.equals(MimeConstants.MIME_XSL_FO)) {
                throw new FOPException(
                        "FO output mode is only available if you use -xml and -xsl");
            } else if (outputmode.equals(MimeConstants.MIME_FOP_AREA_TREE)) {
                throw new FOPException(
                    "Area Tree Output is not available if Intermediate Format is used as input!");
            } else if (outputmode.equals(MimeConstants.MIME_FOP_IF)) {
                throw new FOPException(
                    "Intermediate Output is not available if Intermediate Format is used as input!");
            }
            if (iffile != null && !iffile.exists()) {
                throw new FileNotFoundException("Error: intermediate format file "
                                              + iffile.getAbsolutePath()
                                              + " not found ");
            }
        } else if (inputmode == IMAGE_INPUT) {
            if (outputmode.equals(MimeConstants.MIME_XSL_FO)) {
                throw new FOPException(
                        "FO output mode is only available if you use -xml and -xsl");
            }
            if (imagefile != null && !imagefile.exists()) {
                throw new FileNotFoundException("Error: image file "
                                              + imagefile.getAbsolutePath()
                                              + " not found ");
            }
        }
    }    // end checkSettings

    /**
     * Sets the user configuration.
     * @throws FOPException if creating the user configuration fails
     * @throws IOException
     */
    private void setUserConfig() throws FOPException, IOException {
        if (userConfigFile == null) {
            return;
        }
        try {
            factory.setUserConfig(userConfigFile);
        } catch (SAXException e) {
            throw new FOPException(e);
        }
     }

    /**
     * @return the chosen output format (MIME type)
     * @throws FOPException for invalid output formats
     */
    protected String getOutputFormat() throws FOPException {
        if (outputmode == null) {
            throw new FOPException("Renderer has not been set!");
        }
        if (outputmode.equals(MimeConstants.MIME_FOP_AREA_TREE)) {
            renderingOptions.put("fineDetail", isCoarseAreaXml());
        }
        return outputmode;
    }

    /**
     * Create an InputHandler object based on command-line parameters
     * @return a new InputHandler instance
     * @throws IllegalArgumentException if invalid/missing parameters
     */
    private InputHandler createInputHandler() {
        switch (inputmode) {
            case FO_INPUT:
                return new InputHandler(fofile);
            case AREATREE_INPUT:
                return new AreaTreeInputHandler(areatreefile);
            case IF_INPUT:
                return new IFInputHandler(iffile);
            case XSLT_INPUT:
                InputHandler handler = new InputHandler(xmlfile, xsltfile, xsltParams);
                if (useCatalogResolver) {
                    handler.createCatalogResolver(foUserAgent);
                }
                return handler;
            case IMAGE_INPUT:
                return new ImageInputHandler(imagefile, xsltfile, xsltParams);
            default:
                throw new IllegalArgumentException("Error creating InputHandler object.");
        }
    }

    /**
     * Get the FOUserAgent for this Command-Line run
     * @return FOUserAgent instance
     */
    protected FOUserAgent getFOUserAgent() {
        return foUserAgent;
    }

    /**
     * Returns the XSL-FO file if set.
     * @return the XSL-FO file, null if not set
     */
    public File getFOFile() {
        return fofile;
    }

    /**
     * Returns the input XML file if set.
     * @return the input XML file, null if not set
     */
    public File getXMLFile() {
        return xmlfile;
    }

    /**
     * Returns the stylesheet to be used for transformation to XSL-FO.
     * @return stylesheet
     */
    public File getXSLFile() {
        return xsltfile;
    }

    /**
     * Returns the output file
     * @return the output file
     */
    public File getOutputFile() {
        return outfile;
    }

    /**
     * Returns the user configuration file to be used.
     * @return the userconfig.xml file
     */
    public File getUserConfigFile() {
        return userConfigFile;
    }

    /**
     * Indicates whether the XML renderer should generate coarse area XML
     * @return true if coarse area XML is desired
     */
    public Boolean isCoarseAreaXml() {
        return suppressLowLevelAreas;
    }

    /**
     * Indicates whether input comes from standard input (stdin).
     * @return true if input comes from standard input (stdin)
     */
    public boolean isInputFromStdIn() {
        return this.useStdIn;
    }

    /**
     * Indicates whether output is sent to standard output (stdout).
     * @return true if output is sent to standard output (stdout)
     */
    public boolean isOutputToStdOut() {
        return this.useStdOut;
    }

    /**
     * Returns the input file.
     * @return either the fofile or the xmlfile
     */
    public File getInputFile() {
        switch (inputmode) {
        case FO_INPUT:
            return fofile;
        case XSLT_INPUT:
            return xmlfile;
        default:
            return fofile;
        }
    }

    private static void printVersion() {
        System.out.println("FOP Version " + Version.getVersion());
    }

    /**
     * Shows the command line syntax including a summary of all available options and some
     * examples.
     *
     * @param out the stream to which the message must be printed
     */
    public static void printUsage(PrintStream out) {
        out.println(
              "\nUSAGE\nfop [options] [-fo|-xml] infile [-xsl file] "
                    + "[-awt|-pdf|-mif|-rtf|-tiff|-png|-pcl|-ps|-txt|-at [mime]|-print] <outfile>\n"
            + " [OPTIONS]  \n"
            + "  -version          print FOP version and exit\n"
            + "  -d                debug mode   \n"
            + "  -x                dump configuration settings  \n"
            + "  -q                quiet mode  \n"
            + "  -c cfg.xml        use additional configuration file cfg.xml\n"
            + "  -l lang           the language to use for user information \n"
            + "  -r                relaxed/less strict validation (where available)\n"
            + "  -dpi xxx          target resolution in dots per inch (dpi) where xxx is a number\n"
            + "  -s                for area tree XML, down to block areas only\n"
            + "  -v                run in verbose mode (currently simply print FOP version and continue)\n\n"
            + "  -o [password]     PDF file will be encrypted with option owner password\n"
            + "  -u [password]     PDF file will be encrypted with option user password\n"
            + "  -noprint          PDF file will be encrypted without printing permission\n"
            + "  -nocopy           PDF file will be encrypted without copy content permission\n"
            + "  -noedit           PDF file will be encrypted without edit content permission\n"
            + "  -noannotations    PDF file will be encrypted without edit annotation permission\n"
            + "  -pdfprofile prof  PDF file will be generated with the specified profile\n"
            + "                    (Examples for prof: PDF/A-1b or PDF/X-3:2003)\n\n"
            + "  -conserve         Enable memory-conservation policy (trades memory-consumption for disk I/O)\n"
            + "                    (Note: currently only influences whether the area tree is serialized.)\n\n"
            + " [INPUT]  \n"
            + "  infile            xsl:fo input file (the same as the next) \n"
            + "                    (use '-' for infile to pipe input from stdin)\n"
            + "  -fo  infile       xsl:fo input file  \n"
            + "  -xml infile       xml input file, must be used together with -xsl \n"
            + "  -atin infile      area tree input file \n"
            + "  -ifin infile      intermediate format input file \n"
            + "  -imagein infile   image input file (piping through stdin not supported)\n"
            + "  -xsl stylesheet   xslt stylesheet \n \n"
            + "  -param name value <value> to use for parameter <name> in xslt stylesheet\n"
            + "                    (repeat '-param name value' for each parameter)\n \n"
            + "  -catalog          use catalog resolver for input XML and XSLT files\n"
            + " [OUTPUT] \n"
            + "  outfile           input will be rendered as PDF into outfile\n"
            + "                    (use '-' for outfile to pipe output to stdout)\n"
            + "  -pdf outfile      input will be rendered as PDF (outfile req'd)\n"
            + "  -pdfa1b outfile   input will be rendered as PDF/A-1b compliant PDF\n"
            + "                    (outfile req'd, same as \"-pdf outfile -pdfprofile PDF/A-1b\")\n"
            + "  -awt              input will be displayed on screen \n"
            + "  -rtf outfile      input will be rendered as RTF (outfile req'd)\n"
            + "  -pcl outfile      input will be rendered as PCL (outfile req'd) \n"
            + "  -ps outfile       input will be rendered as PostScript (outfile req'd) \n"
            + "  -afp outfile      input will be rendered as AFP (outfile req'd)\n"
            + "  -tiff outfile     input will be rendered as TIFF (outfile req'd)\n"
            + "  -png outfile      input will be rendered as PNG (outfile req'd)\n"
            + "  -txt outfile      input will be rendered as plain text (outfile req'd) \n"
            + "  -at [mime] out    representation of area tree as XML (outfile req'd) \n"
            + "                    specify optional mime output to allow the AT to be converted\n"
            + "                    to final format later\n"
            + "  -if [mime] out    representation of document in intermediate format XML (outfile req'd)\n"
            + "                    specify optional mime output to allow the IF to be converted\n"
            + "                    to final format later\n"
            + "  -print            input file will be rendered and sent to the printer \n"
            + "                    see options with \"-print help\" \n"
            + "  -out mime outfile input will be rendered using the given MIME type\n"
            + "                    (outfile req'd) Example: \"-out application/pdf D:\\out.pdf\"\n"
            + "                    (Tip: \"-out list\" prints the list of supported MIME types)\n"
            //+ "  -mif outfile      input will be rendered as MIF (FrameMaker) (outfile req'd)\n"
            //+ "                    Experimental feature - requires additional fop-sandbox.jar.\n"
            + "  -svg outfile      input will be rendered as an SVG slides file (outfile req'd) \n"
            + "                    Experimental feature - requires additional fop-sandbox.jar.\n"
            + "\n"
            + "  -foout outfile    input will only be XSL transformed. The intermediate \n"
            + "                    XSL-FO file is saved and no rendering is performed. \n"
            + "                    (Only available if you use -xml and -xsl parameters)\n\n"
            + "\n"
            + " [Examples]\n" + "  fop foo.fo foo.pdf \n"
            + "  fop -fo foo.fo -pdf foo.pdf (does the same as the previous line)\n"
            + "  fop -xml foo.xml -xsl foo.xsl -pdf foo.pdf\n"
            + "  fop -xml foo.xml -xsl foo.xsl -foout foo.fo\n"
            + "  fop -xml - -xsl foo.xsl -pdf -\n"
            + "  fop foo.fo -mif foo.mif\n"
            + "  fop foo.fo -rtf foo.rtf\n"
            + "  fop foo.fo -print\n"
            + "  fop foo.fo -awt\n");
    }

    /**
     * shows the options for print output
     */
    private void printUsagePrintOutput() {
        System.err.println("USAGE: -print [from[-to][,even|odd]] [-copies numCopies]\n\n"
           + "Example:\n"
           + "all pages:                        fop infile.fo -print\n"
           + "all pages with two copies:        fop infile.fo -print -copies 2\n"
           + "all pages starting with page 7:   fop infile.fo -print 7\n"
           + "pages 2 to 3:                     fop infile.fo -print 2-3\n"
           + "only even page between 10 and 20: fop infile.fo -print 10-20,even\n");
    }

    /**
     * Outputs all commandline settings
     */
    private void dumpConfiguration() {
        log.info("Input mode: ");
        switch (inputmode) {
        case NOT_SET:
            log.info("not set");
            break;
        case FO_INPUT:
            log.info("FO ");
            if (isInputFromStdIn()) {
                log.info("fo input file: from stdin");
            } else {
                log.info("fo input file: " + fofile.toString());
            }
            break;
        case XSLT_INPUT:
            log.info("xslt transformation");
            if (isInputFromStdIn()) {
                log.info("xml input file: from stdin");
            } else {
                log.info("xml input file: " + xmlfile.toString());
            }
            log.info("xslt stylesheet: " + xsltfile.toString());
            break;
        case AREATREE_INPUT:
            log.info("AT ");
            if (isInputFromStdIn()) {
                log.info("area tree input file: from stdin");
            } else {
                log.info("area tree input file: " + areatreefile.toString());
            }
            break;
        case IF_INPUT:
            log.info("IF ");
            if (isInputFromStdIn()) {
                log.info("intermediate input file: from stdin");
            } else {
                log.info("intermediate input file: " + iffile.toString());
            }
            break;
        case IMAGE_INPUT:
            log.info("Image ");
            if (isInputFromStdIn()) {
                log.info("image input file: from stdin");
            } else {
                log.info("image input file: " + imagefile.toString());
            }
            break;
        default:
            log.info("unknown input type");
        }
        log.info("Output mode: ");
        if (outputmode == null) {
            log.info("not set");
        } else if (MimeConstants.MIME_FOP_AWT_PREVIEW.equals(outputmode)) {
            log.info("awt on screen");
            if (outfile != null) {
                log.error("awt mode, but outfile is set:");
                log.error("out file: " + outfile.toString());
            }
        } else if (MimeConstants.MIME_FOP_PRINT.equals(outputmode)) {
            log.info("print directly");
            if (outfile != null) {
                log.error("print mode, but outfile is set:");
                log.error("out file: " + outfile.toString());
            }
        } else if (MimeConstants.MIME_FOP_AREA_TREE.equals(outputmode)) {
            log.info("area tree");
            if (mimicRenderer != null) {
              log.info("mimic renderer: " + mimicRenderer);
            }
            if (isOutputToStdOut()) {
                log.info("output file: to stdout");
            } else {
                log.info("output file: " + outfile.toString());
            }
        } else if (MimeConstants.MIME_FOP_IF.equals(outputmode)) {
            log.info("intermediate format");
            log.info("output file: " + outfile.toString());
        } else {
            log.info(outputmode);
            if (isOutputToStdOut()) {
                log.info("output file: to stdout");
            } else {
                log.info("output file: " + outfile.toString());
            }
        }

        log.info("OPTIONS");

        if (userConfigFile != null) {
            log.info("user configuration file: "
                                 + userConfigFile.toString());
        } else {
            log.info("no user configuration file is used [default]");
        }
    }

}

