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

import java.io.IOException;
import java.io.InputStream;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

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

import org.apache.xmlgraphics.image.loader.Image;
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.fop.util.DefaultErrorListener;
import org.apache.fop.util.UnclosableInputStream;

/**
 * Image preloader for Plan images.
 */
public class PreloaderPlan extends AbstractImagePreloader {

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

    /** {@inheritDoc} */
    public ImageInfo preloadImage(String uri, Source src, ImageContext context)
            throws IOException {
        if (!ImageUtil.hasInputStream(src)) {
            //TODO Remove this and support DOMSource and possibly SAXSource
            return null;
        }
        ImageInfo info = getImage(uri, src, context);
        if (info != null) {
            ImageUtil.closeQuietly(src); //Image is fully read
        }
        return info;
    }

    private ImageInfo getImage(String uri, Source src, ImageContext context) throws IOException {

        InputStream in = new UnclosableInputStream(ImageUtil.needInputStream(src));
        try {
            Document planDoc = getDocument(in);
            Element rootEl = planDoc.getDocumentElement();
            if (!PlanElementMapping.NAMESPACE.equals(
                    rootEl.getNamespaceURI())) {
                in.reset();
                return null;
            }

            //Have to render the plan to know its size
            PlanRenderer pr = new PlanRenderer();
            Document svgDoc = pr.createSVGDocument(planDoc);
            float width = pr.getWidth();
            float height = pr.getHeight();

            //Return converted SVG image
            ImageInfo info = new ImageInfo(uri, "image/svg+xml");
            final ImageSize size = new ImageSize();
            size.setSizeInMillipoints(
                    Math.round(width * 1000),
                    Math.round(height * 1000));
            //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
            Image image = new ImageXMLDOM(info, svgDoc,
                    svgDoc.getDocumentElement().getNamespaceURI());
            info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, image);

            return info;
        } catch (TransformerException e) {
            try {
                in.reset();
            } catch (IOException ioe) {
                // we're more interested in the original exception
            }
            log.debug("Error while trying to parsing a Plan file: "
                    + e.getMessage());
            return null;
        }
    }

    private Document getDocument(InputStream in) throws TransformerException {
        TransformerFactory tFactory = TransformerFactory.newInstance();
        //Custom error listener to minimize output to console
        ErrorListener errorListener = new DefaultErrorListener(log);
        tFactory.setErrorListener(errorListener);
        Transformer transformer = tFactory.newTransformer();
        transformer.setErrorListener(errorListener);
        Source source = new StreamSource(in);
        DOMResult res = new DOMResult();
        transformer.transform(source, res);

        Document doc = (Document)res.getNode();
        return doc;
    }

}
