/* Applet.java -- Java base applet class
   Copyright (C) 1999, 2002 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.applet;

import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Panel;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;

/**
 * This is the base applet class.  An applet is a Java program that
 * runs inside a web browser or other applet viewer in a restricted
 * environment.
 *
 * <p>To be useful, a subclass should override at least start(). Also useful
 * are init, stop, and destroy for control purposes, and getAppletInfo and
 * getParameterInfo for descriptive purposes.
 *
 * @author Aaron M. Renn <arenn@urbanophile.com>
 * @author Eric Blake <ebb9@email.byu.edu>
 * @since 1.0
 * @status updated to 1.4
 */
public class Applet extends Panel
{
  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = -5836846270535785031L;

  /** The applet stub for this applet. */
  private transient AppletStub stub;

  /**
   * The accessibility context for this applet.
   *
   * @serial the accessibleContext for this
   * @since 1.2
   */
  private AccessibleContext accessibleContext;

  /**
   * Default constructor for subclasses.
   *
   * @throws HeadlessException if in a headless environment
   */
  public Applet()
  {
    if (GraphicsEnvironment.isHeadless())
      throw new HeadlessException();
  }

  /**
   * The browser calls this method to set the applet's stub, which is the
   * low level interface to the browser. Manually setting this to null is
   * asking for problems down the road.
   *
   * @param stub the applet stub for this applet
   */
  public final void setStub(AppletStub stub)
  {
    this.stub = stub;
  }

  /**
   * Tests whether or not this applet is currently active. An applet is active
   * just before the browser invokes start(), and becomes inactive just
   * before the browser invokes stop().
   *
   * @return <code>true</code> if this applet is active
   */
  public boolean isActive()
  {
    return stub.isActive();
  }

  /**
   * Returns the basename URL of the document this applet is embedded in. This
   * is everything up to the final '/'.
   *
   * @return the URL of the document this applet is embedded in
   * @see #getCodeBase()
   */
  public URL getDocumentBase()
  {
    return stub.getDocumentBase();
  }

  /**
   * Returns the URL of the code base for this applet.
   *
   * @return the URL of the code base for this applet
   */
  public URL getCodeBase()
  {
    return stub.getCodeBase();
  }

  /**
   * Returns the value of the specified parameter that was specified in
   * the <code>&lt;APPLET&gt;</code> tag for this applet.
   *
   * @param name the parameter name
   * @return the parameter value, or null if the parameter does not exist
   * @throws NullPointerException if name is null
   */
  public String getParameter(String name)
  {
    return stub.getParameter(name);
  }

  /**
   * Returns the applet context for this applet.
   *
   * @return the applet context for this applet
   */
  public AppletContext getAppletContext()
  {
    return stub.getAppletContext();
  }

  /**
   * Requests that the applet window for this applet be resized.
   *
   * @param width the new width in pixels
   * @param height the new height in pixels
   */
  public void resize(int width, int height)
  {
    stub.appletResize(width, height);
  }

  /**
   * Requests that the applet window for this applet be resized.
   *
   * @param dim the requested dimensions
   * @throws NullPointerException if dim is null
   */
  public void resize(Dimension dim)
  {
    resize(dim.width, dim.height);
  }

  /**
   * Displays the specified message in the status window if that window
   * exists.
   *
   * @param message the status message, may be null
   */
  public void showStatus(String message)
  {
    getAppletContext().showStatus(message);
  }

  /**
   * Returns an image from the specified URL.  Note that the image is not
   * actually retrieved until the applet attempts to display it, so this
   * method returns immediately.
   *
   * @param url the URL of the image
   * @return the retrieved image
   * @throws NullPointerException if url is null
   */
  public Image getImage(URL url)
  {
    return getAppletContext().getImage(url);
  }

  /**
   * Returns an image from the specified absolute URL, and relative path
   * from that URL.  Note that the image is not actually retrieved until the
   * applet attempts to display it, so this method returns immediately.
   * This calls <code>getImage(new URL(url, name))</code>, but if building
   * the new URL fails, this returns null.
   *
   * @param url the base URL of the image
   * @param name the name of the image relative to the URL
   * @return the retrieved image, or null on failure
   * @see #getImage(URL)
   */
  public Image getImage(URL url, String name)
  {
    try
      {
        return getImage(new URL(url, name));
      }
    catch (MalformedURLException e)
      {
        return null;
      }
  }

  /**
   * Returns an audio clip from the specified URL. This clip is not tied to
   * any particular applet.
   *
   * XXX Classpath does not yet implement this.
   *
   * @param url the URL of the audio clip
   * @return the retrieved audio clip
   * @throws NullPointerException if url is null
   * @see #getAudioClip(URL)
   * @since 1.2
   */
  public static final AudioClip newAudioClip(URL url)
  {
    // This requires an implementation of AudioClip in gnu.java.applet.
    throw new Error("Not implemented");
  }

  /**
   * Returns an audio clip from the specified URL. Note that the clip is not
   * actually retrieved until the applet attempts to play it, so this method
   * returns immediately.
   *
   * @param url the URL of the audio clip
   * @return the retrieved audio clip
   * @throws NullPointerException if url is null
   */
  public AudioClip getAudioClip(URL url)
  {
    return getAppletContext().getAudioClip(url);
  }

