/*

   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.

 */
package org.apache.batik.apps.rasterizer;

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.util.ParsedURL;

/**
 * This application can be used to convert SVG images to raster images.
 * <br>
 * Possible result raster image formats are PNG, JPEG, TIFF, and PDF.
 * The Batik Transcoder API is used to execute the conversion. FOP is
 * needed to be able to transcode to the PDF format<br>
 *
 * The source has to be list of files or URL (set by the <code>setSources</code>
 * method). <br>
 *
 * The destination can be:<br><ul>
 * <li><b>unspecified</b>. In that case, only file sources can be converted and
 * a file in the same directory as the source will be created.</li>
 * <li><b>a directory</b>, set by the <code>setDst</code> method. In that case,
 * the output files are created in that destination directory</li>
 * <li><b>a file</b>. In case there is a <i>single
 * source</i>, the destination can be a single named file
 * (set with the <code>setDst</code> method.)</li>
 * </ul>
 *
 * <hr>
 *
 * There are a number of options which control the way the image is
 * converted to the destination format:<br><ul>
 * <li>destinationType: controls the type of conversion which should be done.
 *     see the {@link DestinationType} documentation.</li>
 * <li>width/height: they control the desired width and height, in user space,
 *     for the output image.</li>
 * <li>maxWidth/maxHeight: control the maximum width and height,
 *     in user space, of the output image.</li>
 * <li>area: controls the specific sub-area of the image which should be
 *     rendered.</li>
 * <li>backgroundColor: controls the color which is used to fill the
 *     background before rendering the image</li>
 * <li>quality: relevant only for JPEG destinations, this controls the
 *     encoding quality.</li>
 * <li>indexed: relevant only for PNG, controls the number of bits
 *              used in writting of a palletized files.</li>
 * <li>mediaType: controls the CSS media, or list of media, for which the
 *     image should be rendered.</li>
 * <li>alternate: controls the alternate CSS stylesheet to activate,
 *     if any.</li>
 * <li>language: controls the user language with which the SVG document
 *     should be converted.</li>
 * <li>userStylesheet: defines the user stylesheet to apply to SVG documents
 *     in addition to other stylesheets referenced by or embedded in the
 *     SVG documents.</li>
 * <li>pixelUnitToMillimeter: defines the size of a pixel in millimeters
 *     to use when processing the SVG documents.</li>
 * </ul>
 *
 * @version $Id$
 * @author <a href="mailto:Henri.Ruini@nokia.com">Henri Ruini</a>
 * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
 */
public class SVGConverter {
    //
    // Error codes reported by the SVGConverter
    //

    //
    // Reported when no source file has been specified.
    //
    public static final String ERROR_NO_SOURCES_SPECIFIED
        = "SVGConverter.error.no.sources.specified";

    //
    // Reported when there is more than one valid input source
    // and no output directory has been set and the source is
    // not a file.
    //
    public static final String ERROR_CANNOT_COMPUTE_DESTINATION
        = "SVGConverter.error.cannot.compute.destination";

    //
    // Reported when the dst is a file and there are multiple
    // sources.
    //
    public static final String ERROR_CANNOT_USE_DST_FILE
        = "SVGConverter.error.cannot.use.dst.file";

    //
    // Reported when the <code>Transcoder</code> for the requested
    // <code>destinationType</code> cannot be found.
    //
    public static final String ERROR_CANNOT_ACCESS_TRANSCODER
        = "SVGConverter.error.cannot.access.transcoder";

    //
    // Reported when the source is found to be the same as
    // the destination. Note that it is not guaranteed that
    // this error condition will always be detected.
    //
    public static final String ERROR_SOURCE_SAME_AS_DESTINATION
        = "SVGConverter.error.source.same.as.destination";

    //
    // Reported when one of the sources cannot be read.
    //
    public static final String ERROR_CANNOT_READ_SOURCE
        = "SVGConverter.error.cannot.read.source";

    //
    // Reported when an error happens while opening a source
    // file.
    //
    public static final String ERROR_CANNOT_OPEN_SOURCE
        = "SVGConverter.error.cannot.open.source";

    //
    // Reported if the output is not writeable. This may
    // happen if the output file already exists and does not
    // have write permission.
    //
    public static final String ERROR_OUTPUT_NOT_WRITEABLE
        = "SVGConverter.error.output.not.writeable";

