/* MediaTracker.java -- Class used for keeping track of images
   Copyright (C) 1999, 2002, 2004, 2005  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 java.awt;

import java.awt.image.ImageObserver;
import java.util.ArrayList;

/**
  * This class is used for keeping track of the status of various media
  * objects.
  *
  * Media objects are tracked by assigning them an ID. It is possible
  * to assign the same ID to mutliple objects, effectivly grouping them
  * together. In this case the status flags ({@link #statusID}) and error flag
  * (@link #isErrorID} and {@link #getErrorsID}) are ORed together. This
  * means that you cannot say exactly which media object has which status,
  * at most you can say that there <em>are</em> certain media objects with
  * some certain status.
  * 
  * At the moment only images are supported by this class.
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Bryce McKinlay
  */
public class MediaTracker implements java.io.Serializable
{
  /** Indicates that the media is still loading. */
  public static final int LOADING = 1 << 0;

  /** Indicates that the loading operation has been aborted. */
  public static final int ABORTED = 1 << 1;

  /** Indicates that an error has occured during loading of the media. */
  public static final int ERRORED = 1 << 2;

  /** Indicates that the media has been successfully and completely loaded. */
  public static final int COMPLETE = 1 << 3;

  /** The component on which the media is eventually been drawn. */
  Component target;

  /** The head of the linked list of tracked media objects. */
  MediaEntry head;

  /** Our serialVersionUID for serialization. */
  static final long serialVersionUID = -483174189758638095L;

  /**
   * This represents a media object that is tracked by a MediaTracker.
   * It also implements a simple linked list.
   */
  // FIXME: The serialized form documentation says MediaEntry is a 
  // serializable field, but the serialized form of MediaEntry itself
  // doesn't appear to be documented.
  class MediaEntry implements ImageObserver
  {
    /** The ID of the media object. */
    int id;

    /** The media object. (only images are supported ATM). */
    Image image;

    /** The link to the next entry in the list. */
    MediaEntry next;

    /** The tracking status. */
    int status;

    /** The width of the image. */
    int width;

    /** The height of the image. */
    int height;
    
    /**
     * Receives notification from an {@link java.awt.image.ImageProducer}
     * that more data of the image is available.
     *
     * @param img the image that is updated
     * @param flags flags from the ImageProducer that indicate the status
     *        of the loading process
     * @param x the X coordinate of the upper left corner of the image
     * @param y the Y coordinate of the upper left corner of the image
     * @param width the width of the image
     * @param height the height of the image
     *
     * @return <code>true</code> if more data is needed, <code>false</code>
     *         otherwise
     *
     * @see java.awt.image.ImageObserver
     */
    public boolean imageUpdate(Image img, int flags, int x, int y, 
                               int width, int height)
    {
      if ((flags & ABORT) != 0)
        status = ABORTED;
      else if ((flags & ERROR) != 0)
        status = ERRORED;
      else if ((flags & ALLBITS) != 0)
        status = COMPLETE;
      else
        status = 0;

      synchronized (MediaTracker.this)
        {
          MediaTracker.this.notifyAll();
        }

      // If status is not COMPLETE then we need more updates.
      return ((status & (COMPLETE | ERRORED | ABORTED)) == 0);
    }
  }

  /**
   * Constructs a new MediaTracker for the component <code>c</code>. The
   * component should be the component that uses the media (i.e. draws it).
   *
   * @param c the Component that wants to use the media
   */
  public MediaTracker(Component c)
  {
    target = c;
  }

  /**
   * Adds an image to the tracker with the specified <code>ID</code>.
   *
   * @param image the image to be added
   * @param id the ID of the tracker list to which the image is added
   */
  public void addImage(Image image, int id)
  {
    MediaEntry e = new MediaEntry();
    e.id = id;
    e.image = image;
    synchronized(this)
      {
        e.next = head;
        head = e;
      }
  }

  /**
   * Adds an image to the tracker with the specified <code>ID</code>.
   * The image is expected to be rendered with the specified width and
   * height.
   *
   * @param image the image to be added
   * @param id the ID of the tracker list to which the image is added
   * @param width the width of the image
   * @param height the height of the image
   */
  public void addImage(Image image, int id, int width, int height)
  {
    MediaEntry e = new MediaEntry();
    e.id = id;
    e.image = image;
    e.width = width;
    e.height = height;
    synchronized(this)
      {
        e.next = head;
        head = e;
      }
  }

