/*
 * 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.
 */
package org.apache.commons.imaging;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.imaging.common.BinaryFileParser;
import org.apache.commons.imaging.common.IBufferedImageFactory;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.SimpleBufferedImageFactory;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.common.bytesource.ByteSourceArray;
import org.apache.commons.imaging.common.bytesource.ByteSourceFile;
import org.apache.commons.imaging.formats.bmp.BmpImageParser;
import org.apache.commons.imaging.formats.dcx.DcxImageParser;
import org.apache.commons.imaging.formats.gif.GifImageParser;
import org.apache.commons.imaging.formats.icns.IcnsImageParser;
import org.apache.commons.imaging.formats.ico.IcoImageParser;
import org.apache.commons.imaging.formats.jpeg.JpegImageParser;
import org.apache.commons.imaging.formats.pcx.PcxImageParser;
import org.apache.commons.imaging.formats.png.PngImageParser;
import org.apache.commons.imaging.formats.pnm.PnmImageParser;
import org.apache.commons.imaging.formats.psd.PsdImageParser;
import org.apache.commons.imaging.formats.rgbe.RgbeImageParser;
import org.apache.commons.imaging.formats.tiff.TiffImageParser;
import org.apache.commons.imaging.formats.wbmp.WbmpImageParser;
import org.apache.commons.imaging.formats.xbm.XbmImageParser;
import org.apache.commons.imaging.formats.xpm.XpmImageParser;
import org.apache.commons.imaging.util.Debug;

