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

// Java
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.Map;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
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.ImageSessionContext;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
import org.apache.xmlgraphics.image.loader.util.SoftMapCache;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.Version;
import org.apache.fop.accessibility.Accessibility;
import org.apache.fop.accessibility.DummyStructureTreeEventHandler;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.events.DefaultEventBroadcaster;
import org.apache.fop.events.Event;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.events.EventListener;
import org.apache.fop.events.FOPEventListenerProxy;
import org.apache.fop.events.LoggingEventListener;
import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.layoutmgr.LayoutManagerMaker;
import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererConfig;
import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.RendererConfigOption;
import org.apache.fop.render.RendererFactory;
import org.apache.fop.render.XMLHandlerRegistry;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.util.ColorSpaceCache;
import org.apache.fop.util.ContentHandlerFactoryRegistry;

/**
 * This is the user agent for FOP.
 * It is the entity through which you can interact with the XSL-FO processing and is
 * used by the processing to obtain user configurable options.
 * <p>
 * Renderer specific extensions (that do not produce normal areas on
 * the output) will be done like so:
 * <br>
 * The extension will create an area, custom if necessary
 * <br>
 * this area will be added to the user agent with a key
 * <br>
 * the renderer will know keys for particular extensions
 * <br>
 * eg. bookmarks will be held in a special hierarchical area representing
 * the title and bookmark structure
 * <br>
 * These areas may contain resolvable areas that will be processed
 * with other resolvable areas
 */
public class FOUserAgent {

    private static Log log = LogFactory.getLog("FOP");

    private final FopFactory factory;

    private final InternalResourceResolver resourceResolver;

    private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
    private Map rendererOptions = new java.util.HashMap();
    private File outputFile;
    private IFDocumentHandler documentHandlerOverride;
    private Renderer rendererOverride;
    private FOEventHandler foEventHandlerOverride;
    private boolean locatorEnabled = true; // true by default (for error messages).
    private boolean conserveMemoryPolicy;
    private EventBroadcaster eventBroadcaster = new FOPEventBroadcaster();
    private StructureTreeEventHandler structureTreeEventHandler
            = DummyStructureTreeEventHandler.INSTANCE;
    private boolean pdfUAEnabled;

    /** Producer:  Metadata element for the system/software that produces
     * the document. (Some renderers can store this in the document.)
     */
    protected String producer = "Apache FOP Version " + Version.getVersion();

    /** Creator:  Metadata element for the user that created the
     * document. (Some renderers can store this in the document.)
     */
    protected String creator;

    /** Creation Date:  Override of the date the document was created.
     * (Some renderers can store this in the document.)
     */
    protected Date creationDate;

    /** Author of the content of the document. */
    protected String author;
    /** Title of the document. */
    protected String title;
    /** Subject of the document. */
    protected String subject;
    /** Set of keywords applicable to this document. */
    protected String keywords;

    private final ImageSessionContext imageSessionContext;
    private final SoftMapCache pdfObjectCache = new SoftMapCache(true);

    /**
     * Main constructor. <b>This constructor should not be called directly. Please use the
     * methods from FopFactory to construct FOUserAgent instances!</b>
     * @param factory the factory that provides environment-level information
     * @param resourceResolver the resolver used to acquire resources
     * @see org.apache.fop.apps.FopFactory
     */
    FOUserAgent(final FopFactory factory, InternalResourceResolver resourceResolver) {
        this.factory = factory;
        this.resourceResolver = resourceResolver;
        setTargetResolution(factory.getTargetResolution());
        setAccessibility(factory.isAccessibilityEnabled());
        imageSessionContext = new AbstractImageSessionContext(factory.getFallbackResolver()) {

            public ImageContext getParentContext() {
                return factory;
            }

            public float getTargetResolution() {
                return FOUserAgent.this.getTargetResolution();
            }

            public Source resolveURI(String uri) {
                return FOUserAgent.this.resolveURI(uri);
            }
        };
    }

    /**
     * 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 org.apache.fop.apps.FopFactory#newFOUserAgent() 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 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 new Fop(outputFormat, this, stream);
    }


    /**
     * 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 org.apache.fop.apps.FopFactory#newFOUserAgent() 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").
     * @return the new Fop instance
     * @throws FOPException  when the constructor fails
     */
    public Fop newFop(String outputFormat) throws FOPException {
        return newFop(outputFormat, null);
    }


    /**
     * Returns the resource resolver.
     *
     * @return the resource resolver
     */
    public InternalResourceResolver getResourceResolver() {
        return resourceResolver;
    }

    // ---------------------------------------------- rendering-run dependent stuff