  /**
   * Returns an audio clip from the specified absolute URL, and relative path
   * from that URL.  Note that the clip is not actually retrieved until the
   * applet attempts to play it, so this method returns immediately. This
   * calls <code>getAudioClip(new URL(url, name))</code>, but if building
   * the new URL fails, this returns null.
   *
   * @param url the base URL of the audio clip
   * @param name the name of the clip relative to the URL
   * @return the retrieved audio clip, or null on failure
   * @see #getAudioClip(URL)
   */
  public AudioClip getAudioClip(URL url, String name)
  {
    try
      {
        return getAudioClip(new URL(url, name));
      }
    catch (MalformedURLException e)
      {
        return null;
      }
  }

  /**
   * Returns a descriptive string with applet defined information.  The
   * implementation in this class returns <code>null</code>, so subclasses
   * must override to return information.
   *
   * @return a string describing the author, version, and applet copyright
   */
  public String getAppletInfo()
  {
    return null;
  }

  /**
   * Returns the locale for this applet, if it has been set.  If no applet
   * specific locale has been set, the default locale is returned.
   *
   * @return the locale for this applet
   * @see Component#setLocale(Locale)
   * @since 1.1
   */
  public Locale getLocale()
  {
    return super.getLocale();
  }

  /**
   * Returns a list of parameters this applet supports.  Each element of
   * the outer array is an array of three strings with the name of the
   * parameter, the data type or valid values, and a description.  This
   * method is optional and the default implementation returns null.
   *
   * @return the list of parameters supported by this applet
   */
  public String[][] getParameterInfo()
  {
    return null;
  }

  /**
   * Loads and plays the audio clip pointed to by the specified URL. This does
   * nothing if the URL does not point to a valid audio clip.
   *
   * @param url the URL of the audio clip
   * @throws NullPointerException if url is null
   * @see #getAudioClip(URL)
   */
  public void play(URL url)
  {
    AudioClip ac = getAudioClip(url);
    try
      {
        ac.play();
      }
    catch (Exception ignored)
      {
      }
  }

  /**
   * Loads and plays the audio clip pointed to by the specified absolute URL,
   * and relative path from that URL. This does nothing if the URL cannot be
   * constructed, or if it does not point to a valid audio clip.
   *
   * @param url the base URL of the audio clip
   * @param name the name of the audio clip relative to the URL
   * @see #getAudioClip(URL, String)
   * @see #play(URL)
   */
  public void play(URL url, String name)
  {
    try
      {
        getAudioClip(url, name).play();
      }
    catch (Exception ignored)
      {
      }
  }

  /**
   * This method is called when the applet is first loaded, before start().
   * The default implementation does nothing; override to do any one-time
   * initialization.
   *
   * @see #start()
   * @see #stop()
   * @see #destroy()
   */
  public void init()
  {
  }

  /**
   * This method is called when the applet should start running.  This is
   * normally each time a web page containing it is loaded.  The default
   * implemention does nothing; override for your applet to be useful.
   *
   * @see #init()
   * @see #stop()
   * @see #destroy()
   */
  public void start()
  {
  }

  /**
   * This method is called when the applet should stop running.  This is
   * normally when the next web page is loaded.  The default implementation
   * does nothing; override for your applet to stop using resources when
   * it is no longer visible, but may be restarted soon.
   *
   * @see #init()
   * @see #start()
   * @see #destroy()
   */
  public void stop()
  {
  }

  /**
   * This method is called when the applet is being unloaded.  The default
   * implementation does nothing; override for your applet to clean up
   * resources on exit.
   *
   * @see #init()
   * @see #start()
   * @see #stop()
   */
  public void destroy()
  {
  }

  /**
   * Gets the AccessibleContext associated with this applet, creating one if
   * necessary. This always returns an instance of {@link AccessibleApplet}.
   *
   * @return the accessibility context of this applet
   * @since 1.3
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleApplet();
    return accessibleContext;
  }

  /**
   * Read an applet from an object stream. This checks for a headless
   * environment, then does the normal read.
   *
   * @param s the stream to read from
   * @throws ClassNotFoundException if a class is not found
   * @throws IOException if deserialization fails
   * @throws HeadlessException if this is a headless environment
   * @see GraphicsEnvironment#isHeadless()
   * @since 1.4
   */
  private void readObject(ObjectInputStream s)
    throws ClassNotFoundException, IOException
  {
    if (GraphicsEnvironment.isHeadless())
      throw new HeadlessException();
    s.defaultReadObject();
  }

  /**
   * This class provides accessibility support for Applets, and is the
   * runtime type returned by {@link #getAccessibleContext()}.
   *
   * @author Eric Blake <ebb9@email.byu.edu>
   * @since 1.3
   */
  protected class AccessibleApplet extends AccessibleAWTPanel
  {
    /**
     * Compatible with JDK 1.4+.
     */
    private static final long serialVersionUID = 8127374778187708896L;

    /**
     * The default constructor.
     */
    protected AccessibleApplet()
    {
    }

    /**
     * Get the role of this accessible object, a frame.
     *
     * @return the role of the object
     * @see AccessibleRole#FRAME
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.FRAME;
    }

    /**
     * Get the state set of this accessible object. In addition to the default
     * states of a Component, the applet can also be active.
     *
     * @return the role of the object
     * @see AccessibleState
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      AccessibleStateSet s = super.getAccessibleStateSet();
      if (isActive())
        s.add(AccessibleState.ACTIVE);
      return s;
    }
  } // class AccessibleApplet
} // class Applet
