/**************************************************************************
* Copyright (c) 1996 Jim Crossley
*
* Although it's unlikely that anyone would actually want it,
* permission is hereby granted, without written agreement and
* without license or royalty fees, to use, copy, modify, and
* distribute this software and its documentation for any purpose,
* provided that the above copyright notice and the following three
* paragraphs appear in all copies of this software, its documentation
* and any derivative work.
*
* In no event shall Jim Crossley or Automated Design Systems, Inc. be
* liable to any party for direct, indirect, special, incidental, or
* consequential damages arising out of the use of this software and
* its documentation.
*
* The software provided hereunder is on an "as is" basis, and neither
* Jim Crossley nor Automated Design Systems, Inc. has any obligation
* to provide maintenance, support, updates, enhancements, or modifications.
*
* Derived or altered versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
***************************************************************************/
import java.applet.*;
import java.awt.*;

/**
 * Shows two spotlights dancing around some message.  The size of the
 * message font (TimesRoman) is relative to the height of the applet,
 * as is the size of the spotlights.
 * <p>
 *
 * Optional parameters [default]
 * <ul>
 * <li><em>message</em> - the message text [What lurks in the shadows?]
 * <li><em>background</em> - background color ["000000"]
 * <li><em>foreground</em> - foreground color ["ffff00"]
 * </ul>
 *
 * @author  Jim Crossley
 * @version 1.0, 9/17/1996
 */
public class Spotlight extends Applet
	implements Runnable {

	private static final String DEFAULT_MSG = "What lurks in the shadows?";

	private Image offscreen;
	private Thread animator;
	private Dimension app;
	private Font font;
	private String msg;
	private Color foreground, background;
	private int spotWidth, cushion;
	private int xMsg, yMsg;

	/**
	 * Reads parameters and establishes font and spotlight sizes.
	 */
	public void init() {
		app = this.size();
		offscreen = this.createImage(app.width, app.height);
		if ((msg = this.getParameter("message")) == null)
			msg = DEFAULT_MSG;
		if ((foreground = getColorParameter("foreground")) == null)
			foreground = Color.yellow;
		if ((background = getColorParameter("background")) == null)
			background = Color.black;

		spotWidth = app.height * 2;
		cushion = app.height / 2;
		font = new Font("TimesRoman", Font.BOLD, cushion); // 'cushion' is meaningless in this context!

		FontMetrics fm = this.getFontMetrics(font);
		xMsg = (app.width - fm.stringWidth(msg)) / 2; // center the message
		yMsg = (int) (app.height * 0.7);
	}

	/**
	 * Continuous loop that repeatedly does the following:
	 * <ol>
	 * <li>Draw a background-colored rectangle into the offscreen image
	 * <li>Draw foreground-colored circles[s] at some random spot
	 * <li>Draw a text string the same color as the background
	 * <li>Increment spotlight coordinates and change direction if necessary
	 * </ol>
	 */
	public void run() {
		int x = 0, y = 0;
		int x_direction = 5, y_direction = 5;
		while (true) {
			// Draw a background-colored rectangle into the offscreen image
			Graphics g = offscreen.getGraphics();
			g.setColor(background);
			g.fillRect(0, 0, app.width, app.height);

			// Draw foreground-colored circles[s] at some random spot
			g.setColor(foreground);
			g.fillOval(x, y, spotWidth, spotWidth);
			g.fillOval(app.width-spotWidth-x, app.height-spotWidth-y, spotWidth, spotWidth);

			// Draw a text string the same color as the background
			g.setColor(background);
			g.setFont(font);
			g.drawString(msg,xMsg,yMsg);

			// Repaint the applet
			repaint();

			// Increment spotlight coordinates and change direction if necessary
			x += 2*x_direction;
			y += y_direction;
			if ((x > app.width - cushion) || (x < cushion - spotWidth)) x_direction *= -1;
			if ((y > app.height - cushion) || (y < cushion - spotWidth)) y_direction *= -1;

			// Pause for a while
			try {
				Thread.sleep(100);
			}
			catch (InterruptedException e) {
			}
		}
	}

	/**
	 * Read the color parameter from the html source.
	 * The format should be "rrggbb"
	 */
	protected Color getColorParameter(String name) {
		String value = this.getParameter(name);
		int intvalue;
		try {
			intvalue = Integer.parseInt(value, 16);
		}
		catch (NumberFormatException e) {
			return null;
		}
		return new Color(intvalue);
	}

	/**
	 * Override to reduce flicker
	 */
	public void update(Graphics g) {
		paint(g);
	}

	/**
	 * Draw the offscreen image
	 */
	public void paint(Graphics g) {
		g.drawImage(offscreen,0,0,this);
	}

	public void start() {
		if (animator == null) {
			animator = new Thread(this);
			animator.start();
		}
	}
	public void stop() {
		if (animator != null) {
			animator.stop();
			animator = null;
		}
	}
}