    //
    // Reported when an error happens while trying to open
    // the output file for writing.
    //
    public static final String ERROR_CANNOT_OPEN_OUTPUT_FILE
        = "SVGConverter.error.cannot.open.output.file";

    //
    // Reported when the converter was not able to create
    // the destination directory for the files.
    //
    public static final String ERROR_UNABLE_TO_CREATE_OUTPUT_DIR
        = "SVGConverter.error.unable.to.create.output.dir";

    //
    // Reported when an error occurs while convertion the
    // source file.
    //
    public static final String ERROR_WHILE_RASTERIZING_FILE
        = "SVGConverter.error.while.rasterizing.file";

    //
    // Class variables and constants
    //

    /** SVG file extension */
    protected static final String SVG_EXTENSION = ".svg";

    /** Default quality value.  A value of -1 means disabled. */
    protected static final float DEFAULT_QUALITY
        = -1.0f;

    /** Maximum quality value */
    protected static final float MAXIMUM_QUALITY
        = .99F;

    /** Default result type */
    protected static final DestinationType DEFAULT_RESULT_TYPE
        = DestinationType.PNG;

    /** Default width */
    protected static final float DEFAULT_WIDTH = -1;

    /** Default height */
    protected static final float DEFAULT_HEIGHT = -1;

    /** Result type */
    protected DestinationType destinationType = DEFAULT_RESULT_TYPE;

    /** Output image height. */
    protected float height = DEFAULT_HEIGHT;

    /** Output image width. */
    protected float width = DEFAULT_WIDTH;

    /** Maximum output image height. */
    protected float maxHeight = DEFAULT_HEIGHT;

    /** Maximum output image width. */
    protected float maxWidth = DEFAULT_WIDTH;

    /** Output image quality. */
    protected float quality = DEFAULT_QUALITY;

    /** Should output Image be indexed . */
    protected int indexed = -1;

    /** Output AOI area. */
    protected Rectangle2D area = null;

    /** Language */
    protected String language = null;

    /** User stylesheet */
    protected String userStylesheet = null;

    /** Millimeters Per Pixel */
    protected float pixelUnitToMillimeter = -1.0f;

    /** Validation flag */
    protected boolean validate = false;

    /** Execute the 'onload' scripts flag */
    protected boolean executeOnload = false;

    /** Document time to seek to. */
    protected float snapshotTime = Float.NaN;

    /** Set of allowed script types. */
    protected String allowedScriptTypes = null;

    /** Controls whether scripts can only have the same origin as
        the document which references them. */
    protected boolean constrainScriptOrigin = true;

    protected boolean allowExternalResources = true;

    /** Controls whether scripts should be run securely or not */
    protected boolean securityOff = false;

    /** Sources files or URLs */
    protected List sources = null;

    /**
     * Destination image path. Can be a file (for single source) or
     *  a directory
     */
    protected File dst;

    /** Background color for the output images. */
    protected Color backgroundColor = null;

    /** Media type for which the SVG image should be rendered */
    protected String mediaType = null;

    /** Default value for the font-family when it is unspecified */
    protected String defaultFontFamily = null;

    /** Alternate stylesheet for which should be applied to the SVG */
    protected String alternateStylesheet = null;

    /** Contents of <code>fileset</code> elements. */
    protected List files = new ArrayList();

    /**
     * Controls some aspects of the converter's operation,
     *  such as whether or not it should proceed in some
     *  error situations. See {@link SVGConverterController}
     */
    protected SVGConverterController controller;

    //
    // Default constructor
    //
    public SVGConverter(){
        this(new DefaultSVGConverterController());
    }

    //
    // Constructor
    //
    public SVGConverter(SVGConverterController controller){
        if (controller == null){
            throw new IllegalArgumentException();
        }

        this.controller = controller;
    }

    //
    // Property get/set methods
    //

    /**
     * Sets the <code>destinationType</code> attribute value.
     * Should not be null.
     */
    public void setDestinationType(DestinationType destinationType) {
        if(destinationType == null){
            throw new IllegalArgumentException();
        }
        this.destinationType = destinationType;
    }

    public DestinationType getDestinationType(){
        return destinationType;
    }

    /**
     * In less than or equal to zero, the height is not
     * constrained on the output image. The height is in
     * user space.
     */
    public void setHeight(float height) {
        this.height = height;
    }

    public float getHeight(){
        return height;
    }

    /**
     * In less than or equal to zero, the width is not
     * constrained on the output image. The width is in
     * user space.
     */
    public void setWidth(float width) {
        this.width = width;
    }

