import java.awt.*;
import java.awt.geom.*;

public class Ball {

    private double presentX;
    private double presentY;

    private double highlightX = 10.0;
    private double highlightY = 10.0;

    private double radius = 50.0;
    private double highlightRadius = 10.0;
    private Color color = Color.red;
    private Color highlightColor = Color.white;
    private Color shadowColor = Color.black;

    private int direction;
    private double inc;
    private double angInc;

    private int fieldWidth;
    private int fieldHeight;

    private final static int RIGHT = 0;
    private final static int RIGHT_DOWN = 1;
    private final static int DOWN = 2;
    private final static int LEFT_DOWN = 3;
    private final static int LEFT = 4;
    private final static int LEFT_UP = 5;
    private final static int UP = 6;
    private final static int RIGHT_UP = 7;

    public Ball(int fieldWidth, int fieldHeight){
        this.fieldWidth = fieldWidth;
        this.fieldHeight = fieldHeight;

        presentX = Math.random() * fieldWidth;
        presentY = Math.random() * fieldHeight;
        
        inc = Math.random() * 20.0;
        angInc = inc / Math.sqrt(2.0);

        direction = (int)(Math.random() * 8.0);

    }

    public synchronized void turn(){
        direction++;
        if(direction > RIGHT_UP){
            direction = RIGHT;
        }
    }

    public synchronized void move(){
        switch(direction){
          case RIGHT:
            presentX += inc;
            break;
          case RIGHT_DOWN:
            presentX += angInc;
            presentY += angInc;
            break;
          case DOWN:
            presentY += inc;
            break;
          case LEFT_DOWN:
            presentX -= angInc;
            presentY += angInc;
            break;
          case LEFT:
            presentX -= inc;
            break;
          case LEFT_UP:
            presentX -= angInc;
            presentY -= angInc;
            break;
          case UP:
            presentY -= inc;
            break;
          case RIGHT_UP:
            presentX += angInc;
            presentY -= angInc;
            break;
        }
            
        if(presentX > fieldWidth){
            presentX = -radius;
        }else if(presentX < -radius){
            presentX = fieldWidth;
        }

        if(presentY > fieldHeight){
            presentY = -radius;
        }else if(presentY < -radius){
            presentY = fieldHeight;
        }
    }

    public void draw(Graphics2D g){
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
        g.setPaint(color);
        g.fill(new Ellipse2D.Double(presentX, presentY, radius, radius));

        g.setPaint(highlightColor);
        g.fill(new Ellipse2D.Double(presentX + highlightX, presentY + highlightY,
                                    highlightRadius, highlightRadius));
    }

    public void drawShadow(Graphics2D g){
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
        g.setPaint(shadowColor);
        g.fill(new Ellipse2D.Double(presentX + radius * .1, presentY + radius * .8,
                                    radius, radius * .3));
    }
}
