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

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.xml.sax.SAXException;

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

import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext.FallbackResolver;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.configuration.Configuration;
import org.apache.fop.fo.ElementMapping;
import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.hyphenation.HyphenationTreeCache;
import org.apache.fop.layoutmgr.LayoutManagerMaker;
import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.RendererConfig;
import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.RendererFactory;
import org.apache.fop.render.XMLHandlerRegistry;
import org.apache.fop.util.ColorSpaceCache;
import org.apache.fop.util.ContentHandlerFactoryRegistry;

/**
 * Factory class which instantiates new Fop and FOUserAgent instances. This
 * class also holds environmental information and configuration used by FOP.
 * Information that may potentially be different for each renderingq run can be
 * found and managed in the FOUserAgent.
 */
public final class FopFactory implements ImageContext {

    /** logger instance */
    private static Log log = LogFactory.getLog(FopFactory.class);

    /** Factory for Renderers and FOEventHandlers */
    private final RendererFactory rendererFactory;

    /** Registry for XML handlers */
    private final XMLHandlerRegistry xmlHandlers;

    /** Registry for image handlers */
    private final ImageHandlerRegistry imageHandlers;

    /** The registry for ElementMapping instances */
    private final ElementMappingRegistry elementMappingRegistry;

    /** The registry for ContentHandlerFactory instance */
    private final ContentHandlerFactoryRegistry contentHandlerFactoryRegistry
            = new ContentHandlerFactoryRegistry();

    private final ColorSpaceCache colorSpaceCache;

    private final FopFactoryConfig config;

    private final InternalResourceResolver resolver;

    private final Map<String, RendererConfig> rendererConfig;

    private HyphenationTreeCache hyphenationTreeCache;

    private FopFactory(FopFactoryConfig config) {
        this.config = config;
        this.resolver = ResourceResolverFactory.createInternalResourceResolver(config.getBaseURI(),
                config.getResourceResolver());
        this.elementMappingRegistry = new ElementMappingRegistry(this);
        this.colorSpaceCache = new ColorSpaceCache(resolver);
        this.rendererFactory = new RendererFactory(config.preferRenderer());
        this.xmlHandlers = new XMLHandlerRegistry();
        this.imageHandlers = new ImageHandlerRegistry();
        rendererConfig = new HashMap<String, RendererConfig>();
    }

    /**
     * Map of configured names of hyphenation pattern file names: ll_CC => name
     */
    private Map<String, String> hyphPatNames;

    /**
     * FOP has the ability, for some FO's, to continue processing even if the
     * input XSL violates that FO's content model.  This is the default
     * behavior for FOP.  However, this flag, if set, provides the user the
     * ability for FOP to halt on all content model violations if desired.
     * Returns a new FopFactory instance that is configured using the {@link FopFactoryConfig} object.
     *
     * @param config the fop configuration
     * @return the requested FopFactory instance.
     */
    public static FopFactory newInstance(FopFactoryConfig config) {
        return new FopFactory(config);
    }

    /**
     * Returns a new FopFactory instance that is configured using the {@link FopFactoryConfig} object that
     * is created when the fopConf is parsed.
     *
     * @param fopConf the fop conf configuration file to parse
     * @return the requested FopFactory instance.
     * @throws IOException
     * @throws SAXException
     */
    public static FopFactory newInstance(File fopConf) throws SAXException, IOException {
        return new FopConfParser(fopConf).getFopFactoryBuilder().build();
    }

    /**
     * Returns a new FopFactory instance that is configured only by the default configuration
     * parameters.
     *
     * @param baseURI the base URI to resolve resource URIs against
     * @return the requested FopFactory instance.
     */
    public static FopFactory newInstance(URI baseURI) {
        return new FopFactoryBuilder(baseURI).build();
    }

    /**
     * Returns a new FopFactory instance that is configured using the {@link FopFactoryConfig} object that
     * is created when the fopConf is parsed.
     *
     * @param baseURI the base URI to resolve resource URIs against
     * @param confStream the fop conf configuration stream to parse
     * @return the requested FopFactory instance.
     * @throws SAXException
     * @throws IOException
     */
    public static FopFactory newInstance(URI baseURI, InputStream confStream) throws SAXException,
            IOException {
        return new FopConfParser(confStream, baseURI).getFopFactoryBuilder().build();
    }

