/* GtkImage.java
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.awt.peer.gtk;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.MemoryImageSource;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
import java.io.ByteArrayOutputStream;
import java.io.BufferedInputStream;
import java.net.URL;
import gnu.classpath.Pointer;

/**
 * GtkImage - wraps a GdkPixbuf.
 *
 * A GdkPixbuf is 'on-screen' and the gdk cannot draw to it,
 * this is used for the other constructors (and other createImage methods), and
 * corresponds to the Image implementations returned by the Toolkit.createImage
 * methods, and is basically immutable. 
 *
 * @author Sven de Marothy
 */
public class GtkImage extends Image
{
  int width = -1, height = -1;

  /**
   * Properties.
   */
  Hashtable props;

  /**
   * Loaded or not flag, for asynchronous compatibility.
   */
  boolean isLoaded;

  /**
   * Pointer to the GdkPixbuf - 
   * don't change the name without changing the native code.
   */
  Pointer pixbuf;

  /**
   * Observer queue.
   */
  Vector observers;

  /**
   * Error flag for loading.
   */
  boolean errorLoading;

  /**
   * Original source, if created from an ImageProducer.
   */
  ImageProducer source;

  /*
   * The 32-bit AABBGGRR format the GDK uses.
   */
  static ColorModel nativeModel = new DirectColorModel(32, 
						       0x000000FF,
						       0x0000FF00,
						       0x00FF0000,
						       0xFF000000);

  /**
   * The singleton GtkImage that is returned on errors by GtkToolkit.
   */
  private static GtkImage errorImage;

  /**
   * Lock that should be held for all gdkpixbuf operations. We don't use
   * the global gdk_threads_enter/leave functions in most places since
   * most gdkpixbuf operations can be done in parallel to drawing and 
   * manipulating gtk widgets.
   */
  static Object pixbufLock = new Object();

  /**
   * Allocate a PixBuf from a given ARGB32 buffer pointer.
   */
  private native void initFromBuffer( long bufferPointer );

  /**
   * Returns a copy of the pixel data as a java array.
   * Should be called with the pixbufLock held.
   */
  native int[] getPixels();

  /**
   * Sets the pixel data from a java array.
   * Should be called with the pixbufLock held.
   */
  private native void setPixels(int[] pixels);

  /**
   * Loads an image using gdk-pixbuf from a file.
   * Should be called with the pixbufLock held.
   */
  private native boolean loadPixbuf(String name);

  /**
   * Loads an image using gdk-pixbuf from data.
   * Should be called with the pixbufLock held.
   */
  private native boolean loadImageFromData(byte[] data);

  /**
   * Allocates a Gtk Pixbuf
   * Should be called with the pixbufLock held.
   */
  private native void createPixbuf();

  /**
   * Frees the above.
   * Should be called with the pixbufLock held.
   */
  private native void freePixbuf();

  /**
   * Sets the pixbuf to scaled copy of src image. hints are rendering hints.
   * Should be called with the pixbufLock held.
   */
  private native void createScaledPixbuf(GtkImage src, int hints);

  /**
   * Constructs a GtkImage from an ImageProducer. Asynchronity is handled in
   * the following manner: 
   * A GtkImageConsumer gets the image data, and calls setImage() when 
   * completely finished. The GtkImage is not considered loaded until the
   * GtkImageConsumer is completely finished. We go for all "all or nothing".
   */
  public GtkImage (ImageProducer producer)
  {
    isLoaded = false;
    observers = new Vector();
    source = producer;
    errorLoading = false;
    source.startProduction(new GtkImageConsumer(this, source));
  }

  /**
   * Constructs a blank GtkImage.  This is called when
   * GtkToolkit.createImage (String) is called with an empty string
   * argument ("").  A blank image is loaded immediately upon
   * construction and has width -1 and height -1.
   */
  public GtkImage ()
  {
    isLoaded = true;
    observers = null;
    props = new Hashtable();
    errorLoading = false;
  }

  /**
   * Constructs a GtkImage by loading a given file.
   *
   * @throws IllegalArgumentException if the image could not be loaded.
   */
  public GtkImage (String filename)
  {
    File f = new File(filename);
    try
      {
	String path = f.getCanonicalPath();
	synchronized(pixbufLock)
	  {
	    if (loadPixbuf(f.getCanonicalPath()) != true)
	      throw new IllegalArgumentException("Couldn't load image: "
						 + filename);
	  }
      } 
    catch(IOException e)
      {
	IllegalArgumentException iae;
	iae = new IllegalArgumentException("Couldn't load image: "
					   + filename);
	iae.initCause(e);
	throw iae;
      }

    isLoaded = true;
    observers = null;
    props = new Hashtable();
  }

  /**
   * Constructs a GtkImage from a byte array of an image file.
   *
   * @throws IllegalArgumentException if the image could not be
   * loaded.
   */
  public GtkImage (byte[] data)
  {
    synchronized(pixbufLock)
      {
	if (loadImageFromData (data) != true)
	  throw new IllegalArgumentException ("Couldn't load image.");
      }

    isLoaded = true;
    observers = null;
    props = new Hashtable();
    errorLoading = false;
  }

  /**
   * Constructs a GtkImage from a URL. May result in an error image.
   */
  public GtkImage (URL url)
  {
    isLoaded = false;
    observers = new Vector();
    errorLoading = false;
    if( url == null)
      return;
    ByteArrayOutputStream baos = new ByteArrayOutputStream (5000);
    try
      {
        BufferedInputStream bis = new BufferedInputStream (url.openStream());

        byte[] buf = new byte[5000];
        int n = 0;

        while ((n = bis.read(buf)) != -1)
	  baos.write(buf, 0, n); 
        bis.close();
      }
    catch(IOException e)
      {
	throw new IllegalArgumentException ("Couldn't load image.");
      }
    byte[] array = baos.toByteArray();
    synchronized(pixbufLock)
      {
	if (loadImageFromData(array) != true)
	  throw new IllegalArgumentException ("Couldn't load image.");
      }

    isLoaded = true;
    observers = null;
    props = new Hashtable();
  }