    /**
     * Sets an explicit document handler to use which overrides the one that would be
     * selected by default.
     * @param documentHandler the document handler instance to use
     */
    public void setDocumentHandlerOverride(IFDocumentHandler documentHandler) {
        if (isAccessibilityEnabled()) {
            setStructureTreeEventHandler(documentHandler.getStructureTreeEventHandler());
        }
        this.documentHandlerOverride = documentHandler;
    }

    /**
     * Returns the overriding {@link IFDocumentHandler} instance, if any.
     * @return the overriding document handler or null
     */
    public IFDocumentHandler getDocumentHandlerOverride() {
        return this.documentHandlerOverride;
    }

    /**
     * Sets an explicit renderer to use which overrides the one defined by the
     * render type setting.
     * @param renderer the Renderer instance to use
     */
    public void setRendererOverride(Renderer renderer) {
        this.rendererOverride = renderer;
    }

    /**
     * Returns the overriding Renderer instance, if any.
     * @return the overriding Renderer or null
     */
    public Renderer getRendererOverride() {
        return rendererOverride;
    }


    /**
     * Sets an explicit FOEventHandler instance which overrides the one
     * defined by the render type setting.
     * @param handler the FOEventHandler instance
     */
    public void setFOEventHandlerOverride(FOEventHandler handler) {
        this.foEventHandlerOverride = handler;
    }

    /**
     * Returns the overriding FOEventHandler instance, if any.
     * @return the overriding FOEventHandler or null
     */
    public FOEventHandler getFOEventHandlerOverride() {
        return this.foEventHandlerOverride;
    }

    /**
     * Sets the producer of the document.
     * @param producer source of document
     */
    public void setProducer(String producer) {
        this.producer = producer;
    }

    /**
     * Returns the producer of the document
     * @return producer name
     */
    public String getProducer() {
        return producer;
    }

    /**
     * Sets the creator of the document.
     * @param creator of document
     */
    public void setCreator(String creator) {
        this.creator = creator;
    }

    /**
     * Returns the creator of the document
     * @return creator name
     */
    public String getCreator() {
        return creator;
    }

    /**
     * Sets the creation date of the document.
     * @param creationDate date of document
     */
    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    /**
     * Returns the creation date of the document
     * @return creation date of document
     */
    public Date getCreationDate() {
        return creationDate;
    }

    /**
     * Sets the author of the document.
     * @param author of document
     */
    public void setAuthor(String author) {
        this.author = author;
    }

    /**
     * Returns the author of the document
     * @return author name
     */
    public String getAuthor() {
        return author;
    }

    /**
     * Sets the title of the document. This will override any title coming from
     * an fo:title element.
     * @param title of document
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * Returns the title of the document
     * @return title name
     */
    public String getTitle() {
        return title;
    }

    /**
     * Sets the subject of the document.
     * @param subject of document
     */
    public void setSubject(String subject) {
        this.subject = subject;
    }

    /**
     * Returns the subject of the document
     * @return the subject
     */
    public String getSubject() {
        return subject;
    }

    /**
     * Sets the keywords for the document.
     * @param keywords for the document
     */
    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    /**
     * Returns the keywords for the document
     * @return the keywords
     */
    public String getKeywords() {
        return keywords;
    }

    /**
     * Returns the renderer options
     * @return renderer options
     */
    public Map getRendererOptions() {
        return rendererOptions;
    }

    /**
     * Gets the renderer options given an interface representing renderer configuration options.
     *
     * @param option the renderer option
     * @return the value
    */
    public Object getRendererOption(RendererConfigOption option) {
        return rendererOptions.get(option.getName());
    }

    /**
     * Attempts to resolve the given URI.
     * Will use the configured resolver and if not successful fall back
     * to the default resolver.
     * @param uri URI to access
     * @return A {@link javax.xml.transform.Source} object, or null if the URI
     * cannot be resolved.
     */
    public StreamSource resolveURI(String uri) {
        // TODO: What do we want to do when resources aren't found??? We also need to remove this
        // method entirely
        try {
            // Have to do this so we can resolve data URIs
            StreamSource src = new StreamSource(resourceResolver.getResource(uri));
            src.setSystemId(uri);
            return src;
        } catch (URISyntaxException use) {
            return null;
        } catch (IOException ioe) {
            return null;
        }
    }

    /**
     * Sets the output File.
     * @param f the output File
     */
    public void setOutputFile(File f) {
        this.outputFile = f;
    }

    /**
     * Gets the output File.
     * @return the output File
     */
    public File getOutputFile() {
        return outputFile;
    }

    /**
     * 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 UnitConv.IN2MM / this.targetResolution;
    }

    /** @return the resolution for resolution-dependant output */
    public float getTargetResolution() {
        return this.targetResolution;
    }