    /**
     * Returns a new FOUserAgent instance. Use the FOUserAgent to configure special values that
     * are particular to a rendering run. Don't reuse instances over multiple rendering runs but
     * instead create a new one each time and reuse the FopFactory.
     * @return the newly created FOUserAgent instance initialized with default values
     */
    public FOUserAgent newFOUserAgent() {
        FOUserAgent userAgent = new FOUserAgent(this, resolver);
        return userAgent;
    }

    boolean isComplexScriptFeaturesEnabled() {
        return config.isComplexScriptFeaturesEnabled();
    }

    /**
     * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
     * instance.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(String outputFormat) throws FOPException {
        return newFOUserAgent().newFop(outputFormat);
    }

    /**
     * Returns a new {@link Fop} instance. Use this factory method if you want to configure this
     * very rendering run, i.e. if you want to set some metadata like the title and author of the
     * document you want to render. In that case, create a new {@link FOUserAgent}
     * instance using {@link #newFOUserAgent()}.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param userAgent the user agent that will be used to control the rendering run
     * @return the new Fop instance
     * @throws FOPException  when the constructor fails
     */
    public Fop newFop(String outputFormat, FOUserAgent userAgent) throws FOPException {
        return userAgent.newFop(outputFormat, null);
    }

    boolean isTableBorderOverpaint() {
        return config.isTableBorderOverpaint();
    }

    /**
     * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
     * instance. Use this factory method if your output type requires an output stream.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param stream the output stream
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(String outputFormat, OutputStream stream) throws FOPException {
        return newFOUserAgent().newFop(outputFormat, stream);
    }

    /**
     * Returns a new {@link Fop} instance. Use this factory method if your output type
     * requires an output stream and you want to configure this very rendering run,
     * i.e. if you want to set some metadata like the title and author of the document
     * you want to render. In that case, create a new {@link FOUserAgent} instance
     * using {@link #newFOUserAgent()}.
     * <p>
     * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
     * use the constants defined in {@link MimeConstants}.
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param userAgent the user agent that will be used to control the rendering run
     * @param stream the output stream
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(String outputFormat, FOUserAgent userAgent, OutputStream stream)
            throws FOPException {
        return userAgent.newFop(outputFormat, stream);
    }

    /**
     * Returns a new {@link Fop} instance. Use this factory method if you want to supply your
     * own {@link org.apache.fop.render.Renderer Renderer} or
     * {@link org.apache.fop.fo.FOEventHandler FOEventHandler}
     * instance instead of the default ones created internally by FOP.
     * @param userAgent the user agent that will be used to control the rendering run
     * @return the new Fop instance
     * @throws FOPException when the constructor fails
     */
    public Fop newFop(FOUserAgent userAgent) throws FOPException {
        if (userAgent.getRendererOverride() == null
                && userAgent.getFOEventHandlerOverride() == null
                && userAgent.getDocumentHandlerOverride() == null) {
            throw new IllegalStateException("An overriding renderer,"
                    + " FOEventHandler or IFDocumentHandler must be set on the user agent"
                    + " when this factory method is used!");
        }
        return newFop(null, userAgent);
    }

    /** @return the RendererFactory */
    public RendererFactory getRendererFactory() {
        return this.rendererFactory;
    }

    /** @return the XML handler registry */
    public XMLHandlerRegistry getXMLHandlerRegistry() {
        return this.xmlHandlers;
    }

    /** @return the image handler registry */
    public ImageHandlerRegistry getImageHandlerRegistry() {
        return this.imageHandlers;
    }

    /** @return the element mapping registry */
    public ElementMappingRegistry getElementMappingRegistry() {
        return this.elementMappingRegistry;
    }

    /** @return the content handler factory registry */
    public ContentHandlerFactoryRegistry getContentHandlerFactoryRegistry() {
        return this.contentHandlerFactoryRegistry;
    }

    /**
     * Returns the renderer configuration object for a specific renderer given the parser and
     * configuration to read. The renderer config is cached such that the {@link Configuration} is
     * only parsed once per renderer, per FopFactory instance.
     *
     * @param userAgent the user agent
     * @param cfg the configuration to be parsed
     * @param configCreator the parser that creates the config object
     * @return the config object
     * @throws FOPException when an error occurs while creating the configuration object
     */
    synchronized RendererConfig getRendererConfig(FOUserAgent userAgent, Configuration cfg,
            RendererConfigParser configCreator) throws FOPException {
        RendererConfig config = rendererConfig.get(configCreator.getMimeType());
        if (config == null) {
            try {
                config = configCreator.build(userAgent, cfg);
                rendererConfig.put(configCreator.getMimeType(), config);
            } catch (Exception e) {
                throw new FOPException(e);
            }
        }
        return config;
    }