  /**
   * Constructs a scaled version of the src bitmap, using the GDK.
   */
  private GtkImage (GtkImage src, int width, int height, int hints)
  {
    this.width = width;
    this.height = height;
    props = new Hashtable();
    isLoaded = true;
    observers = null;

    // Use the GDK scaling method.
    synchronized(pixbufLock)
      {
	createScaledPixbuf(src, hints);
      }
  }

  /**
   * Package private constructor to create a GtkImage from a given
   * PixBuf pointer.
   */
  GtkImage (Pointer pixbuf)
  {
    this.pixbuf = pixbuf;
    synchronized(pixbufLock)
      {
	createFromPixbuf();
      }
    isLoaded = true;
    observers = null;
    props = new Hashtable();
  }

  /**
   * Wraps a buffer with a GtkImage.
   *
   * @param bufferPointer a pointer to an ARGB32 buffer
   */
  GtkImage(int width, int height, long bufferPointer)
  {
    this.width = width;
    this.height = height;
    props = new Hashtable();
    isLoaded = true;
    observers = null;
    initFromBuffer( bufferPointer );
  }

  /**
   * Returns an empty GtkImage with the errorLoading flag set.
   * Called from GtkToolKit when some error occured, but an image needs
   * to be returned anyway.
   */
  static synchronized GtkImage getErrorImage()
  {
    if (errorImage == null)
      {
	errorImage = new GtkImage();
	errorImage.errorLoading = true;
      }
    return errorImage;
  }

  /**
   * Native helper function for constructor that takes a pixbuf Pointer.
   * Should be called with the pixbufLock held.
   */
  private native void createFromPixbuf();

  /**
   * Callback from the image consumer.
   */
  public void setImage(int width, int height, 
		       int[] pixels, Hashtable properties)
  {
    this.width = width;
    this.height = height;
    props = (properties != null) ? properties : new Hashtable();

    if (width <= 0 || height <= 0 || pixels == null)
      {
	errorLoading = true;
	return;
      }

    isLoaded = true;
    deliver();
    synchronized(pixbufLock)
      {
	createPixbuf();
	setPixels(pixels);
      }
  }

  // java.awt.Image methods ////////////////////////////////////////////////

  public synchronized int getWidth (ImageObserver observer)
  {
    if (addObserver(observer))
      return -1;

    return width;
  }
  
  public synchronized int getHeight (ImageObserver observer)
  {
    if (addObserver(observer))
      return -1;
    
    return height;
  }

  public synchronized Object getProperty (String name, ImageObserver observer)
  {
    if (addObserver(observer))
      return UndefinedProperty;
    
    Object value = props.get (name);
    return (value == null) ? UndefinedProperty : value;
  }

  /**
   * Returns the source of this image.
   */
  public ImageProducer getSource ()
  {
    if (!isLoaded)
      return null;

    int[] pixels;
    synchronized (pixbufLock)
      {
        if (!errorLoading)
          pixels = getPixels();
        else
          return null;
      }
    return new MemoryImageSource(width, height, nativeModel, pixels, 
				 0, width);
  }

  /**
   * Does nothing. Should not be called.
   */
  public Graphics getGraphics ()
  {
    throw new IllegalAccessError("This method only works for off-screen"
				 +" Images.");
  }
  
  /**
   * Returns a scaled instance of this pixbuf.
   */
  public Image getScaledInstance(int width,
				 int height,
				 int hints)
  {
    if (width <= 0 || height <= 0)
      throw new IllegalArgumentException("Width and height of scaled bitmap"+
					 "must be >= 0");

    return new GtkImage(this, width, height, hints);
  }

  /**
   * If the image is loaded and comes from an ImageProducer, 
   * regenerate the image from there.
   *
   * I have no idea if this is ever actually used. Since GtkImage can't be
   * instantiated directly, how is the user to know if it was created from
   * an ImageProducer or not?
   */
  public synchronized void flush ()
  {
    if (isLoaded && source != null)
      {
	observers = new Vector();
	isLoaded = false;
	synchronized(pixbufLock)
	  {
	    freePixbuf();
	  }
	source.startProduction(new GtkImageConsumer(this, source));
      }
  }

  public void finalize()
  {
    if (isLoaded)
      {
	synchronized(pixbufLock)
	  {
	    freePixbuf();
	  }
      }
  }

  /**
   * Returns the image status, used by GtkToolkit
   */
  public int checkImage (ImageObserver observer)
  {
    if (addObserver(observer))
      {
	if (errorLoading == true)
	  return ImageObserver.ERROR;
	else
	  return 0;
      }

    return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
  }


  // Private methods ////////////////////////////////////////////////

  /**
   * Delivers notifications to all queued observers.
   */
  private void deliver()
  {
    int flags = ImageObserver.HEIGHT | 
      ImageObserver.WIDTH |
      ImageObserver.PROPERTIES |
      ImageObserver.ALLBITS;

    if (observers != null)
      for(int i=0; i < observers.size(); i++)
	((ImageObserver)observers.elementAt(i)).
	  imageUpdate(this, flags, 0, 0, width, height);

    observers = null;
  }
  
  /**
   * Adds an observer, if we need to.
   * @return true if an observer was added.
   */
  private boolean addObserver(ImageObserver observer)
  {
    if (!isLoaded)
      {
	if(observer != null)
	  if (!observers.contains (observer))
	    observers.addElement (observer);
	return true;
      }
    return false;
  }
}