    public float getWidth(){
        return width;
    }

    /**
     * If less than or equal to zero, the maximum height
     * does not have any effect on the output image.
     * The maximum height is in user space.
     */
    public void setMaxHeight(float height) {
        this.maxHeight = height;
    }

    public float getMaxHeight(){
        return maxHeight;
    }

    /**
     * If less than or equal to zero, the maximum width
     * does not have any effect on the output image.
     * The maximum width is in user space.
     */
    public void setMaxWidth(float width) {
        this.maxWidth = width;
    }

    public float getMaxWidth(){
        return maxWidth;
    }

    /**
     * Sets the JPEG encoding quality. The value should be strictly
     * less than 1. If the value is less than zero, then the maximum
     * encoding quality is used.
     */
    public void setQuality(float quality) throws IllegalArgumentException {
        if(quality >= 1){
            throw new IllegalArgumentException();
        }

        this.quality = quality;
    }

    public float getQuality(){
        return quality;
    }

    /**
     * Tells the PNG encoder to reduce the image to 256 colors, so the
     * PNG file is indexed.
     */
    public void setIndexed(int bits) throws IllegalArgumentException {
        this.indexed = bits;
    }

    public int getIndexed(){
        return indexed;
    }

    /**
     * Sets the user language. If the value is null, then the default (see
     * {@link org.apache.batik.bridge.UserAgent#getLanguages})
     * is used.
     */
    public void setLanguage(String language){
        this.language = language;
    }

    public String getLanguage(){
        return language;
    }

    /**
     * Sets the user stylesheet. May be null.
     */
    public void setUserStylesheet(String userStylesheet){
        this.userStylesheet = userStylesheet;
    }

    public String getUserStylesheet(){
        return userStylesheet;
    }

    /**
     * Sets the millimeters per pixel constant. A negative
     * value will cause the default value
     * (see {@link org.apache.batik.bridge.UserAgent#getPixelUnitToMillimeter})
     * to be used.
     */
    public void setPixelUnitToMillimeter(float pixelUnitToMillimeter){
        this.pixelUnitToMillimeter = pixelUnitToMillimeter;
    }

    public float getPixelUnitToMillimeter(){
        return pixelUnitToMillimeter;
    }

    /**
     * Sets the <code>area</code> as a Rectangle. This value can
     * be null in which case the whole image will be rendered. If the
     * area is not null, then only the portion of the image it
     * defines will be rendered.
     */
    public void setArea(Rectangle2D area){
        this.area = area;
    }

    public Rectangle2D getArea(){
        return area;
    }

    /**
     * Sets the list of individual SVG sources. The strings
     * can be either URLs or file names. Note that invalid
     * sources (e.g., read-protected files or invalid URLs)
     * will cause <code>SVGConverterExceptions</code> to be
     * thrown during the transcoding process (see {@link #execute});
     */
    public void setSources(String[] sources) {
        if(sources == null){
            this.sources = null;
        }
        else{
            this.sources = new ArrayList();
            for (String source : sources) {
                if (source != null) {
                    this.sources.add(source);
                }
            }

            if (this.sources.size() == 0){
                this.sources = null;
            }
        }
    }

    public List getSources(){
        return sources;
    }

    /**
     * When converting a single source, dst can be a file.
     * Othewise, it should be a directory.
     */
    public void setDst(File dst) {
        this.dst = dst;
    }

    public File getDst(){
        return dst;
    }

    /**
     * Sets the <code>backgroundColor</code> value. This can be
     * null in which case no color will be used to fill the
     * background before rendering this SVG image.
     */
    public void setBackgroundColor(Color backgroundColor){
        this.backgroundColor = backgroundColor;
    }

    public Color getBackgroundColor(){
        return backgroundColor;
    }

    /**
     * Sets the <code>mediaType</code> value. This value controls
     * the CSS media for which the image should be rendered. It
     * can be null, in which case no specific media selectors will
     * apply. If it is not null, it can contain space separated values
     * of the medias for which the image should be rendered. For example,
     * "screen", "print" or "scree projection" are valid values.
     */
    public void setMediaType(String mediaType){
        this.mediaType = mediaType;
    }

    public String getMediaType(){
        return mediaType;
    }

