/*
 * 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.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.transform.Source;

import org.apache.commons.io.EndianUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.batik.transcoder.wmf.WMFConstants;
import org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore;

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.util.ImageUtil;
import org.apache.xmlgraphics.io.XmlSourceUtil;

import org.apache.fop.util.UnclosableInputStream;

/**
 * Image preloader for WMF images (Windows Metafile).
 */
public class PreloaderWMF extends AbstractImagePreloader {

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

    private boolean batikAvailable = true;

    /** {@inheritDoc} */
    public ImageInfo preloadImage(String uri, Source src, ImageContext context)
            throws IOException {
        if (!ImageUtil.hasInputStream(src)) {
            return null;
        }
        ImageInfo info = null;
        if (batikAvailable) {
            try {
                Loader loader = new Loader();
                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;
    }

    /**
     * This method is put in another class so that the class loader does not
     * attempt to load Batik related classes when constructing the WMFPreloader
     * 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 = new UnclosableInputStream(XmlSourceUtil.needInputStream(src));
            try {
                in.mark(4 + 1);

                DataInputStream din = new DataInputStream(in);
                int magic = EndianUtils.swapInteger(din.readInt());
                din.reset();
                if (magic != WMFConstants.META_ALDUS_APM) {
                    return null; //Not a WMF file
                }

                WMFRecordStore wmfStore = new WMFRecordStore();
                wmfStore.read(din);
                IOUtils.closeQuietly(din);

                int width = wmfStore.getWidthUnits();
                int height = wmfStore.getHeightUnits();
                int dpi = wmfStore.getMetaFileUnitsPerInch();

                ImageInfo info = new ImageInfo(uri, "image/x-wmf");
                ImageSize size = new ImageSize();
                size.setSizeInPixels(width, height);
                size.setResolution(dpi);
                size.calcSizeFromPixels();
                info.setSize(size);
                ImageWMF img = new ImageWMF(info, wmfStore);
                info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, img);

                return info;
            } catch (NoClassDefFoundError ncdfe) {
                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 WMF 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;
            }
        }
    }

}
