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

import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;

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

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UnitProcessor;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.svg.SVGOMDocument;

import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader;
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.io.XmlSourceUtil;
import org.apache.xmlgraphics.util.MimeConstants;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.svg.SimpleSVGUserAgent;
import org.apache.fop.util.UnclosableInputStream;

/**
 * Image preloader for SVG images.
 */
public class PreloaderSVG extends AbstractImagePreloader {

    /** Logger instance */
    private static Log log = LogFactory.getLog(PreloaderSVG.class);

    private boolean batikAvailable = true;

    /** {@inheritDoc} */
    public ImageInfo preloadImage(String uri, Source src, ImageContext context)
            throws IOException {
        ImageInfo info = null;
        if (batikAvailable) {
            try {
                Loader loader = new Loader();
                if (!loader.isSupportedSource(src)) {
                    return null;
                }
                info = loader.getImage(uri, src, context);
            } catch (NoClassDefFoundError e) {
                batikAvailable = false;
                log.warn("Batik not in class path", e);
                return null;
            }
        }
        if (info != null) {
            XmlSourceUtil.closeQuietly(src); //Image is fully read
        }
        return info;
    }

    /**
     * Returns the fully qualified classname of an XML parser for
     * Batik classes that apparently need it (error messages, perhaps)
     * @return an XML parser classname
     */
    public static String getParserName() {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            return factory.newSAXParser().getXMLReader().getClass().getName();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * This method is put in another class so that the class loader does not
     * attempt to load Batik related classes when constructing the SVGPreloader
     * class.
     */
    private final class Loader {

        private Loader() {
        }

        private ImageInfo getImage(String uri, Source src,
                ImageContext context) {
            // parse document and get the size attributes of the svg element

            InputStream in = null;
            try {
                SVGDocument doc;
                if (src instanceof DOMSource) {
                    DOMSource domSrc = (DOMSource)src;
                    doc = (SVGDocument)domSrc.getNode();
                } else {
                    in = new UnclosableInputStream(XmlSourceUtil.needInputStream(src));
                    int length = in.available();
                    in.mark(length + 1);
                    SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
                            getParserName());
                    doc = factory.createSVGDocument(src.getSystemId(), in);
                }
                ImageInfo info = createImageInfo(uri, context, doc);

                return info;
            } catch (NoClassDefFoundError ncdfe) {
                if (in != null) {
                    try {
                        in.reset();
                    } catch (IOException ioe) {
                        // we're more interested in the original exception
                    }
                }
                batikAvailable = false;
                log.warn("Batik not in class path", ncdfe);
                return null;
            } catch (IOException e) {
                // If the svg is invalid then it throws an IOException
                // so there is no way of knowing if it is an svg document

                log.debug("Error while trying to load stream as an SVG file: "
                                       + e.getMessage());
                // assuming any exception means this document is not svg
                // or could not be loaded for some reason
                try {
                    in.reset();
                } catch (IOException ioe) {
                    // we're more interested in the original exception
                }
                return null;
            }
        }

        private ImageInfo createImageInfo(String uri, ImageContext context, SVGDocument doc) {
            Element e = doc.getRootElement();
            float pxUnitToMillimeter = UnitConv.IN2MM / context.getSourceResolution();
            UserAgent userAg = new SimpleSVGUserAgent(pxUnitToMillimeter,
                        new AffineTransform()) {

                /** {@inheritDoc} */
                public void displayMessage(String message) {
                    log.debug(message);
                }

            };
            BridgeContext ctx = new BridgeContext(userAg);
            UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);

            String s;
            // 'width' attribute - default is 100%
            s = e.getAttributeNS(null, SVGOMDocument.SVG_WIDTH_ATTRIBUTE);
            if (s.length() == 0) {
                s = SVGOMDocument.SVG_SVG_WIDTH_DEFAULT_VALUE;
            }
            float width = UnitProcessor.svgHorizontalLengthToUserSpace(
                    s, SVGOMDocument.SVG_WIDTH_ATTRIBUTE, uctx);

            // 'height' attribute - default is 100%
            s = e.getAttributeNS(null, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE);
            if (s.length() == 0) {
                s = SVGOMDocument.SVG_SVG_HEIGHT_DEFAULT_VALUE;
            }
            float height = UnitProcessor.svgVerticalLengthToUserSpace(
                    s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx);

            int widthMpt = (int)Math.round(px2mpt(width, context.getSourceResolution()));
            int heightMpt = (int)Math.round(px2mpt(height, context.getSourceResolution()));

            ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_SVG);
            ImageSize size = new ImageSize();
            size.setSizeInMillipoints(widthMpt, heightMpt);
            //Set the resolution to that of the FOUserAgent
            size.setResolution(context.getSourceResolution());
            size.calcPixelsFromSize();
            info.setSize(size);

            //The whole image had to be loaded for this, so keep it
            ImageXMLDOM xmlImage = new ImageXMLDOM(info,
                    doc, BatikImageFlavors.SVG_DOM);
            info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, xmlImage);
            return info;
        }

        private boolean isSupportedSource(Source src) {
            if (src instanceof DOMSource) {
                DOMSource domSrc = (DOMSource)src;
                return (domSrc.getNode() instanceof SVGDocument);
            } else {
                return ImageUtil.hasInputStream(src);
            }
        }

    }

    private static double px2mpt(double px, double resolution) {
        return px * 1000 * UnitConv.IN2PT / resolution;
    }

}