    /**
     * Sets the <code>defaultFontFamily</code> value. This value controls
     * the default value for the font-family CSS property when that
     * property is unspecified.
     */
    public void setDefaultFontFamily(String defaultFontFamily) {
        this.defaultFontFamily = defaultFontFamily;
    }

    public String getDefaultFontFamily() {
        return defaultFontFamily;
    }

    /**
     * Sets the <code>alternateStyleSheet</code> value. This value
     * controls the CSS alternate stylesheet to select in the
     * rendered SVG file(s). It may be null, in which case no alternate
     * stylesheet will be selected.
     */
    public void setAlternateStylesheet(String alternateStylesheet){
        this.alternateStylesheet = alternateStylesheet;
    }

    public String getAlternateStylesheet(){
        return alternateStylesheet;
    }

    /**
     * Defines whether or not input sources should be validated in
     * the conversion process
     */
    public void setValidate(boolean validate){
        this.validate = validate;
    }

    public boolean getValidate(){
        return validate;
    }

    /**
     * Sets whether or not scripts attached to the DOM using 'onload'
     * event attribute must be executed before rasterizing.
     *
     * @param b true means scripts will be executed
     */
    public void setExecuteOnload(boolean b){
        this.executeOnload = b;
    }

    /**
     * Returns true if the scripts attached to the DOM using 'onload'
     * event attribute is going to be executed before rasterizing,
     * false otherwise.
     */
    public boolean getExecuteOnload(){
        return executeOnload;
    }

    /**
     * Sets the document time to seek to before rasterizing.
     *
     * @param t the document time, in seconds
     */
    public void setSnapshotTime(float t) {
        snapshotTime = t;
    }

    /**
     * Returns the document to to seek to before rasterizing.
     */
    public float getSnapshotTime() {
        return snapshotTime;
    }

    /**
     * Sets the set of allowed script types (i.e., the set of possible
     * values for the type attribute in the &lt;script&gt; element),
     * as a comma separated list of allowed values.
     */
    public void setAllowedScriptTypes(String allowedScriptTypes){
        this.allowedScriptTypes = allowedScriptTypes;
    }

    /**
     * Returns the list of allowed script types.
     *
     * @see #setAllowedScriptTypes
     */
    public String getAllowedScriptTypes(){
        return allowedScriptTypes;
    }

    /**
     * Sets whether scripts should only be loaded from the same
     * location as the documents referencing them.
     */
    public void setConstrainScriptOrigin(boolean constrainScriptOrigin){
        this.constrainScriptOrigin = constrainScriptOrigin;
    }

    /**
     * Returns whether scripts can only be loaded from the same
     * origin as the documents referencing them.
     */
    public boolean getConstrainScriptOrigin(){
        return constrainScriptOrigin;
    }

    /**
     * Sets whether or not scripts should be run securely
     */
    public void setSecurityOff(boolean securityOff){
        this.securityOff = securityOff;
    }

    /**
     * Returns whether or not scripts will be run securely
     */
    public boolean getSecurityOff(){
        return securityOff;
    }

    /**
     * Returns true if f is a File. <code>f</code> is found to be a file if
     * it exists and is a file. If it does not exist, it is declared
     * to be a file if it has the same extension as the DestinationType.
     */
    protected boolean isFile(File f){
        if (f.exists()){
            return f.isFile();
        } else {
            if (f.toString().toLowerCase().endsWith(destinationType.getExtension())){
                return true;
            }
        }

        return false;
    }

    /**
     * Starts the conversion process.
     * @throws SVGConverterException thrown if parameters are not set correctly.
     */
    public void execute() throws SVGConverterException {
        // Compute the set of SVGConverterSource from the source properties
        // (srcDir and srcFile);
        // This throws an exception if there is not at least one src file.
        List sources = computeSources();

        // Compute the destination files from dest
        List dstFiles = null;
        if(sources.size() == 1 && dst != null && isFile(dst)){
            dstFiles = new ArrayList();
            dstFiles.add(dst);
        }
        else{
            dstFiles = computeDstFiles(sources);
        }

        // Now, get the transcoder to use for the operation
        Transcoder transcoder = destinationType.getTranscoder();
        if(transcoder == null) {
            throw new SVGConverterException(ERROR_CANNOT_ACCESS_TRANSCODER,
                                             new Object[]{destinationType.toString()},
                                             true /* fatal error */);
        }

        // Now, compute the set of transcoding hints to use
        Map hints = computeTranscodingHints();
        transcoder.setTranscodingHints(hints);

        // Notify listener that task has been computed
        if(!controller.proceedWithComputedTask(transcoder,
                                               hints,
                                               sources,
                                               dstFiles)){
            return;
        }

        // Convert files one by one
        for(int i = 0 ; i < sources.size() ; i++) {
            // Get the file from the vector.
            SVGConverterSource currentFile
                = (SVGConverterSource)sources.get(i);
            File outputFile  = (File)dstFiles.get(i);

            createOutputDir(outputFile);
            transcode(currentFile, outputFile, transcoder);
        }
    }

