/*
 * 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.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.avalon.framework.configuration.Configuration;

import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageManager;

import org.apache.fop.apps.io.ResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.layoutmgr.LayoutManagerMaker;

/**
 * This is the builder class for {@link FopFactory}. Setters can be chained to
 * make building a {@link FopFactory} object more concise and intuitive e.g.
 *
 * <pre>
 * {@code
 * FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder(<URI>)
 *                                                  .setURIResolver(<URIResolver>)
 *                                                  .setPageHeight(<String>)
 *                                                  .setPageWidth(<String>)
 *                                                  .setStrictUserConfigValidation(<boolean>)
 *                                                    ... etc ...
 * FopFactory fopFactory = fopFactoryBuilder.build();
 * }
 * </pre>
 */
public final class FopFactoryBuilder {

    private final FopFactoryConfig config;

    private FopFactoryConfigBuilder fopFactoryConfigBuilder;

    /**
     * A builder class for {@link FopFactory} which can be used for setting configuration. This is
     * a helper constructor that uses the default URI resolver implementation that FOP packages
     * provide ({@link org.apache.fop.apps.io.ResourceResolverFactory.DefaultResourceResolver}).
     *
     * @param defaultBaseURI the default base URI for resolving URIs against
     */
    public FopFactoryBuilder(URI defaultBaseURI) {
        this(defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver());
    }

