/*
 *  =============================================================
 *  BouncePanel.java : Bounce circles around on the screen.
 *  Does not implement double buffering so has problems with 
 *  overlapping circles. Overrides update to avoid flickering
 *  problems.
 *
 *  Written by : Vasilios Lagakos                     March, 2001
 *  ==============================================================
 */

import javax.swing.*;
import java.awt.*;
import java.util.Vector;

public class BouncePanel extends JComponent implements Runnable {

   private Vector circles;
   private int width, height;
   private Thread animationThread = null;  
   boolean Reset = true;
  

   public BouncePanel() {

	circles = new Vector();
   }

   //----------------------------------------------------
   /*** Skip the usual screen-clearing step of update
      *  so that there is no "flicker" between each
      *  drawing step.
      */
   public void update(Graphics g){
	paint(g);
   }

   //----------------------------------------------------

   /***  Erase each circle's old position, move it,
      *  then draw it in new location.
      */
   public void paint(Graphics g) {
      MovingCircle circle;
      width = getSize().width;
      height = getSize().height;
      for(int i=0; i<circles.size(); i++) {
      	 circle = (MovingCircle)circles.elementAt(i);
      	 g.setColor(getBackground());
      	 circle.draw(g); // Old position
      	 circle.move(width, height);
      	 g.setColor(getForeground());
      	 circle.draw(g); // New position
       }
   }

   //----------------------------------------------------
   /*** When the "start" button is pressed, start the
      *  animation thread if it is not already started.
      *  Either way, add a circle to the Vector of
      *  circles that are being bounced.
      */ 
   public void start() {

	if (Reset == true)
         circles.removeAllElements();
	Reset = false;


	if (circles.size() == 0) {
         animationThread = new Thread(this);
         animationThread.start();
      }
      int radius = 25;
      int x = radius + randomInt(width - 2 * radius);
      int y = radius + randomInt(height - 2 * radius);
      int deltaX = 1 + randomInt(10);
      int deltaY = 1 + randomInt(10);
      circles.addElement(new MovingCircle(x, y, radius,
                                          deltaX,
                                          deltaY));
   }

   //----------------------------------------------------
   /***  When the "stop" button is pressed, stop
      *  the thread and clear the Vector of circles.
      */
   public void stop() {   
	if (animationThread != null) {
         animationThread = null;
	   Reset = true;
      }
   }


   //----------------------------------------------------
   /** Each time around the loop, call paint and then
    *  take a short pause. The paint method will
    *  move the circles and draw them.
    */
   public void run() {
	Thread myThread = Thread.currentThread();
      // Really while animationThread not null
      while(animationThread==myThread) { 
         repaint();
         pause(100);
      }
   }



   //----------------------------------------------------
   // Returns an int from 0 to max (inclusive),
   // yielding max + 1 possible values.
   private int randomInt(int max) {
	double x = Math.floor((double)(max + 1) * Math.random());
      return((int)(Math.round(x)));
   }

   //----------------------------------------------------
   // Sleep for the specified amount of time.
   private void pause(int milliseconds) {
      try {
         Thread.sleep((long)milliseconds);
      } catch(InterruptedException ie) {}
   }
} // end of class BouncePanel