    /**
     * Populates a vector with destination files names
     * computed from the names of the files in the sources vector
     * and the value of the dst property
     */
    protected List computeDstFiles(List sources)
    throws SVGConverterException {
        List dstFiles = new ArrayList();
        if (dst != null) {
            if (dst.exists() && dst.isFile()) {
                throw new SVGConverterException(ERROR_CANNOT_USE_DST_FILE);
            }

            //
            // Either dst exist and is a directory or dst does not
            // exist and we may fail later on in createOutputDir
            //
            int n = sources.size();
            for (Object source : sources) {
                SVGConverterSource src = (SVGConverterSource) source;
                // Generate output filename from input filename.
                File outputName = new File(dst.getPath(),
                        getDestinationFile(src.getName()));
                dstFiles.add(outputName);

            }
        } else {
            //
            // No destination directory has been specified.
            // Try and create files in the same directory as the
            // sources. This only work if sources are files.
            //
            int n = sources.size();
            for (Object source : sources) {
                SVGConverterSource src = (SVGConverterSource) source;
                if (!(src instanceof SVGConverterFileSource)) {
                    throw new SVGConverterException(ERROR_CANNOT_COMPUTE_DESTINATION,
                            new Object[]{src});
                }

                // Generate output filename from input filename.
                SVGConverterFileSource fs = (SVGConverterFileSource) src;
                File outputName = new File(fs.getFile().getParent(),
                        getDestinationFile(src.getName()));
                dstFiles.add(outputName);
            }

        }

        return dstFiles;
    }

    /**
     * Populates a vector with the set of SVG files from the
     * srcDir if it is not null and with the sources (files or URLs)
     * if any.
     */
    protected List computeSources() throws SVGConverterException{
        List sources = new ArrayList();

        // Check that at least one source has been specified.
        if (this.sources == null){
            throw new SVGConverterException(ERROR_NO_SOURCES_SPECIFIED);
        }

        int n = this.sources.size();
        for (Object source : this.sources) {
            String sourceString = (String) source;
            File file = new File(sourceString);
            if (file.exists()) {
                sources.add(new SVGConverterFileSource(file));
            } else {
                String[] fileNRef = getFileNRef(sourceString);
                file = new File(fileNRef[0]);
                if (file.exists()) {
                    sources.add(new SVGConverterFileSource(file, fileNRef[1]));
                } else {
                    sources.add(new SVGConverterURLSource(sourceString));
                }
            }
        }

        return sources;
    }

    public String[] getFileNRef(String fileName){
        int n = fileName.lastIndexOf('#');
        String[] result = {fileName, ""};
        if (n > -1){
            result[0] = fileName.substring(0, n);
            if (n+1 < fileName.length()){
                result[1] = fileName.substring(n+1);
            }
        }

        return result;
    }

    // -----------------------------------------------------------------------
    //   Internal methods
    // -----------------------------------------------------------------------

