import java.util.Scanner;
import java.util.Random;
import java.awt.*;

/*
 * Program to simulate dropping golf balls on a target.
 */

public class Target
{   
    /*
     * The main method gets the window size and target size from the
     * user. Then it draws the initial window. Finally it calls
     * the method to drop the gold balls.
     */
    public static void main(String[] args){
        Scanner s = new Scanner(System.in);        
        System.out.println("What size window do you want?");
        int winSize = getIntInRange(s, 100, 1000);
        System.out.println("What size target do you want?");
        int tgtSize = getIntInRange(s, 10, winSize / 2);
        DrawingPanel win = drawWindow(winSize, tgtSize);
        drop(win, winSize, tgtSize);
    }
    
    /*
     * Method to drop the balls until a hit on the target
     */
    public static void drop(DrawingPanel p, int winSize, int tgtSize){
        //coordinates of ball
        int x;
        int y;
        Random r = new Random();
        final int BALL_SIZE = 5;
        final int LIMIT = winSize - BALL_SIZE; //so we don't draw balls that go off screen
        Graphics g = p.getGraphics();
        g.setColor(Color.WHITE);
        
        // keep dropping balls until a hit
        do{
            x = r.nextInt(LIMIT);
            y = r.nextInt(LIMIT);
            g.fillOval(x, y, BALL_SIZE, BALL_SIZE);
            p.sleep(10);
        }while(!hit(winSize, tgtSize, x, y, BALL_SIZE) );
    }
    
    // determine if hit. x and y are upper left corner of bounding
    // box for golf ball.
    // figure center coordinates of target and ball.
    // calculate distance between them.
    // return true if distance between centers is less than or
    // equal to sum of the radius of the target and the ball
    public static boolean hit(int winSize, int tgtSize, int x, int y, int ballSize){
        int centerXTarget = winSize / 2;
        int centerYTarget = winSize / 2;
        int radiusOfTarget = tgtSize / 2;
        int centerXBall = x + ballSize / 2;
        int centerYBall = y + ballSize / 2;
        double distance = Math.pow(centerXTarget - centerXBall, 2);
        distance += Math.pow(centerYTarget - centerYBall, 2);
        distance = Math.sqrt( distance );
        return distance <= (radiusOfTarget + ballSize / 2);
    }
    
    // draw the initial window
    public static DrawingPanel drawWindow(int winSize, int tgtSize){
        int coord = winSize / 2 - tgtSize / 2;
        DrawingPanel p = new DrawingPanel(winSize, winSize);
        p.setBackground( Color.GRAY );
        Graphics g = p.getGraphics();
        g.setColor(Color.RED);
        g.fillOval(coord, coord, tgtSize, tgtSize);
        return p;
    }
    
    // get value between min and max inclusive
    // max > min
    public static int getIntInRange(Scanner s, int min, int max){
        System.out.println("Please enter a value between " + min 
            + " and " + max + ".");
        int result = getInt(s);
        while( result < min || result > max ){
            //out of range
            System.out.println( result + " is out of range.");
            System.out.println("Please enter a value between " + min 
                + " and " + max + ".");
            result = getInt(s);
        }
        assert result >= min && result <= max;
        return result;
    }
    
    // prompt user for an int
    public static int getInt(Scanner s){
        String temp;
        int result;
        
        System.out.print("Enter an integer: ");
        while( !s.hasNextInt() ){
            // bad input
            temp = s.nextLine();
            System.out.println( temp + " is not an integer.");
            System.out.print("Enter an integer: ");
        }
        assert s.hasNextInt();
        result = s.nextInt();
        s.nextLine();
        return result;      
    }
}
