/*
 * 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.avalon.framework.configuration.Configuration;
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.fo.ElementMapping;
import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fonts.FontManager;
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 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 = null;

    /**
     * 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
     * @throws FOPException
     */
    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);
    }

    /**
     * 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();
    }

    /** @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();
    }

    /**
     * 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;
    }
}
