/*
 * ImageViewer.java  $Revision: 1.1 $  $Date: 2007/08/04 05:36:54 $
 *
 * Copyright (c) Meldcraft, Inc. 2006
 */
package com.meldcraft.imageviewer;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.stream.ImageInputStream;

/**
 * @version $Revision: 1.1 $ $Date: 2007/08/04 05:36:54 $
 * @author Rob Richards
 */
public class ImageLoader
{
    private ArrayList   mProgressListeners = new ArrayList();

    public void addIIOReadProgressListener(IIOReadProgressListener listener)
    {
        if (!mProgressListeners.contains(listener))
        {
            mProgressListeners.add(listener);
        }
    }

    public boolean removeIIOReadProgressListener(IIOReadProgressListener listener)
    {
        return mProgressListeners.remove(listener);
    }

    public Image loadImage(Object arg) throws IOException
    {
        Object obj = arg;

        if (obj instanceof String)
        {
            try
            {
                obj = new URL((String)obj);
            }
            catch (MalformedURLException e)
            {
                obj = new File((String)obj);
            }
        }

        if (obj instanceof File)
        {
            File file = (File)obj;
            try
            {
                obj = file.toURI().toURL();
            }
            catch (MalformedURLException e)
            {
            }
        }

        Image image = null;
        if (obj instanceof URL)
        {
            URL url = (URL)obj;
            image = readImage(url);
        }

        return image;
    }
    
    protected Image readImage(URL url) throws IOException
    {
        ImageReader reader = findImageReader(url);
        if (reader == null)
        {
            throw new IOException("Unknown image type.");
        }
        Object[] listeners = mProgressListeners.toArray();
        if ((listeners != null) && (listeners.length > 0))
        {
            for (int i=0 ; i < listeners.length ; i++)
            {
                reader.addIIOReadProgressListener((IIOReadProgressListener)listeners[i]);
            }
        }
        return loadImage(reader);
    }

    protected ImageReader findImageReader(URL url) throws IOException
    {
        ImageInputStream input = null;
        input = ImageIO.createImageInputStream(url.openStream());
        ImageReader reader = null;
        if (input != null)
        {
            Iterator readers = ImageIO.getImageReaders(input);
            while ((reader == null) && (readers != null) && readers.hasNext())
            {
                reader = (ImageReader) readers.next();
            }
            if (reader != null)
            {
                reader.setInput(input);
            }
        }
        return reader;
    }

    protected BufferedImage loadImage(ImageReader reader) throws IOException
    {
        BufferedImage image = null;
        try
        {
            int index = reader.getMinIndex();
            image = reader.read(index);
        }
        finally
        {
            if (reader != null)
            {
                try
                {
                    reader.dispose();
                }
                finally
                {
                    try
                    {
                        reader.removeAllIIOReadProgressListeners();
                    }
                    finally
                    {
                        ImageInputStream input = (ImageInputStream)reader.getInput();
                        if (input != null)
                        {
                            try
                            {
                                input.close();
                            }
                            catch (IOException e)
                            {
                                // ignored
                            }
                        }
                    }
                }
            }
        }
        return image;
    }
}