    /**
     * Computes the set of transcoding hints to use for the operation
     */
    protected Map computeTranscodingHints(){
        Map map = new HashMap();

        // Set AOI. ----------------------------------------------------------
        if (area != null) {
            map.put(ImageTranscoder.KEY_AOI, area);
        }

        // Set image quality. ------------------------------------------------
        if (quality > 0) {
            map.put(JPEGTranscoder.KEY_QUALITY, this.quality);
        }

        // Set image indexed. ------------------------------------------------
        if (indexed != -1) {
            map.put(PNGTranscoder.KEY_INDEXED, indexed);
        }

        // Set image background color -----------------------------------------
        if (backgroundColor != null){
            map.put(ImageTranscoder.KEY_BACKGROUND_COLOR, backgroundColor);
        }

        // Set image height and width. ----------------------------------------
        if (height > 0) {
            map.put(ImageTranscoder.KEY_HEIGHT, this.height);
        }
        if (width > 0){
            map.put(ImageTranscoder.KEY_WIDTH, this.width);
        }

        // Set maximum height and width ---------------------------------------
        if (maxHeight > 0) {
            map.put(ImageTranscoder.KEY_MAX_HEIGHT, this.maxHeight);
        }
        if (maxWidth > 0){
            map.put(ImageTranscoder.KEY_MAX_WIDTH, this.maxWidth);
        }

        // Set CSS Media
        if (mediaType != null){
            map.put(ImageTranscoder.KEY_MEDIA, mediaType);
        }

        // Set default font-family
        if (defaultFontFamily != null) {
            map.put(ImageTranscoder.KEY_DEFAULT_FONT_FAMILY, defaultFontFamily);
        }

        // Set alternateStylesheet
        if (alternateStylesheet != null){
            map.put(ImageTranscoder.KEY_ALTERNATE_STYLESHEET, alternateStylesheet);
        }

        // Set user stylesheet
        if (userStylesheet != null) {
            String userStylesheetURL;
            try {
                URL userDir = new File(System.getProperty("user.dir")).toURI().toURL();
                userStylesheetURL = new ParsedURL(userDir, userStylesheet).toString();
            } catch (Exception e) {
                userStylesheetURL = userStylesheet;
            }
            map.put(ImageTranscoder.KEY_USER_STYLESHEET_URI, userStylesheetURL);
        }

        // Set the user language
        if (language != null){
            map.put(ImageTranscoder.KEY_LANGUAGE, language);
        }

        // Sets the millimeters per pixel
        if (pixelUnitToMillimeter > 0){
            map.put(ImageTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER,
                    pixelUnitToMillimeter);
        }

        // Set validation
        if (validate){
            map.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, Boolean.TRUE);
        }

        // Set onload
        if (executeOnload) {
            map.put(ImageTranscoder.KEY_EXECUTE_ONLOAD, Boolean.TRUE);
        }

        // Set snapshot time
        if (!Float.isNaN(snapshotTime)) {
            map.put(ImageTranscoder.KEY_SNAPSHOT_TIME, snapshotTime);
        }

        // Set allowed scripts
        if (allowedScriptTypes != null) {
            map.put(ImageTranscoder.KEY_ALLOWED_SCRIPT_TYPES, allowedScriptTypes);
        }

        // Set constrain script origin
        if (!constrainScriptOrigin) {
            map.put(ImageTranscoder.KEY_CONSTRAIN_SCRIPT_ORIGIN, Boolean.FALSE);
        }

        if (!allowExternalResources) {
            map.put(ImageTranscoder.KEY_ALLOW_EXTERNAL_RESOURCES, Boolean.FALSE);
        }