public abstract class ImageParser extends BinaryFileParser implements
        SanselanConstants
{

    public static final ImageParser[] getAllImageParsers()
    {
        ImageParser result[] = { new JpegImageParser(), new TiffImageParser(),
                new PngImageParser(), new BmpImageParser(),
                new GifImageParser(), new PsdImageParser(),
                new PnmImageParser(), new IcoImageParser(),
                new IcnsImageParser(), new WbmpImageParser(),
                new PcxImageParser(), new DcxImageParser(),
                new XbmImageParser(), new XpmImageParser(),
                new RgbeImageParser()
        // new JBig2ImageParser(),
        // new TgaImageParser(),
        };

        return result;
    }

    public final IImageMetadata getMetadata(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        return getMetadata(byteSource, null);
    }

    public abstract IImageMetadata getMetadata(ByteSource byteSource, Map params)
            throws ImageReadException, IOException;

    public final IImageMetadata getMetadata(byte bytes[])
            throws ImageReadException, IOException
    {
        return getMetadata(bytes, null);
    }

    public final IImageMetadata getMetadata(byte bytes[], Map params)
            throws ImageReadException, IOException
    {
        return getMetadata(new ByteSourceArray(bytes), params);
    }

    public final IImageMetadata getMetadata(File file)
            throws ImageReadException, IOException
    {
        return getMetadata(file, null);
    }

    public final IImageMetadata getMetadata(File file, Map params)
            throws ImageReadException, IOException
    {
        if (debug)
            System.out.println(getName() + ".getMetadata" + ": "
                    + file.getName());

        if (!canAcceptExtension(file))
            return null;

        return getMetadata(new ByteSourceFile(file), params);
    }

    public abstract ImageInfo getImageInfo(ByteSource byteSource, Map params)
            throws ImageReadException, IOException;

    public final ImageInfo getImageInfo(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        return getImageInfo(byteSource, null);
    }

    public final ImageInfo getImageInfo(byte bytes[], Map params)
            throws ImageReadException, IOException
    {
        return getImageInfo(new ByteSourceArray(bytes), params);
    }

    public final ImageInfo getImageInfo(File file, Map params)
            throws ImageReadException, IOException
    {
        if (!canAcceptExtension(file))
            return null;

        return getImageInfo(new ByteSourceFile(file), params);
    }

    /**
     * @throws ImageReadException may be thrown by sub-classes
     * @throws IOException  may be thrown by sub-classes
     */
    public FormatCompliance getFormatCompliance(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        return null;
    }

    public final FormatCompliance getFormatCompliance(byte bytes[])
            throws ImageReadException, IOException
    {
        return getFormatCompliance(new ByteSourceArray(bytes));
    }

    public final FormatCompliance getFormatCompliance(File file)
            throws ImageReadException, IOException
    {
        if (!canAcceptExtension(file))
            return null;

        return getFormatCompliance(new ByteSourceFile(file));
    }

    public List<BufferedImage> getAllBufferedImages(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        BufferedImage bi = getBufferedImage(byteSource, null);

        List<BufferedImage> result = new ArrayList<BufferedImage>();

        result.add(bi);

        return result;
    }

    public final List<BufferedImage> getAllBufferedImages(byte bytes[])
            throws ImageReadException, IOException
    {
        return getAllBufferedImages(new ByteSourceArray(bytes));
    }

    public final List<BufferedImage> getAllBufferedImages(File file)
            throws ImageReadException, IOException
    {
        if (!canAcceptExtension(file))
            return null;

        return getAllBufferedImages(new ByteSourceFile(file));
    }

    // public boolean extractImages(ByteSource byteSource, File dstDir,
    // String dstRoot, ImageParser encoder) throws ImageReadException,
    // IOException, ImageWriteException
    // {
    // List v = getAllBufferedImages(byteSource);
    //
    // if (v == null)
    // return false;
    //
    // for (int i = 0; i < v.size(); i++)
    // {
    // BufferedImage image = (BufferedImage) v.get(i);
    // File file = new File(dstDir, dstRoot + "_" + i
    // + encoder.getDefaultExtension());
    // encoder.writeImage(image, new FileOutputStream(file), null);
    // }
    //
    // return false;
    // }
    //
    // public final boolean extractImages(byte bytes[], File dstDir,
    // String dstRoot, ImageParser encoder)
    //
    // throws ImageReadException, IOException, ImageWriteException
    // {
    // return extractImages(new ByteSourceArray(bytes), dstDir, dstRoot,
    // encoder);
    // }
    //
    // public final boolean extractImages(File file, File dstDir,
    // String dstRoot, ImageParser encoder)
    //
    // throws ImageReadException, IOException, ImageWriteException
    // {
    // if (!canAcceptExtension(file))
    // return false;
    //
    // return extractImages(new ByteSourceFile(file), dstDir, dstRoot,
    // encoder);
    // }

    public abstract BufferedImage getBufferedImage(ByteSource byteSource,
            Map params) throws ImageReadException, IOException;

    public final BufferedImage getBufferedImage(byte bytes[], Map params)
            throws ImageReadException, IOException
    {
        return getBufferedImage(new ByteSourceArray(bytes), params);
    }

    public final BufferedImage getBufferedImage(File file, Map params)
            throws ImageReadException, IOException
    {
        if (!canAcceptExtension(file))
            return null;

        return getBufferedImage(new ByteSourceFile(file), params);
    }

    /**
     * @throws IOException may be thrown by sub-classes 
     */
    public void writeImage(BufferedImage src, OutputStream os, Map params)
            throws ImageWriteException, IOException
    {
        try
        {
            os.close(); // we are obligated to close stream.
        } catch (Exception e)
        {
            Debug.debug(e);
        }

        throw new ImageWriteException("This image format (" + getName()
                + ") cannot be written.");
    }

    public final Dimension getImageSize(byte bytes[])
            throws ImageReadException, IOException
    {
        return getImageSize(bytes, null);
    }

    public final Dimension getImageSize(byte bytes[], Map params)
            throws ImageReadException, IOException
    {
        return getImageSize(new ByteSourceArray(bytes), params);
    }

    public final Dimension getImageSize(File file) throws ImageReadException,
            IOException
    {

        return getImageSize(file, null);
    }

    public final Dimension getImageSize(File file, Map params)
            throws ImageReadException, IOException
    {

        if (!canAcceptExtension(file))
            return null;

        return getImageSize(new ByteSourceFile(file), params);
    }

    public abstract Dimension getImageSize(ByteSource byteSource, Map params)
            throws ImageReadException, IOException;

    public abstract String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException;

    public final byte[] getICCProfileBytes(byte bytes[])
            throws ImageReadException, IOException
    {
        return getICCProfileBytes(bytes, null);
    }

    public final byte[] getICCProfileBytes(byte bytes[], Map params)
            throws ImageReadException, IOException
    {
        return getICCProfileBytes(new ByteSourceArray(bytes), params);
    }

    public final byte[] getICCProfileBytes(File file)
            throws ImageReadException, IOException
    {
        return getICCProfileBytes(file, null);
    }

    public final byte[] getICCProfileBytes(File file, Map params)
            throws ImageReadException, IOException
    {
        if (!canAcceptExtension(file))
            return null;

        if (debug)
            System.out.println(getName() + ": " + file.getName());

        return getICCProfileBytes(new ByteSourceFile(file), params);
    }

    public abstract byte[] getICCProfileBytes(ByteSource byteSource, Map params)
            throws ImageReadException, IOException;

    public final String dumpImageFile(byte bytes[]) throws ImageReadException,
            IOException
    {
        return dumpImageFile(new ByteSourceArray(bytes));
    }

    public final String dumpImageFile(File file) throws ImageReadException,
            IOException
    {
        if (!canAcceptExtension(file))
            return null;

        if (debug)
            System.out.println(getName() + ": " + file.getName());

        return dumpImageFile(new ByteSourceFile(file));
    }

    public final String dumpImageFile(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);

        dumpImageFile(pw, byteSource);

        pw.flush();

        return sw.toString();
    }

    /**
     * @throws ImageReadException  may be thrown by sub-classes
     * @throws IOException may be thrown by sub-classes
     */
    public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
            throws ImageReadException, IOException
    {
        return false;
    }

    public abstract boolean embedICCProfile(File src, File dst, byte profile[]);

    public abstract String getName();

    public abstract String getDefaultExtension();

    protected abstract String[] getAcceptedExtensions();

    protected abstract ImageFormat[] getAcceptedTypes();

    public boolean canAcceptType(ImageFormat type)
    {
        ImageFormat types[] = getAcceptedTypes();

        for (int i = 0; i < types.length; i++)
            if (types[i].equals(type))
                return true;
        return false;
    }

    protected final boolean canAcceptExtension(File file)
    {
        return canAcceptExtension(file.getName());
    }

    protected final boolean canAcceptExtension(String filename)
    {
        String exts[] = getAcceptedExtensions();
        if (exts == null)
            return true;

        int index = filename.lastIndexOf('.');
        if (index >= 0)
        {
            String ext = filename.substring(index);
            ext = ext.toLowerCase();

            for (int i = 0; i < exts.length; i++)
                if (exts[i].toLowerCase().equals(ext))
                    return true;
        }
        return false;
    }

    protected IBufferedImageFactory getBufferedImageFactory(Map params)
    {
        if (params == null)
            return new SimpleBufferedImageFactory();

        IBufferedImageFactory result = (IBufferedImageFactory) params
                .get(SanselanConstants.BUFFERED_IMAGE_FACTORY);

        if (null != result)
            return result;

        return new SimpleBufferedImageFactory();
    }

    public static final boolean isStrict(Map params)
    {
        if (params == null || !params.containsKey(PARAM_KEY_STRICT))
            return false;
        return ((Boolean) params.get(PARAM_KEY_STRICT)).booleanValue();
    }
}