    /**
     * Sets the target resolution in dpi. This value defines the target resolution of
     * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
     * bitmap images generated by filter effects in Apache Batik.
     * @param dpi resolution in dpi
     */
    public void setTargetResolution(float dpi) {
        this.targetResolution = dpi;
        if (log.isDebugEnabled()) {
            log.debug("target-resolution set to: " + targetResolution
                    + "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")");
        }
    }

    /**
     * Sets the target resolution in dpi. This value defines the target resolution of
     * bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of
     * bitmap images generated by filter effects in Apache Batik.
     * @param dpi resolution in dpi
     */
    public void setTargetResolution(int dpi) {
        setTargetResolution((float)dpi);
    }

    /**
     * Returns the image session context for the image package.
     * @return the ImageSessionContext instance for this rendering run
     */
    public ImageSessionContext getImageSessionContext() {
        return this.imageSessionContext;
    }

    // ---------------------------------------------- environment-level stuff
    //                                                (convenience access to FopFactory methods)

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

    /** @return the resolution for resolution-dependant input */
    public float getSourceResolution() {
        return factory.getSourceResolution();
    }

    /**
     * Gets the default page-height to use as fallback,
     * in case page-height="auto"
     *
     * @return the page-height, as a String
     * @see FopFactory#getPageHeight()
     */
    public String getPageHeight() {
        return factory.getPageHeight();
    }

    /**
     * Gets the default page-width to use as fallback,
     * in case page-width="auto"
     *
     * @return the page-width, as a String
     * @see FopFactory#getPageWidth()
     */
    public String getPageWidth() {
        return factory.getPageWidth();
    }

    /**
     * Returns whether FOP is strictly validating input XSL
     * @return true of strict validation turned on, false otherwise
     * @see FopFactory#validateStrictly()
     */
    public boolean validateStrictly() {
        return factory.validateStrictly();
    }