        return map;
    }

    /**
     * Converts the input image to the result image.
     * with the given transcoder. If a failure happens, the
     * controller is notified and decides whether to proceed
     * or not. If it decides to proceed, the converter will
     * continue processing other files. Otherwise, it will
     * throw an exception.
     */
    protected void transcode(SVGConverterSource inputFile,
                             File outputFile,
                             Transcoder transcoder)
        throws SVGConverterException {
        TranscoderInput input = null;
        TranscoderOutput output = null;
        OutputStream outputStream = null;

        if (!controller.proceedWithSourceTranscoding(inputFile,
                                                     outputFile)){
            return;
        }

        try {
            if (inputFile.isSameAs(outputFile.getPath())) {
                throw new SVGConverterException(ERROR_SOURCE_SAME_AS_DESTINATION,
                                                 true /* fatal error */);
            }

            // Compute transcoder input.
            if (!inputFile.isReadable()) {
                throw new SVGConverterException(ERROR_CANNOT_READ_SOURCE,
                                                 new Object[]{inputFile.getName()});
            }

            try {
                InputStream in = inputFile.openStream();
                in.close();
            } catch(IOException ioe) {
                throw new SVGConverterException(ERROR_CANNOT_OPEN_SOURCE,
                                                 new Object[] {inputFile.getName(),
                                                               ioe.toString()});
                                                               }

            input = new TranscoderInput(inputFile.getURI());

            // Compute transcoder output.
            if (!isWriteable(outputFile)) {
                throw new SVGConverterException(ERROR_OUTPUT_NOT_WRITEABLE,
                                                 new Object[] {outputFile.getName()});
            }
            try {
                outputStream = new FileOutputStream(outputFile);
            } catch(FileNotFoundException fnfe) {
                throw new SVGConverterException(ERROR_CANNOT_OPEN_OUTPUT_FILE,
                                                 new Object[] {outputFile.getName()});
            }

            output = new TranscoderOutput(outputStream);
        } catch(SVGConverterException e){
            boolean proceed = controller.proceedOnSourceTranscodingFailure
                (inputFile, outputFile, e.getErrorCode());
            if (proceed){
                e.printStackTrace();
                return;
            } else {
                throw e;
            }
        }

        // Transcode now
        boolean success = false;
        try {
            transcoder.transcode(input, output);
            success = true;
        } catch(Exception te) {
            te.printStackTrace();
            try {
                outputStream.flush();
                outputStream.close();
            } catch(IOException ioe) {}

            // Report error to the controller. If controller decides
            // to stop, throw an exception
            boolean proceed = controller.proceedOnSourceTranscodingFailure
                (inputFile, outputFile, ERROR_WHILE_RASTERIZING_FILE);

            if (!proceed){
                throw new SVGConverterException(ERROR_WHILE_RASTERIZING_FILE,
                                                 new Object[] {outputFile.getName(),
                                                               te.getMessage()});
            }
        }

        // Close streams and clean up.
        try {
            outputStream.flush();
            outputStream.close();
        } catch(IOException ioe) {
            return;
        }

        if (success){
            controller.onSourceTranscodingSuccess(inputFile, outputFile);
        }
    }

    /**
     * Get the name of the result image file.
     *
     * <P>This method modifies the result filename, it changes the existing
     * suffix to correspong the result file type. It also adds the suffix
     * if the file doesn't have one.</P>
     *
     * @param file Result file name as a String object.
     *
     * @return Name of the file. The directory of the file is not returned.
     *         The returned string is empty if the parameter is not a file.
     */
    protected String getDestinationFile(String file) {
        int suffixStart;            // Location of the first char of
                                    // the suffix in a String.
        String oldName;             // Existing filename.
        String newSuffix = destinationType.getExtension();
                                    // New suffix.

        oldName = file;
        // Find the first char of the suffix.
        suffixStart = oldName.lastIndexOf( '.' );
        String dest = null;
        if (suffixStart != -1) {
            // Replace existing suffix.
            dest = oldName.substring(0, suffixStart) + newSuffix;
        } else {
            // Add new suffix.
            dest = oldName + newSuffix;
        }

        return dest;
    }

    /**
     * Creates directories for output files if needed.
     *
     * @param output Output file with path.
     *
     * @throws SVGConverterException Output directory doesn't exist and it can't be created.
     */
    protected void createOutputDir(File output)
        throws SVGConverterException {

        File outputDir;             // Output directory object.
        boolean success = true;     // false if the output directory
                                    // doesn't exist and it can't be created
                                    // true otherwise


        // Create object from output directory.
        String parentDir = output.getParent();
        if (parentDir != null){
            outputDir = new File(output.getParent());
            if ( ! outputDir.exists() ) {
                // Output directory doesn't exist, so create it.
                success = outputDir.mkdirs();
            } else {
                if ( ! outputDir.isDirectory() ) {
                    // File, which have a same name as the output directory, exists.
                    // Create output directory.
                    success = outputDir.mkdirs();
                }
            }
        }

        if (!success) {
            throw new SVGConverterException(ERROR_UNABLE_TO_CREATE_OUTPUT_DIR);
        }
    }

    /**
     * Checks if the application is allowed to write to the file.
     *
     * @param file File to be checked.
     *
     * @return <code>true</code> if the file is writeable and <code>false</code> otherwise.
     */
    protected boolean isWriteable(File file) {
        if (file.exists()) {
            // Check the existing file.
            if (!file.canWrite()) {
                return false;
            }
        } else {
            // Check the file that doesn't exist yet.
            // Create a new file. The file is writeable if
            // the creation succeeds.
            try {
                file.createNewFile();
            } catch(IOException ioe) {
                return false;
            }
        }
        return true;
    }

    // -----------------------------------------------------------------------
    //   Inner classes
    // -----------------------------------------------------------------------

    /**
     * Convenience class to filter svg files
     */
    public static class SVGFileFilter implements FileFilter {
        public static final String SVG_EXTENSION = ".svg";

        public boolean accept(File file){
            if (file != null && file.getName().toLowerCase().endsWith(SVG_EXTENSION)){
                return true;
            }

            return false;
        }
    }

}

