// SimpleThreads2.java
// ExerciseD15.25
// Background is cleared between calls to paint
// All three ball threads have same default priority
// Bounces three colored balls inside an applet
// Implements Runnable for Thread
// APPLET CODE="SimpleThreads2" HEIGHT=350 WIDTH=620
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SimpleThreads2 extends JApplet implements Runnable, MouseListener {
	private int redX, redY;  // position of the red ball
	private int redXMove, redYMove;
	private int orangeX, orangeY;  // position of the orange ball
	private int orangeXMove, orangeYMove;
	private int magentaX, magentaY;  // position of the magenta ball
	private int magentaXMove, magentaYMove;

	private int n;  // number of balls
	private int size;  // size of the balls
	boolean isRedBall, isOrangeBall, isMagentaBall;

	Thread threadRed, threadOrange, threadMagenta;

	public void init( ) {
		n = 0;
		size = 50;
		redXMove = ( int ) ( 5 * Math.random( ) + 1 );
		redYMove = ( int ) ( 5 * Math.random( ) + 1 );
		orangeXMove = ( int ) ( 5 * Math.random( ) + 1 );
		orangeYMove = ( int ) ( 5 * Math.random( ) + 1 );
		magentaXMove = ( int ) ( 5 * Math.random( ) + 1 );
		magentaYMove = ( int ) ( 5 * Math.random( ) + 1 );

		isRedBall = false;  // so a ball won't be drawn on startup
		isOrangeBall = false;
		isMagentaBall = false;

		// applet listens to its own mouse events
		addMouseListener( this );
	}

	public void run( ) {
		Thread executingThread;
		
		while ( true ) {
			// sleep for .01 second
			try {
				Thread.sleep( 10 );
			}
			catch ( InterruptedException ex ) {
				ex.printStackTrace( );
			}

			executingThread = Thread.currentThread( );
			showStatus( "Executing thread:  " + executingThread.getName( ) );

			if ( executingThread == threadRed ) {
				redX += redXMove;

				if ( redX >= 562 || redX <= 4 )
					redXMove *= -1;  // reverse direction if wall is hit
				
				redY += redYMove;
				
				if ( redY >= 288 || redY <= 4 )
					redYMove *= -1;  // reverse direction if wall is hit
			}

			if ( executingThread == threadOrange ) {  
				orangeX += orangeXMove;

				if ( orangeX >= 562 || orangeX <= 4 )
					orangeXMove *= -1;  // reverse direction if wall is hit
				
				orangeY += orangeYMove;
				
				if ( orangeY >= 288 || orangeY <= 4 )
					orangeYMove *= -1;  // reverse direction if wall is hit
			}

			if ( executingThread == threadMagenta ) {
				magentaX += magentaXMove;

				if ( magentaX >= 562 || magentaX <= 4 )
					magentaXMove *= -1;  // reverse direction if wall is hit
				
				magentaY += magentaYMove;
				
				if ( magentaY >= 288 || magentaY <= 4 )
					magentaYMove *= -1;  // reverse direction if wall is hit
			}

			repaint( );
		}
	}

	public void paint( Graphics g ) {
		g.setColor( Color.blue );
		g.drawRect( 3, 3, 614, 340 );
		g.drawRect( 4, 4, 612, 338 );

		g.setColor( Color.white );
		g.fillRect( 5, 5, 610, 336 );

		if ( isRedBall ) {
			g.setColor( Color.red );
			g.fillOval( redX, redY, size, size );
		}

		if ( isOrangeBall ) {
			g.setColor( Color.orange );
			g.fillOval( orangeX, orangeY, size, size );
		}
		
		if ( isMagentaBall ) {
			g.setColor( Color.magenta );
			g.fillOval( magentaX, magentaY, size, size );
		}
	}

	public void mousePressed( MouseEvent e ) {
		n++;
		if ( n == 1 ) {
			isRedBall = true;
			redX = e.getX( );
			redY = e.getY( );
			threadRed = new Thread( this, "Red Thread" );
			threadRed.start( );
		}

		if ( n == 2 ) {
			isOrangeBall = true;
			orangeX = e.getX( );
			orangeY = e.getY( );
			threadOrange = new Thread( this, "Orange Thread" );
			threadOrange.start( );
		}

		if ( n == 3 ) {
			isMagentaBall = true;
			magentaX = e.getX( );
			magentaY = e.getY( );
			threadMagenta = new Thread( this, "Magenta Thread" );
			threadMagenta.start( );
		}

		repaint( );  // draws the balls for first time at mousePressed
	}

	// remaining methods of MouseListener interface
	public void mouseClicked( MouseEvent e ) { }
	public void mouseReleased( MouseEvent e ) { }
	public void mouseEntered( MouseEvent e ) { }
	public void mouseExited( MouseEvent e ) { }
}