  /**
   * Checks if all media objects have finished loading, i.e. are
   * {@link #COMPLETE}, {@link #ABORTED} or {@link #ERRORED}.
   *
   * If the media objects are not already loading, a call to this
   * method does <em>not</em> start loading. This is equivalent to
   * a call to <code>checkAll(false)</code>.
   *
   * @return if all media objects have finished loading either by beeing
   *         complete, have been aborted or errored.
   */
  public boolean checkAll()
  {
    return checkAll(false);
  }

  /**
   * Checks if all media objects have finished loading, i.e. are
   * {@link #COMPLETE}, {@link #ABORTED} or {@link #ERRORED}.
   *
   * If the media objects are not already loading, and <code>load</code>
   * is <code>true</code> then a call to this
   * method starts loading the media objects.
   *
   * @param load if <code>true</code> this method starts loading objects
   *        that are not already loading
   *
   * @return if all media objects have finished loading either by beeing
   *         complete, have been aborted or errored.
   */
  public boolean checkAll(boolean load)
  {
    MediaEntry e = head;
    boolean result = true;
    
    while (e != null)
      {
        if ((e.status & (COMPLETE | ERRORED | ABORTED)) == 0)
          {
            if (load && ((e.status & LOADING) == 0))
              {
		if (target.prepareImage(e.image, e))
		  e.status = COMPLETE;
		else
		  {
		    e.status = LOADING;
		    int flags = target.checkImage(e.image, e);
		    if ((flags & ImageObserver.ABORT) != 0)
		      e.status = ABORTED;
		    else if ((flags & ImageObserver.ERROR) != 0)
		      e.status = ERRORED;
		    else if ((flags & ImageObserver.ALLBITS) != 0)
		      e.status = COMPLETE;
		  }
		boolean complete = (e.status
				    & (COMPLETE | ABORTED | ERRORED)) != 0;
		if (!complete)
		  result = false;
	      }
            else
              result = false;
          }
        e = e.next;
      }
    return result;
  }

  /**
   * Checks if any of the registered media objects has encountered an error
   * during loading.
   *
   * @return <code>true</code> if at least one media object has encountered
   *         an error during loading, <code>false</code> otherwise
   *
   */
  public boolean isErrorAny()
  {
    MediaEntry e = head;    
    while (e != null)
      {
        if ((e.status & ERRORED) != 0)
          return true;
        e = e.next;
      }
    return false;
  }

  /**
   * Returns all media objects that have encountered errors during loading.
   *
   * @return an array of all media objects that have encountered errors
   *         or <code>null</code> if there were no errors at all
   */
  public Object[] getErrorsAny()
  {
    MediaEntry e = head;
    ArrayList result = null;
    while (e != null)
      {
        if ((e.status & ERRORED) != 0)
          {
            if (result == null)
              result = new ArrayList();
            result.add(e.image);
          }
        e = e.next;
      }
    if (result == null)
      return null;
    else
      return result.toArray();
  }

  /**
   * Waits for all media objects to finish loading, either by completing
   * successfully or by aborting or encountering an error.
   *
   * @throws InterruptedException if another thread interrupted the
   *         current thread while waiting
   */
  public void waitForAll() throws InterruptedException
  {
    synchronized (this)
    {
      while (checkAll(true) == false)
        wait();
    }
  }

  /**
   * Waits for all media objects to finish loading, either by completing
   * successfully or by aborting or encountering an error.
   *
   * This method waits at most <code>ms</code> milliseconds. If the
   * media objects have not completed loading within this timeframe, this
   * method returns <code>false</code>, otherwise <code>true</code>.
   *
   * @param ms timeframe in milliseconds to wait for the media objects to
   *        finish
   *
   * @return <code>true</code> if all media objects have successfully loaded
   *         within the timeframe, <code>false</code> otherwise
   *
   * @throws InterruptedException if another thread interrupted the
   *         current thread while waiting
   */
  public boolean waitForAll(long ms) throws InterruptedException
  {
    long start = System.currentTimeMillis();
    boolean result = checkAll(true);
    synchronized (this)
    {
      while (result == false)
        {
          wait(ms);
          result = checkAll(true);
          if ((System.currentTimeMillis() - start) > ms)
            break;
        }
    }

    return result;
  }

