/* Applet.java -- Java base applet class
   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., 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;

  /** Some applets call setSize in their constructors.  In that case,
      these fields are used to store width and height values until a
      stub is set. */
  private transient int width;
  private transient int height;

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

    if (width != 0 && height != 0)
      stub.appletResize (width, height);
  }

  /**
   * 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)
  {
    if (stub == null)
      {
        this.width = width;
        this.height = height;
      }
    else
      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
