/*
 * 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.xmlgraphics.image.loader;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.xml.transform.Source;

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

import org.apache.xmlgraphics.image.loader.cache.ImageCache;
import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline;
import org.apache.xmlgraphics.image.loader.pipeline.PipelineFactory;
import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
import org.apache.xmlgraphics.image.loader.spi.ImagePreloader;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.image.loader.util.Penalty;
import org.apache.xmlgraphics.io.XmlSourceUtil;

/**
 * ImageManager is the central starting point for image access.
 */
public class ImageManager {

    /** logger */
    protected static final Log log = LogFactory.getLog(ImageManager.class);

    /** Holds all registered interface implementations for the image package */
    private ImageImplRegistry registry;

    /** Provides session-independent information */
    private ImageContext imageContext;

    /** The image cache for this instance */
    private ImageCache cache = new ImageCache();

    private PipelineFactory pipelineFactory = new PipelineFactory(this);

    /**
     * Main constructor.
     * @param context the session-independent context information
     */
    public ImageManager(ImageContext context) {
        this(ImageImplRegistry.newInstance(), context);
    }

    /**
     * Constructor for testing purposes.
     * @param registry the implementation registry with all plug-ins
     * @param context the session-independent context information
     */
    public ImageManager(ImageImplRegistry registry, ImageContext context) {
        this.registry = registry;
        this.imageContext = context;
    }

    /**
     * Returns the ImageImplRegistry in use by the ImageManager.
     * @return the ImageImplRegistry
     */
    public ImageImplRegistry getRegistry() {
        return this.registry;
    }

    /**
     * Returns the ImageContext in use by the ImageManager.
     * @return the ImageContext
     */
    public ImageContext getImageContext() {
        return this.imageContext;
    }

    /**
     * Returns the ImageCache in use by the ImageManager.
     * @return the ImageCache
     */
    public ImageCache getCache() {
        return this.cache;
    }

    /**
     * Returns the PipelineFactory in use by the ImageManager.
     * @return the PipelineFactory
     */
    public PipelineFactory getPipelineFactory() {
        return this.pipelineFactory;
    }

    /**
     * Returns an ImageInfo object containing its intrinsic size for a given URI. The ImageInfo
     * is retrieved from an image cache if it has been requested before.
     * @param uri the URI of the image
     * @param session the session context through which to resolve the URI if the image is not in
     *                the cache
     * @return the ImageInfo object created from the image
     * @throws ImageException If no suitable ImagePreloader can be found to load the image or
     *          if an error occurred while preloading the image.
     * @throws IOException If an I/O error occurs while preloading the image
     */
    public ImageInfo getImageInfo(String uri, ImageSessionContext session)
                throws ImageException, IOException {
        if (getCache() != null) {
            return getCache().needImageInfo(uri, session, this);
        } else {
            return preloadImage(uri, session);
        }
    }

    /**
     * Preloads an image, i.e. the format of the image is identified and some basic information
     * (MIME type, intrinsic size and possibly other values) are loaded and returned as an
     * ImageInfo object. Note that the image is not fully loaded normally. Only with certain formats
     * the image is already fully loaded and references added to the ImageInfo's custom objects
     * (see {@link ImageInfo#getOriginalImage()}).
     * <p>
     * The reason for the preloading: Apache FOP, for example, only needs the image's intrinsic
     * size during layout. Only when the document is rendered to the final format does FOP need
     * to load the full image. Like this a lot of memory can be saved.
     * @param uri the original URI of the image
     * @param session the session context through which to resolve the URI
     * @return the ImageInfo object created from the image
     * @throws ImageException If no suitable ImagePreloader can be found to load the image or
     *          if an error occurred while preloading the image.
     * @throws IOException If an I/O error occurs while preloading the image
     */
    public ImageInfo preloadImage(String uri, ImageSessionContext session)
            throws ImageException, IOException {
        Source src = session.needSource(uri);
        ImageInfo info = preloadImage(uri, src);
        session.returnSource(uri, src);
        return info;
    }

    /**
     * Preloads an image, i.e. the format of the image is identified and some basic information
     * (MIME type, intrinsic size and possibly other values) are loaded and returned as an
     * ImageInfo object. Note that the image is not fully loaded normally. Only with certain formats
     * the image is already fully loaded and references added to the ImageInfo's custom objects
     * (see {@link ImageInfo#getOriginalImage()}).
     * <p>
     * The reason for the preloading: Apache FOP, for example, only needs the image's intrinsic
     * size during layout. Only when the document is rendered to the final format does FOP need
     * to load the full image. Like this a lot of memory can be saved.
     * @param uri the original URI of the image
     * @param src the Source object to load the image from
     * @return the ImageInfo object created from the image
     * @throws ImageException If no suitable ImagePreloader can be found to load the image or
     *          if an error occurred while preloading the image.
     * @throws IOException If an I/O error occurs while preloading the image
     */
    public ImageInfo preloadImage(String uri, Source src)
            throws ImageException, IOException {
        Iterator iter = registry.getPreloaderIterator();
        while (iter.hasNext()) {
            ImagePreloader preloader = (ImagePreloader) iter.next();
            ImageInfo info = preloader.preloadImage(uri, src, imageContext);
            if (info != null) {
                return info;
            }
        }
        throw new ImageException("The file format is not supported. No ImagePreloader found for "
                + uri);
    }