  /**
   * Returns the status flags of all registered media objects ORed together.
   * If <code>load</code> is <code>true</code> then media objects that
   * are not already loading will be started to load.
   *
   * @param load if set to <code>true</code> then media objects that are
   *        not already loading are started
   *
   * @return the status flags of all tracked media objects ORed together
   */
  public int statusAll(boolean load)
  {
    int result = 0;
    MediaEntry e = head;
    while (e != null)
      {
        if (load && e.status == 0)
          {
            if (target.prepareImage(e.image, e))
              e.status = COMPLETE;
            else
	      {
                e.status = LOADING;
                int flags = target.checkImage(e.image, e);
		if ((flags & ImageObserver.ABORT) != 0)
		  e.status = ABORTED;
		else if ((flags & ImageObserver.ERROR) != 0)
		  e.status = ERRORED;
		else if ((flags & ImageObserver.ALLBITS) != 0)
		  e.status = COMPLETE;
	      }
          }
        result |= e.status;
        e = e.next;
      }
    return result;
  }

  /**
   * Checks if the media objects with <code>ID</code> have completed loading.
   *
   * @param id the ID of the media objects to check
   *
   * @return <code>true</code> if all media objects with <code>ID</code>
   *         have successfully finished
   */
  public boolean checkID(int id)
  {
    return checkID(id, false);
  }

  /**
   * Checks if the media objects with <code>ID</code> have completed loading.
   * If <code>load</code> is <code>true</code> then media objects that
   * are not already loading will be started to load.
   *
   * @param id the ID of the media objects to check
   * @param load if set to <code>true</code> then media objects that are
   *        not already loading are started
   *
   * @return <code>true</code> if all media objects with <code>ID</code>
   *         have successfully finished
   */
  public boolean checkID(int id, boolean load)
  {
    MediaEntry e = head;
    boolean result = true;
    
    while (e != null)
      {
        if (e.id == id && ((e.status & (COMPLETE | ABORTED | ERRORED)) == 0))
          {
            if (load && ((e.status & LOADING) == 0))
              {
                e.status = LOADING;
		if (target.prepareImage(e.image, e))
		  e.status = COMPLETE;
		else
		  {
		    int flags = target.checkImage(e.image, e);
		    if ((flags & ImageObserver.ABORT) != 0)
		      e.status = ABORTED;
		    else if ((flags & ImageObserver.ERROR) != 0)
		      e.status = ERRORED;
		    else if ((flags & ImageObserver.ALLBITS) != 0)
		      e.status = COMPLETE;
		  }
		boolean complete = (e.status
				    & (COMPLETE | ABORTED | ERRORED)) != 0;
		if (!complete)
		  result = false;
              }
            else
              result = false;
          }
        e = e.next;
      }
    return result;
  }

  /**
   * Returns <code>true</code> if any of the media objects with <code>ID</code>
   * have encountered errors during loading, false otherwise.
   *
   * @param id the ID of the media objects to check
   *
   * @return <code>true</code> if any of the media objects with <code>ID</code>
   *         have encountered errors during loading, false otherwise
   */
  public boolean isErrorID(int id)
  {
    MediaEntry e = head;    
    while (e != null)
      {
        if (e.id == id && ((e.status & ERRORED) != 0))
          return true;
        e = e.next;
      }
    return false;
  }

  /**
   * Returns all media objects with the specified ID that have encountered
   * an error.
   *
   * @param id the ID of the media objects to check
   *
   * @return an array of all media objects  with the specified ID that
   *         have encountered an error
   */
  public Object[] getErrorsID(int id)
  {
    MediaEntry e = head;
    ArrayList result = null;
    while (e != null)
      {
        if (e.id == id && ((e.status & ERRORED) != 0))
          {
            if (result == null)
              result = new ArrayList();
            result.add(e.image);
          }
        e = e.next;
      }
    if (result == null)
      return null;
    else
      return result.toArray();
  }

