/*

Ball.java

The Ball class controls the movement of a ball and playing
sounds when it hits a wall.

*/

import java.awt.*;
import java.lang.*;
import java.applet.*;


public class Ball implements Runnable {

    private String       name;
    private Color        color;

    private Stage        stage;

    private Thread       runner;

    private double       x0,  y0;    // Initial position in each dimension.
    private double       v0x, v0y;   // Initial velocity in each dimension.
    private double       ax,  ay;    // Acceleration in each dimension.
    private double       x,   y;     // Current position in each dimension.

    private double       t;
    private final double dt = 0.05;

    private final int    r  = 10;

    private int sleepy;



    //----- constructor
    public Ball( String n, Color c,Stage s,int sleepy ) {
        name = n;
        color = c;
        stage = s;
	this.sleepy = sleepy;
        // initial conditions.
        t = 0;
        x = x0 = 2*r;
	y = y0 = 2*r;
        v0x    = 2;   // velocity of 2 to the right
	v0y    = 0;
        ax     = 0;
	ay     = 0.1; // acceleration downward
        runner = null;
    } // end of Ball constructor



    //----- methods for stage object to call.

    public void start() {
        if ( runner == null ) {
            runner = new Thread( this,name );
            runner.start();
        } 
	else {
            runner.resume();
        }
    } // end of start()

    public void stop() {
        runner.suspend();
    } // end of stop()



    //----- methods for runner thread to run

    public void run() {
        while ( true ) {
            for ( int i=0; i<10; i++ ) {
                computeNewPosition();
            }
	    try {
		Thread.sleep( sleepy );
	    }
	    catch ( InterruptedException e ) {
		break;
	    }
        }
    } // end of run()

    public void setSleepy( int sleepy ) {
	this.sleepy = sleepy;
    } // end of setSleepy()

    public void paint( Graphics g ) {
        int size = 2 * r;
        g.setColor(color);
        g.fillOval((int)(x - r), (int)(y - r), size, size);
    } // end of paint()

    public String toString() {
	return name;
    } // end of toString()



    //----- private methods.

    private void computeNewPosition()  {

        boolean collisionX, collisionY;

        // update t and calculate one-dimensional motion with constant
        // acceleration in each dimension.
        t += dt;
        x = x0 + v0x*t + 0.5*ax*t*t;
        y = y0 + v0y*t + 0.5*ay*t*t;

        // detect collisions with walls.
        collisionX = ((x - r) <= 0 || (x + r) >= stage.size().width);
        collisionY = ((y - r) <= 0 || (y + r) >= stage.size().height);

        if ( collisionX || collisionY ) {
            // a collision occurred, so set initial conditions to
            // current conditions and reset t.  Reverse velocity in
            // any dimension in which a collision occurred.
            v0x = v0x + ax * t;
            v0y = v0y + ay * t;
            if (collisionX)  v0x = -v0x;
            if (collisionY)  v0y = -v0y;
            x0 = x;
            y0 = y;
            t = 0;
	    // play sound
	    stage.bounce.sound.play();
	    System.out.println( "bounce!" );
        }
    } // end of computeNewPosition()



} // end of Ball class
