/* 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;
          }
      }
  }
}
