/*
 * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM)
 * Published By SunSoft Press/Prentice-Hall
 * Copyright (C) 1996 Sun Microsystems Inc.
 * All Rights Reserved. ISBN 0-13-565755-5
 *
 * Permission to use, copy, modify, and distribute this 
 * software and its documentation for NON-COMMERCIAL purposes
 * and without fee is hereby granted provided that this 
 * copyright notice appears in all copies. 
 * 
 * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR 
 * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS
 * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED 
 * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING 
 * THIS SOFTWARE OR ITS DERIVATIVES.
 */
/**
 * @version 1.00 07 Feb 1996 
 * @author Cay Horstmann
 */
/**
 * Modified by Michael Scott, December 1996
 */
import java.awt.*;
import java.applet.*;
import java.util.*;

class ThreadList {
    public ThreadList(Thread t, ThreadList n)
    {
        th = t;
        next = n;
    }
    public void stop()
    {
        th.stop();
        if (next != null)
            next.stop();
    }
    private Thread th;
    private ThreadList next;
}

public class BounceThread extends Applet {
    public void init()
    {
        setLayout(new BorderLayout());
        colors = new Color[6];
        colors[0] = Color.blue;
        colors[1] = Color.red;
        colors[2] = Color.green;
        colors[3] = Color.cyan;
        colors[4] = Color.magenta;
        colors[5] = Color.yellow;
        canvas = new Canvas();
        canvas.setBackground(Color.white);
        threads = null;
        prn = new Random();
        add("Center", canvas);
        Panel p = new Panel();
        p.add(new Button("Start"));
        p.add(new Button("Clear"));
        add("South", p);
    }
   
    public boolean action(Event evt, Object arg)
    {
        if (arg.equals("Start")) {
            int x = prn.nextInt() % 300;    /* size specified in html file */
            if (x < 0)
                x = -x;
            int y = prn.nextInt() % 200;    /* size specified in html file */
            if (y < 0)
                y = -y;
            int dx, dy;
            do {
                dx = prn.nextInt() % 3;     /* -2..2 */
            } while (dx == 0);
            do {
                dy = prn.nextInt() % 3;     /* -2..2 */
            } while (dy == 0);
            int cn = prn.nextInt() % 6;
            if (cn < 0)
                cn = -cn;
            Color c = colors[cn];
            Ball b = new Ball(canvas, x, y, dx, dy, c);
            b.start();
            ThreadList temp = new ThreadList((Thread) b, threads);
            threads = temp;
        } else
            if (arg.equals("Clear")) {
                threads.stop();
                threads = null;
            } else
                return super.action(evt, arg);
        return true;
    }
   
   private Random prn;
   private Canvas canvas;
   private ThreadList threads;
   private static Color[] colors;
}

class Ball extends Thread {

    public Ball(Canvas can, int ax, int ay, int adx, int ady, Color c)
    {
        box = can;
        x = ax;
        y = ay;
        dx = ady;
        dy = ady;
        color = c;
    }

    private void draw()
    {
        Graphics g = box.getGraphics();
        g.setColor(color);
        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }

    private void clear()
    {
        Graphics g = box.getGraphics();
        g.setColor(box.getBackground());
        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }
   
    private void move()
    {
        Graphics g = box.getGraphics();
        g.setColor(box.getBackground());
        g.fillOval(x, y, XSIZE, YSIZE);
        x += dx;
        y += dy;
        Dimension d = box.size();
        if (x < 0) {
            x = 0; dx = -dx;
        }
        if (x + XSIZE >= d.width) {
            x = d.width - XSIZE; dx = -dx;
        }
        if (y < 0) {
            y = 0; dy = -dy;
        }
        if (y + YSIZE >= d.height) {
            y = d.height - YSIZE; dy = -dy;
        }
        g.setColor(color);
        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }
   
    public void run()
    {
        draw();
        try {
            for (int i = 1; i <= 1000; i++) {
                move();
                try {
                    Thread.sleep(5);
                } catch(InterruptedException e) {}
            }
        } finally {
            clear();
        }
    }
   
    private Canvas box;
    private Color color;
    private static final int XSIZE = 10;
    private static final int YSIZE = 10;
    private int x = 0;
    private int y = 0;
    private int dx = 2;
    private int dy = 2;   
}