  /**
   * Waits for all media objects with the specified ID to finish loading,
   * either by completing successfully or by aborting or encountering an error.
   *
   * @param id the ID of the media objects to wait for
   *
   * @throws InterruptedException if another thread interrupted the
   *         current thread while waiting
   */
  public void waitForID(int id) throws InterruptedException
  {
    MediaEntry e = head;
    synchronized (this)
    {
      while (checkID (id, true) == false)
        wait();
    }
  }

  /**
   * Waits for all media objects with the specified ID to finish loading,
   * either by completing successfully or by aborting or encountering an error.
   *
   * This method waits at most <code>ms</code> milliseconds. If the
   * media objects have not completed loading within this timeframe, this
   * method returns <code>false</code>, otherwise <code>true</code>.
   *
   * @param id the ID of the media objects to wait for
   * @param ms timeframe in milliseconds to wait for the media objects to
   *        finish
   *
   * @return <code>true</code> if all media objects have successfully loaded
   *         within the timeframe, <code>false</code> otherwise
   *
   * @throws InterruptedException if another thread interrupted the
   *         current thread while waiting
   */
  public boolean waitForID(int id, long ms) throws InterruptedException
  {
    MediaEntry e = head;
    long start = System.currentTimeMillis();
    boolean result = checkID(id, true);

    synchronized (this)
    {
      while (result == false)
        {
          wait(ms);
          result = checkID(id, true);
          if ((System.currentTimeMillis() - start) > ms)
            break;
        }
    }

    return result;
  }

  /**
   * Returns the status flags of the media objects with the specified ID
   * ORed together.
   *
   * If <code>load</code> is <code>true</code> then media objects that
   * are not already loading will be started to load.
   *
   * @param load if set to <code>true</code> then media objects that are
   *        not already loading are started
   *
   * @return the status flags of all tracked media objects ORed together
   */
  public int statusID(int id, boolean load)
  {
    int result = 0;
    MediaEntry e = head;
    while (e != null)
      {
        if (e.id == id)
          {
            if (load && e.status == 0)
              {
		if (target.prepareImage(e.image, e))
                  e.status = COMPLETE;
		else
		  {
		    e.status = LOADING;
		    int flags = target.checkImage(e.image, e);
		    if ((flags & ImageObserver.ABORT) != 0)
		      e.status = ABORTED;
		    else if ((flags & ImageObserver.ERROR) != 0)
		      e.status = ERRORED;
		    else if ((flags & ImageObserver.ALLBITS) != 0)
		      e.status = COMPLETE;
		  }
              }
            result |= e.status;
          }
        e = e.next;
      }
    return result;
  }

  /**
   * Removes an image from this MediaTracker.
   *
   * @param image the image to be removed
   */
  public void removeImage(Image image)
  {
    synchronized (this)
      {
        MediaEntry e = head;
        MediaEntry prev = null;
        while (e != null)
          {
            if (e.image == image)
              {
                if (prev == null)
                  head = e.next;
                else
                  prev.next = e.next;
              }
            else
              prev = e;
            e = e.next;
          }
      }
  }

  /**
   * Removes an image with the specified ID from this MediaTracker.
   *
   * @param image the image to be removed
   */
  public void removeImage(Image image, int id)
  {
    synchronized (this)
      {
        MediaEntry e = head;
        MediaEntry prev = null;
        while (e != null)
          {
            if (e.id == id && e.image == image)
              {
                if (prev == null)
                  head = e.next;
                else
                  prev.next = e.next;
              }
            else
              prev = e;
            e = e.next;
          }
      }
  }

  /**
   * Removes an image with the specified ID and scale from this MediaTracker.
   *
   * @param image the image to be removed
   */
  public void removeImage(Image image, int id, int width, int height)
  {
    synchronized (this)
      {
        MediaEntry e = head;
        MediaEntry prev = null;
        while (e != null)
          {
            if (e.id == id && e.image == image
                && e.width == width && e.height == height)
              {
                if (prev == null)
                  head = e.next;
                else
                  prev.next = e.next;
              }
            else
              prev = e;
            e = e.next;
          }
      }
  }
}