    private Map prepareHints(Map hints, ImageSessionContext sessionContext) {
        Map newHints = new java.util.HashMap();
        if (hints != null) {
            newHints.putAll(hints); //Copy in case an unmodifiable map is passed in
        }
        if (!newHints.containsKey(ImageProcessingHints.IMAGE_SESSION_CONTEXT)
                && sessionContext != null) {
            newHints.put(ImageProcessingHints.IMAGE_SESSION_CONTEXT, sessionContext);

        }
        if (!newHints.containsKey(ImageProcessingHints.IMAGE_MANAGER)) {
            newHints.put(ImageProcessingHints.IMAGE_MANAGER, this);
        }
        return newHints;
    }

    /**
     * Loads an image. The caller can indicate what kind of image flavor is requested. When this
     * method is called the code looks for a suitable ImageLoader and, if necessary, builds
     * a conversion pipeline so it can return the image in exactly the form the caller needs.
     * <p>
     * Optionally, it is possible to pass in Map of hints. These hints may be used by ImageLoaders
     * and ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints
     * used by the bundled implementations. You can, of course, define your own hints.
     * @param info the ImageInfo instance for the image (obtained by
     *                  {@link #getImageInfo(String, ImageSessionContext)})
     * @param flavor the requested image flavor.
     * @param hints a Map of hints to any of the background components or null
     * @param session the session context
     * @return the fully loaded image
     * @throws ImageException If no suitable loader/converter combination is available to fulfill
     *                  the request or if an error occurred while loading the image.
     * @throws IOException If an I/O error occurs
     */
    public Image getImage(ImageInfo info, ImageFlavor flavor, Map hints,
                ImageSessionContext session)
            throws ImageException, IOException {
        hints = prepareHints(hints, session);

        Image img = null;
        ImageProviderPipeline pipeline = getPipelineFactory().newImageConverterPipeline(
                info, flavor);
        if (pipeline != null) {
            img = pipeline.execute(info, hints, session);
        }
        if (img == null) {
            throw new ImageException(
                    "Cannot load image (no suitable loader/converter combination available) for "
                        + info);
        }
        XmlSourceUtil.closeQuietly(session.getSource(info.getOriginalURI()));
        return img;
    }

    /**
     * Loads an image. The caller can indicate what kind of image flavors are requested. When this
     * method is called the code looks for a suitable ImageLoader and, if necessary, builds
     * a conversion pipeline so it can return the image in exactly the form the caller needs.
     * The array of image flavors is ordered, so the first image flavor is given highest priority.
     * <p>
     * Optionally, it is possible to pass in Map of hints. These hints may be used by ImageLoaders
     * and ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints
     * used by the bundled implementations. You can, of course, define your own hints.
     * @param info the ImageInfo instance for the image (obtained by
     *                  {@link #getImageInfo(String, ImageSessionContext)})
     * @param flavors the requested image flavors (in preferred order).
     * @param hints a Map of hints to any of the background components or null
     * @param session the session context
     * @return the fully loaded image
     * @throws ImageException If no suitable loader/converter combination is available to fulfill
     *                  the request or if an error occurred while loading the image.
     * @throws IOException If an I/O error occurs
     */
    public Image getImage(ImageInfo info, ImageFlavor[] flavors, Map hints,
                        ImageSessionContext session)
                throws ImageException, IOException {
        hints = prepareHints(hints, session);

        Image img = null;
        ImageProviderPipeline[] candidates = getPipelineFactory().determineCandidatePipelines(
                info, flavors);
        ImageProviderPipeline pipeline = choosePipeline(candidates);

        if (pipeline != null) {
            img = pipeline.execute(info, hints, session);
        }
        if (img == null) {
            throw new ImageException(
                    "Cannot load image (no suitable loader/converter combination available) for "
                            + info);
        }
        XmlSourceUtil.closeQuietly(session.getSource(info.getOriginalURI()));
        return img;
    }

    /**
     * Loads an image with no hints. See
     * {@link #getImage(ImageInfo, ImageFlavor, Map, ImageSessionContext)} for more
     * information.
     * @param info the ImageInfo instance for the image (obtained by
     *                  {@link #getImageInfo(String, ImageSessionContext)})
     * @param flavor the requested image flavor.
     * @param session the session context
     * @return the fully loaded image
     * @throws ImageException If no suitable loader/converter combination is available to fulfill
     *                  the request or if an error occurred while loading the image.
     * @throws IOException If an I/O error occurs
     */
    public Image getImage(ImageInfo info, ImageFlavor flavor, ImageSessionContext session)
            throws ImageException, IOException {
        return getImage(info, flavor, ImageUtil.getDefaultHints(session), session);
    }