    /**
     * Add the element mapping with the given class name.
     * @param elementMapping the class name representing the element mapping.
     */
    public void addElementMapping(ElementMapping elementMapping) {
        this.elementMappingRegistry.addElementMapping(elementMapping);
    }

    /**
     * Returns whether accessibility is enabled.
     * @return true if accessibility is enabled
     */
    boolean isAccessibilityEnabled() {
        return config.isAccessibilityEnabled();
    }

    boolean isKeepEmptyTags() {
        return config.isKeepEmptyTags();
    }

    /** @see FopFactoryConfig#getImageManager() */
    public ImageManager getImageManager() {
        return config.getImageManager();
    }

    /** @see FopFactoryConfig#getLayoutManagerMakerOverride() */
    public LayoutManagerMaker getLayoutManagerMakerOverride() {
        return config.getLayoutManagerMakerOverride();
    }

    /** @see FopFactoryConfig#getHyphenationPatternNames() */
    public Map<String, String> getHyphenationPatternNames() {
        return config.getHyphenationPatternNames();
    }

    /** @see FopFactoryConfig#validateStrictly() */
    public boolean validateStrictly() {
        return config.validateStrictly();
    }

    /** @see FopFactoryConfig#isBreakIndentInheritanceOnReferenceAreaBoundary() */
    public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
        return config.isBreakIndentInheritanceOnReferenceAreaBoundary();
    }

    /** @see FopFactoryConfig#getSourceResolution() */
    public float getSourceResolution() {
        return config.getSourceResolution();
    }

    /** @see FopFactoryConfig#getTargetResolution() */
    public float getTargetResolution() {
        return config.getTargetResolution();
    }

    public InternalResourceResolver getHyphenationResourceResolver() {
        return config.getHyphenationResourceResolver();
    }

    /**
     * Returns the conversion factor from pixel units to millimeters. This
     * depends on the desired source resolution.
     * @return float conversion factor
     * @see #getSourceResolution()
     */
    public float getSourcePixelUnitToMillimeter() {
        return UnitConv.IN2MM / getSourceResolution();
    }

    /**
     * Returns the conversion factor from pixel units to millimeters. This
     * depends on the desired target resolution.
     * @return float conversion factor
     * @see #getTargetResolution()
     */
    public float getTargetPixelUnitToMillimeter() {
        return 25.4f / getTargetResolution();
    }

    /** @see FopFactoryConfig#getPageHeight() */
    public String getPageHeight() {
        return config.getPageHeight();
    }

    /** @see FopFactoryConfig#getPageWidth() */
    public String getPageWidth() {
        return config.getPageWidth();
    }

    /** @see FopFactoryConfig#isNamespaceIgnored(String) */
    public boolean isNamespaceIgnored(String namespaceURI) {
        return config.isNamespaceIgnored(namespaceURI);
    }

    /** @see FopFactoryConfig#getIgnoredNamespaces() */
    public Set<String> getIgnoredNamespace() {
        return config.getIgnoredNamespaces();
    }

    /**
     * Get the user configuration.
     * @return the user configuration
     */
    public Configuration getUserConfig() {
        return config.getUserConfig();
    }

    /** @see FopFactoryConfig#validateUserConfigStrictly() */
    public boolean validateUserConfigStrictly() {
        return config.validateUserConfigStrictly();
    }

    /** @see FopFactoryConfig#getFontManager() */
    public FontManager getFontManager() {
        return config.getFontManager();
    }

    /** @see FopFactoryConfig#getFallbackResolver() */
    FallbackResolver getFallbackResolver() {
        return config.getFallbackResolver();
    }

    /**
     * Returns the color space cache for this instance.
     * <p>
     * Note: this method should not be considered as part of FOP's external API.
     * @return the color space cache
     */
    public ColorSpaceCache getColorSpaceCache() {
        return this.colorSpaceCache;
    }

    public HyphenationTreeCache getHyphenationTreeCache() {
        if (hyphenationTreeCache == null) {
            hyphenationTreeCache = new HyphenationTreeCache();
        }
        return hyphenationTreeCache;
    }
}