    /**
     * @return true if the indent inheritance should be broken when crossing reference area
     *         boundaries (for more info, see the javadoc for the relative member variable)
     * @see FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()
     */
    public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
        return factory.isBreakIndentInheritanceOnReferenceAreaBoundary();
    }

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

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

    /**
     * Controls the use of SAXLocators to provide location information in error
     * messages.
     *
     * @param enableLocator <code>false</code> if SAX Locators should be disabled
     */
    public void setLocatorEnabled(boolean enableLocator) {
        locatorEnabled = enableLocator;
    }

    /**
     * Checks if the use of Locators is enabled
     * @return true if context information should be stored on each node in the FO tree.
     */
    public boolean isLocatorEnabled() {
        return locatorEnabled;
    }

    /**
     * Returns the event broadcaster that control events sent inside a processing run. Clients
     * can register event listeners with the event broadcaster to listen for events that occur
     * while a document is being processed.
     * @return the event broadcaster.
     */
    public EventBroadcaster getEventBroadcaster() {
        return this.eventBroadcaster;
    }

    public boolean isPdfUAEnabled() {
        return pdfUAEnabled;
    }

    public void setPdfUAEnabled(boolean pdfUAEnabled) {
        this.pdfUAEnabled = pdfUAEnabled;
    }

    private class FOPEventBroadcaster extends DefaultEventBroadcaster {

        private EventListener rootListener;

        public FOPEventBroadcaster() {
            //Install a temporary event listener that catches the first event to
            //do some initialization.
            this.rootListener = new EventListener() {
                public void processEvent(Event event) {
                    if (!listeners.hasEventListeners()) {
                        //Backwards-compatibility: Make sure at least the LoggingEventListener is
                        //plugged in so no events are just silently swallowed.
                        addEventListener(
                                new LoggingEventListener(LogFactory.getLog(FOUserAgent.class)));
                    }
                    //Replace with final event listener
                    rootListener = new FOPEventListenerProxy(
                            listeners, FOUserAgent.this);
                    rootListener.processEvent(event);
                }
            };
        }

        /** {@inheritDoc} */
        public void broadcastEvent(Event event) {
            rootListener.processEvent(event);
        }

    }

    /**
     * Check whether memory-conservation is enabled.
     *
     * @return true if FOP is to conserve as much as possible
     */
    public boolean isConserveMemoryPolicyEnabled() {
        return this.conserveMemoryPolicy;
    }

    /**
     * Control whether memory-conservation should be enabled
     *
     * @param conserveMemoryPolicy the cachingEnabled to set
     */
    public void setConserveMemoryPolicy(boolean conserveMemoryPolicy) {
        this.conserveMemoryPolicy = conserveMemoryPolicy;
    }

    /**
     * Check whether complex script features are enabled.
     *
     * @return true if FOP is to use complex script features
     */
    public boolean isComplexScriptFeaturesEnabled() {
        return factory.isComplexScriptFeaturesEnabled();
    }

    /**
     * Returns the renderer configuration object for a particular MIME type.
     *
     * @param mimeType the config MIME type
     * @param configCreator the parser for creating the config for the first run of parsing.
     * @return the renderer configuration object
     * @throws FOPException if an error occurs when creating the config object
     */
    public RendererConfig getRendererConfig(String mimeType, RendererConfigParser configCreator)
            throws FOPException {
        return factory.getRendererConfig(this, getRendererConfiguration(mimeType), configCreator);
    }

    /**
     * Returns a {@link Configuration} object for which contains renderer configuration for a given
     * MIME type.
     *
     * @param mimeType the renderer configuration MIME type
     * @return the configuration object
     */
    public Configuration getRendererConfiguration(String mimeType) {
        Configuration cfg = getUserConfig();
        String type = "renderer";
        String mime = "mime";
        if (cfg == null) {
            if (log.isDebugEnabled()) {
                log.debug("userconfig is null");
            }
            return null;
        }

        Configuration userConfig = null;

        Configuration[] cfgs = cfg.getChild(type + "s").getChildren(type);
        for (int i = 0; i < cfgs.length; ++i) {
            Configuration child = cfgs[i];
            try {
                if (child.getAttribute(mime).equals(mimeType)) {
                    userConfig = child;
                    break;
                }
            } catch (ConfigurationException e) {
                // silently pass over configurations without mime type
            }
        }
        log.debug((userConfig == null ? "No u" : "U")
                + "ser configuration found for MIME type " + mimeType);
        return userConfig;
    }

    /**
     * Activates accessibility (for output formats that support it).
     *
     * @param accessibility <code>true</code> to enable accessibility support
     */
    public void setAccessibility(boolean accessibility) {
        if (accessibility) {
            getRendererOptions().put(Accessibility.ACCESSIBILITY, Boolean.TRUE);
        }
    }

    /**
     * Check if accessibility is enabled.
     * @return true if accessibility is enabled
     */
    public boolean isAccessibilityEnabled() {
        Boolean enabled = (Boolean)this.getRendererOptions().get(Accessibility.ACCESSIBILITY);
        if (enabled != null) {
            return enabled.booleanValue();
        } else {
            return false;
        }
    }

    /**
     * Sets the document's structure tree event handler, for use by accessible
     * output formats.
     *
     * @param structureTreeEventHandler The structure tree event handler to set
     */
    public void setStructureTreeEventHandler(StructureTreeEventHandler structureTreeEventHandler) {
        this.structureTreeEventHandler = structureTreeEventHandler;
    }

    /**
     * Returns the document's structure tree event handler, for use by
     * accessible output formats.
     *
     * @return The structure tree event handler
     */
    public StructureTreeEventHandler getStructureTreeEventHandler() {
        return this.structureTreeEventHandler;
    }

    /** @see FopFactory#getLayoutManagerMakerOverride() */
    public LayoutManagerMaker getLayoutManagerMakerOverride() {
        return factory.getLayoutManagerMakerOverride();
    }

    /** @see FopFactory#getContentHandlerFactoryRegistry() */
    public ContentHandlerFactoryRegistry getContentHandlerFactoryRegistry() {
        return factory.getContentHandlerFactoryRegistry();
    }

    /** @see FopFactory#getImageManager() */
    public ImageManager getImageManager() {
        return factory.getImageManager();
    }

    /** @see FopFactory#getElementMappingRegistry() */
    public ElementMappingRegistry getElementMappingRegistry() {
        return factory.getElementMappingRegistry();
    }

    /** @see FopFactory#getFontManager() */
    public FontManager getFontManager() {
        return factory.getFontManager();
    }

    /**
     * Indicates whether a namespace URI is on the ignored list.
     * @param namespaceURI the namespace URI
     * @return true if the namespace is ignored by FOP
     */
    public boolean isNamespaceIgnored(String namespaceURI) {
        return factory.isNamespaceIgnored(namespaceURI);
    }

    /**
     * Is the user configuration to be validated?
     * @return if the user configuration should be validated
     */
    public boolean validateUserConfigStrictly() {
        return factory.validateUserConfigStrictly();
    }

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

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

    /** @return the color space cache */
    public ColorSpaceCache getColorSpaceCache() {
        return factory.getColorSpaceCache();
    }

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

    public SoftMapCache getPDFObjectCache() {
        return pdfObjectCache;
    }
}