    /**
     * Loads an image with no hints. See
     * {@link #getImage(ImageInfo, ImageFlavor[], Map, ImageSessionContext)} for more
     * information.
     * @param info the ImageInfo instance for the image (obtained by
     *                  {@link #getImageInfo(String, ImageSessionContext)})
     * @param flavors the requested image flavors (in preferred order).
     * @param session the session context
     * @return the fully loaded image
     * @throws ImageException If no suitable loader/converter combination is available to fulfill
     *                  the request or if an error occurred while loading the image.
     * @throws IOException If an I/O error occurs
     */
    public Image getImage(ImageInfo info, ImageFlavor[] flavors, ImageSessionContext session)
            throws ImageException, IOException {
        return getImage(info, flavors, ImageUtil.getDefaultHints(session), session);
    }

    /**
     * Closes the resources associated to the given image. This method should be
     * used only when none of the {@code getImage} methods is called by the
     * client application.
     *
     * @param uri the URI of the image
     * @param session the session context that was used to resolve the URI
     */
    public void closeImage(String uri, ImageSessionContext session) {
        XmlSourceUtil.closeQuietly(session.getSource(uri));
    }

    /**
     * Converts an image. The caller can indicate what kind of image flavors are requested. When
     * this method is called the code looks for a suitable combination of ImageConverters so it
     * can return the image in exactly the form the caller needs.
     * The array of image flavors is ordered, so the first image flavor is given highest priority.
     * <p>
     * Optionally, it is possible to pass in Map of hints. These hints may be used by
     * ImageConverters to act on the image. See {@link ImageProcessingHints} for common hints
     * used by the bundled implementations. You can, of course, define your own hints.
     * @param image the image to convert
     * @param flavors the requested image flavors (in preferred order).
     * @param hints a Map of hints to any of the background components or null
     * @return the fully loaded image
     * @throws ImageException If no suitable loader/converter combination is available to fulfill
     *                  the request or if an error occurred while loading the image.
     * @throws IOException If an I/O error occurs
     */
    public Image convertImage(Image image, ImageFlavor[] flavors, Map hints)
                throws ImageException, IOException {
        hints = prepareHints(hints, null);
        ImageInfo info = image.getInfo();

        Image img = null;
        for (ImageFlavor flavor : flavors) {
            if (image.getFlavor().equals(flavor)) {
                //Shortcut (the image is already in one of the requested formats)
                return image;
            }
        }
        ImageProviderPipeline[] candidates = getPipelineFactory().determineCandidatePipelines(
                image, flavors);
        ImageProviderPipeline pipeline = choosePipeline(candidates);

        if (pipeline != null) {
            img = pipeline.execute(info, image, hints, null);
        }
        if (img == null) {
            throw new ImageException(
                    "Cannot convert image " + image
                    + " (no suitable converter combination available)");
        }
        return img;
    }

    /**
     * Converts an image with no hints. See
     * {@link #convertImage(Image, ImageFlavor[], Map)} for more
     * information.
     * @param image the image to convert
     * @param flavors the requested image flavors (in preferred order).
     * @return the fully loaded image
     * @throws ImageException If no suitable loader/converter combination is available to fulfill
     *                  the request or if an error occurred while loading the image.
     * @throws IOException If an I/O error occurs
     */
    public Image convertImage(Image image, ImageFlavor[] flavors)
                throws ImageException, IOException {
        return convertImage(image, flavors, null);
    }

    /**
     * Chooses the best {@link ImageProviderPipeline} from a set of candidates.
     * @param candidates the candidates
     * @return the best pipeline
     */
    public ImageProviderPipeline choosePipeline(ImageProviderPipeline[] candidates) {
        ImageProviderPipeline pipeline = null;
        int minPenalty = Integer.MAX_VALUE;
        int count = candidates.length;
        if (log.isTraceEnabled()) {
            log.trace("Candidate Pipelines:");
            for (int i = 0; i < count; i++) {
                if (candidates[i] == null) {
                    continue;
                }
                log.trace("  " + i + ": "
                        + candidates[i].getConversionPenalty(getRegistry()) + " for " + candidates[i]);
            }
        }
        for (int i = count - 1; i >= 0; i--) {
            if (candidates[i] == null) {
                continue;
            }
            Penalty penalty = candidates[i].getConversionPenalty(getRegistry());
            if (penalty.isInfinitePenalty()) {
                continue; //Exclude candidate on infinite penalty
            }
            if (penalty.getValue() <= minPenalty) {
                pipeline = candidates[i];
                minPenalty = penalty.getValue();
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("Chosen pipeline: " + pipeline);
        }
        return pipeline;
    }

}
