/*
 * 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.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.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.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) {

        InputStream in = new UnclosableInputStream(ImageUtil.needInputStream(src));
        try {
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            Source source = new StreamSource(in);
            DOMResult res = new DOMResult();
            transformer.transform(source, res);

            //Have to render the plan to know its size
            PlanRenderer pr = new PlanRenderer();
            Document svgDoc = pr.createSVGDocument((Document)res.getNode());
            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;
        }
    }

}

@@ -1186,16 +1186,44 @@
 ocument;
+%0Aimport org.w3c.dom.Element;
 %0A%0Aimport
@@ -2517,16 +2517,35 @@
 context)
+ throws IOException
  %7B%0A%0A    
@@ -3053,38 +3053,18 @@
 ent 
-svg
+plan
 Doc = 
-pr.createSVGDocument(
 (Doc
@@ -3082,16 +3082,289 @@
 etNode()
+;%0A            Element rootEl = planDoc.getDocumentElement();%0A            if (!PlanElementMapping.NAMESPACE.equals(rootEl.getNamespaceURI())) %7B%0A                in.reset();%0A                return null;%0A            %7D%0A%0A            Document svgDoc = pr.createSVGDocument(planDoc
 );%0A     

Check for plan namespace to avoid errors while parsing plan XML.