    /**
     * A builder class for {@link FopFactory} which can be used for setting configuration.
     *
     * @param defaultBaseURI the default base URI for resolving URIs against
     * @param resourceResolver the URI resolver
     */
    public FopFactoryBuilder(URI defaultBaseURI, ResourceResolver resourceResolver) {
        this(EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver));
    }

    /**
     * A builder class for {@link FopFactory} which can be used for setting configuration.
     *
     * @param enviro the profile of the FOP deployment environment
     */
    public FopFactoryBuilder(EnvironmentProfile enviro) {
        config = new FopFactoryConfigImpl(enviro);
        fopFactoryConfigBuilder = new ActiveFopFactoryConfigBuilder((FopFactoryConfigImpl) config);
    }

    /**
     * Returns the {@link FopFactoryConfig} which is needed to get an instance of
     * {@link FopFactory}.
     *
     * @return build the {@link FopFactoryConfig}
     * @deprecated Exposing the {@link FopFactoryConfig} is only to maintain backwards compatibility
     */
    public FopFactoryConfig buildConfig() {
        return buildConfiguration();
    }

    /**
     * Builds the configuration object used by the FopFactory.
     *
     * @return the config for the {@link FopFactory}
     */
    // The {@link FopFactoryConfig} doesn't need to be exposed in the "public" API, this method
    // should remain package private.
    FopFactoryConfig buildConfiguration() {
        fopFactoryConfigBuilder = CompletedFopFactoryConfigBuilder.INSTANCE;
        return config;
    }

    /**
     * Builds an instance of the the {@link FopFactory}.
     *
     * @return the FopFactory instance
     */
    public FopFactory build() {
        return FopFactory.newInstance(buildConfiguration());
    }

    /**
     * Gets the base URI used to resolve all URIs within FOP.
     *
     * @return the base URI
     */
    URI getBaseURI() {
        return config.getBaseURI();
    }

    /**
     * Returns the {@link FontManager} used for managing the fonts within FOP.
     *
     * @return the font managing object
     */
    public FontManager getFontManager() {
        return config.getFontManager();
    }

    /**
     * Return the {@link ImageManager} used for handling images through out FOP.
     *
     * @return the image manager
     */
    public ImageManager getImageManager() {
        return config.getImageManager();
    }

    /**
     * Sets whether to include accessibility features in document creation.
     *
     * @param enableAccessibility true to set accessibility on
     * @return <code>this</code>
     */
    public FopFactoryBuilder setAccessibility(boolean enableAccessibility) {
        fopFactoryConfigBuilder.setAccessibility(enableAccessibility);
        return this;
    }

    /**
     * Sets the {@link LayoutManagerMaker} so that users can configure how FOP creates
     * {@link org.apache.fop.layoutmgr.LayoutManager}s.
     *
     * @param lmMaker he layout manager maker
     * @return <code>this</code>
     */
    public FopFactoryBuilder setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
        fopFactoryConfigBuilder.setLayoutManagerMakerOverride(lmMaker);
        return this;
    }

    /**
     * Sets the base URI, this will be used for resolving all URIs given to FOP.
     *
     * @param baseURI the base URI
     * @return <code>this</code>
     */
    public FopFactoryBuilder setBaseURI(URI baseURI) {
        fopFactoryConfigBuilder.setBaseURI(baseURI);
        return this;
    }

    /**
     * Sets whether to perform strict validation on the FO used.
     *
     * @param validateStrictly true if the FO is to be strictly validated
     * @return <code>this</code>
     */
    public FopFactoryBuilder setStrictFOValidation(boolean validateStrictly) {
        fopFactoryConfigBuilder.setStrictFOValidation(validateStrictly);
        return this;
    }

    /**
     * Sets whether to perform strict alidation on the user-configuration.
     *
     * @param validateStrictly true if the fop conf is to be strictly validated
     * @return <code>this</code>
     */
    public FopFactoryBuilder setStrictUserConfigValidation(
            boolean validateStrictly) {
        fopFactoryConfigBuilder.setStrictUserConfigValidation(validateStrictly);
        return this;
    }

    /**
     * Sets whether the indent inheritance should be broken when crossing reference area boundaries.
     *
     * @param value true to break inheritance when crossing reference area boundaries
     * @return <code>this</code>
     */
    public FopFactoryBuilder setBreakIndentInheritanceOnReferenceAreaBoundary(
            boolean value) {
        fopFactoryConfigBuilder.setBreakIndentInheritanceOnReferenceAreaBoundary(value);
        return this;
    }

    /**
     * Sets the resolution of resolution-dependent input.
     *
     * @param dpi the source resolution
     * @return <code>this</code>
     */
    public FopFactoryBuilder setSourceResolution(float dpi) {
        fopFactoryConfigBuilder.setSourceResolution(dpi);
        return this;
    }

    /**
     * Sets the resolution of resolution-dependent output.
     *
     * @param dpi the target resolution
     * @return <code>this</code>
     */
    public FopFactoryBuilder setTargetResolution(float dpi) {
        fopFactoryConfigBuilder.setTargetResolution(dpi);
        return this;
    }

    /**
     * Sets the page height of the paginated output.
     *
     * @param pageHeight the page height
     * @return <code>this</code>
     */
    public FopFactoryBuilder setPageHeight(String pageHeight) {
        fopFactoryConfigBuilder.setPageHeight(pageHeight);
        return this;
    }

    /**
     * Sets the page width of the paginated output.
     *
     * @param pageWidth the page width
     * @return <code>this</code>
     */
    public FopFactoryBuilder setPageWidth(String pageWidth) {
        fopFactoryConfigBuilder.setPageWidth(pageWidth);
        return this;
    }

    /**
     * FOP will ignore the specified XML element namespace.
     *
     * @param namespaceURI the namespace URI to ignore
     * @return <code>this</code>
     */
    public FopFactoryBuilder ignoreNamespace(String namespaceURI) {
        fopFactoryConfigBuilder.ignoreNamespace(namespaceURI);
        return this;
    }

    /**
     * FOP will ignore the colletion of XML element namespaces.
     *
     * @param namespaceURIs a collection of namespace URIs to ignore
     * @return <code>this</code>
     */
    public FopFactoryBuilder ignoreNamespaces(Collection<String> namespaceURIs) {
        fopFactoryConfigBuilder.ignoreNamespaces(namespaceURIs);
        return this;
    }

    /**
     * Sets the Avalon configuration if a FOP conf is used.
     *
     * @param cfg the fop conf configuration
     * @return <code>this</code>
     */
    public FopFactoryBuilder setConfiguration(Configuration cfg) {
        fopFactoryConfigBuilder.setConfiguration(cfg);
        return this;
    }

    /**
     * Sets whether to chose a {@link org.apache.fop.render.Renderer} in preference to an
     * {@link org.apache.fop.render.intermediate.IFDocumentHandler}.
     *
     * @param preferRenderer true to prefer {@link org.apache.fop.render.Renderer}
     * @return <code>this</code>
     */
    public FopFactoryBuilder setPreferRenderer(boolean preferRenderer) {
        fopFactoryConfigBuilder.setPreferRenderer(preferRenderer);
        return this;
    }

    public FopFactoryBuilder setComplexScriptFeatures(boolean csf) {
        fopFactoryConfigBuilder.setComplexScriptFeaturesEnabled(csf);
        return this;
    }

    public FopFactoryBuilder setHyphPatNames(Map<String, String> hyphPatNames) {
        fopFactoryConfigBuilder.setHyphPatNames(hyphPatNames);
        return this;
    }

    public static class FopFactoryConfigImpl implements FopFactoryConfig {

        private final EnvironmentProfile enviro;

        private final ImageManager imageManager;

        private boolean accessibility;

        private LayoutManagerMaker layoutManagerMaker;

        private URI baseURI;

        private boolean hasStrictFOValidation = true;

        private boolean hasStrictUserValidation = FopFactoryConfig.DEFAULT_STRICT_USERCONFIG_VALIDATION;

        private boolean breakIndentInheritanceOnReferenceBoundary
        = FopFactoryConfig.DEFAULT_BREAK_INDENT_INHERITANCE;

        private float sourceResolution = FopFactoryConfig.DEFAULT_SOURCE_RESOLUTION;

        private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;

        private String pageHeight = FopFactoryConfig.DEFAULT_PAGE_HEIGHT;

        private String pageWidth = FopFactoryConfig.DEFAULT_PAGE_WIDTH;

        private Set<String> ignoredNamespaces = new HashSet<String>();

        private Configuration cfg;

        private boolean preferRenderer;

        private boolean isComplexScript = true;

        private Map<String, String> hyphPatNames;

        private static final class ImageContextImpl implements ImageContext {

            private final FopFactoryConfig config;

            ImageContextImpl(FopFactoryConfig config) {
                this.config = config;
            }

            public float getSourceResolution() {
                return config.getSourceResolution();
            }
        }

        FopFactoryConfigImpl(EnvironmentProfile enviro) {
            this.enviro = enviro;
            this.baseURI = enviro.getDefaultBaseURI();
            this.imageManager = new ImageManager(new ImageContextImpl(this));
        }

        /** {@inheritDoc} */
        public boolean isAccessibilityEnabled() {
            return accessibility;
        }

        /** {@inheritDoc} */
        public LayoutManagerMaker getLayoutManagerMakerOverride() {
            return layoutManagerMaker;
        }

        /** {@inheritDoc} */
        public ResourceResolver getResourceResolver() {
            return enviro.getResourceResolver();
        }

        /** {@inheritDoc} */
        public URI getBaseURI() {
            return baseURI;
        }

        /** {@inheritDoc} */
        public boolean validateStrictly() {
            return hasStrictFOValidation;
        }

        /** {@inheritDoc} */
        public boolean validateUserConfigStrictly() {
            return hasStrictUserValidation;
        }

        /** {@inheritDoc} */
        public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
            return breakIndentInheritanceOnReferenceBoundary;
        }

        /** {@inheritDoc} */
        public float getSourceResolution() {
            return sourceResolution;
        }

        /** {@inheritDoc} */
        public float getTargetResolution() {
            return targetResolution;
        }

        /** {@inheritDoc} */
        public String getPageHeight() {
            return pageHeight;
        }

        /** {@inheritDoc} */
        public String getPageWidth() {
            return pageWidth;
        }

        /** {@inheritDoc} */
        public Set<String> getIgnoredNamespaces() {
            return Collections.unmodifiableSet(ignoredNamespaces);
        }

        /** {@inheritDoc} */
        public boolean isNamespaceIgnored(String namespace) {
            return ignoredNamespaces.contains(namespace);
        }

        /** {@inheritDoc} */
        public Configuration getUserConfig() {
            return cfg;
        }

        /** {@inheritDoc} */
        public boolean preferRenderer() {
            return preferRenderer;
        }

        /** {@inheritDoc} */
        public FontManager getFontManager() {
            return enviro.getFontManager();
        }

        /** {@inheritDoc} */
        public ImageManager getImageManager() {
            return imageManager;
        }

        public boolean isComplexScriptFeaturesEnabled() {
            return isComplexScript;
        }

        public Map<String, String> getHyphenationPatternNames() {
            return hyphPatNames;
        }
    }

    private interface FopFactoryConfigBuilder {

        void setAccessibility(boolean enableAccessibility);

        void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker);

        void setBaseURI(URI baseURI);

        void setStrictFOValidation(boolean validateStrictly);

        void setStrictUserConfigValidation(boolean validateStrictly);

        void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value);

        void setSourceResolution(float dpi);

        void setTargetResolution(float dpi);

        void setPageHeight(String pageHeight);

        void setPageWidth(String pageWidth);

        void ignoreNamespace(String namespaceURI);

        void ignoreNamespaces(Collection<String> namespaceURIs);

        void setConfiguration(Configuration cfg);

        void setPreferRenderer(boolean preferRenderer);

        void setComplexScriptFeaturesEnabled(boolean csf);

        void setHyphPatNames(Map<String, String> hyphPatNames);
    }

    private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {

        private static final CompletedFopFactoryConfigBuilder INSTANCE
        = new CompletedFopFactoryConfigBuilder();

        private void throwIllegalStateException() {
            throw new IllegalStateException("The final FOP Factory configuration has already been built");
        }

        public void setAccessibility(boolean enableAccessibility) {
            throwIllegalStateException();
        }

        public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
            throwIllegalStateException();

        }

        public void setBaseURI(URI baseURI) {
            throwIllegalStateException();
        }

        public void setStrictFOValidation(boolean validateStrictly) {
            throwIllegalStateException();
        }

        public void setStrictUserConfigValidation(boolean validateStrictly) {
            throwIllegalStateException();
        }

        public void setBreakIndentInheritanceOnReferenceAreaBoundary(
                boolean value) {
            throwIllegalStateException();
        }

        public void setSourceResolution(float dpi) {
            throwIllegalStateException();
        }

        public void setTargetResolution(float dpi) {
            throwIllegalStateException();
        }

        public void setPageHeight(String pageHeight) {
            throwIllegalStateException();
        }

        public void setPageWidth(String pageWidth) {
            throwIllegalStateException();
        }

        public void ignoreNamespace(String namespaceURI) {
            throwIllegalStateException();
        }

        public void ignoreNamespaces(Collection<String> namespaceURIs) {
            throwIllegalStateException();
        }

        public void setConfiguration(Configuration cfg) {
            throwIllegalStateException();
        }

        public void setPreferRenderer(boolean preferRenderer) {
            throwIllegalStateException();
        }

        public void setComplexScriptFeaturesEnabled(boolean csf) {
            throwIllegalStateException();
        }

        public void setHyphPatNames(Map<String, String> hyphPatNames) {
            throwIllegalStateException();
        }

    }

    private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {

        private final FopFactoryConfigImpl config;

        private ActiveFopFactoryConfigBuilder(FopFactoryConfigImpl config) {
            this.config = config;
        }

        public void setAccessibility(boolean enableAccessibility) {
            config.accessibility = enableAccessibility;
        }

        public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
            config.layoutManagerMaker = lmMaker;
        }

        public void setBaseURI(URI baseURI) {
            config.baseURI = baseURI;
        }

        public void setStrictFOValidation(boolean validateStrictly) {
            config.hasStrictFOValidation = validateStrictly;
        }

        public void setStrictUserConfigValidation(
                boolean validateStrictly) {
            config.hasStrictUserValidation = validateStrictly;
        }

        public void setBreakIndentInheritanceOnReferenceAreaBoundary(
                boolean value) {
            config.breakIndentInheritanceOnReferenceBoundary = value;
        }

        public void setSourceResolution(float dpi) {
            config.sourceResolution = dpi;
        }

        public void setTargetResolution(float dpi) {
            config.targetResolution = dpi;
        }

        public void setPageHeight(String pageHeight) {
            config.pageHeight = pageHeight;
        }

        public void setPageWidth(String pageWidth) {
            config.pageWidth = pageWidth;
        }

        public void ignoreNamespace(String namespaceURI) {
            config.ignoredNamespaces.add(namespaceURI);
        }

        public void ignoreNamespaces(
                Collection<String> namespaceURIs) {
            config.ignoredNamespaces.addAll(namespaceURIs);
        }

        public void setConfiguration(Configuration cfg) {
            config.cfg = cfg;
        }

        public void setPreferRenderer(boolean preferRenderer) {
            config.preferRenderer = preferRenderer;
        }

        public void setComplexScriptFeaturesEnabled(boolean csf) {
            config.isComplexScript = csf;
        }

        public void setHyphPatNames(Map<String, String> hyphPatNames) {
            config.hyphPatNames = hyphPatNames;
        }
    }

}
