/*----------------------------------------------------------------------------
 * Klasse:		    Ball.java
 * Beschreibung:	Spielball im Golfspiel
 * Autor:		    Jack Meyer
 * Datum:		    Dezember, 1997
 * ---------------------------------------------------------------------------
 */

import java.awt.*;


class Ball extends Canvas implements Runnable {

    /*
     * Display Farbe des Balles, Klassenkonstante!
     */
    static final Color colorBall = new Color (255,255,255);
    /*
     * Grösse des Balles.
     */
    static private int durchmesser = 3;
    /*
     * Maximale Geschwindigkeit des Balls
     */
    static final int maxSpeed = 25;

    /*
     * laufende Position des Balles.
     */
    private Point position;
    /*
     * Geschwindigkeit des Balles.
     */
    private double speed;       // 0 .. maxSpeed
    private double direction;   // 0 .. 2*PI
    boolean showDirectionArrow;
    /*
     * eigener Prozess zum animieren des Balls
     */
    Thread animationThread;
    /*
     * für zugriff auf die aktuelle Bahn
     */
    Object myBahnverwalter;



    /*
     * Konstruktor
     */
    Ball (Object anObject) {
        position = new Point (0,0);
        speed = 0;
        direction = 0;
        showDirectionArrow = false;
        myBahnverwalter = anObject;
    };


    /*
     * Position und Geschwindigkeit setzen
     */
    void setPos  (int x, int y) {position.x = x; position.y = y;};
    void setPos  (Point p) {position = p;};
    Point getPos () {return position;};
    int getPosX () {return position.x;};
    int getPosY () {return position.y;};

    void setSpeedPercent (int speedPercent) { speed = speedPercent * maxSpeed / 100;};
    void setSpeed (double newSpeed) { speed = newSpeed;};
    double getSpeed () { return speed; };
    double getSpeedX () { return speed * Math.cos(direction);};
    double getSpeedY () { return speed * Math.sin(direction);};

    void setDirection (double newDirection) { direction = newDirection;};
    double getDirection () { return direction;};



    /*
     * bewege Ball
     */
    void move () {
        position.x = (int) (position.x + getSpeedX());
        position.y = (int) (position.y + getSpeedY());
    };




    public void start()
    {
//        System.out.println("Ball>>Start (start)" + animationThread);
//        if (animationThread == null)
//        {
              animationThread = new Thread(this);
              animationThread.start();
//        };
        System.out.println("Ball after Start (start)" + animationThread);
    }

    public void stop()
    {
        System.out.println("Ball>>Stop (stop)" + animationThread);
        if (animationThread != null)
        {
            System.out.println("Jetzt stoppen wir");
            animationThread.stop();
            // hier kommen wir nie an !!!!
            System.out.println("Jetzt ist gestoppt");
            animationThread = null;
            System.out.println("und auf null gesetzt");
        };
        System.out.println("Ball after Stop (stop)" + animationThread);
    }

    public void run()
    {
        System.out.println("Ball>>Run (run)");
        showDirectionArrow = false;
        while (this.getSpeed() > 0)
        {
            // check for collisions during next move
            ((BahnVerwalter)(myBahnverwalter)).collisionDetection(this);
            // do the animation
            this.move();
//            System.out.println("Ball moved");
            this.repaint();
            // check if stop
            if (this.getSpeed() <= 0.5) {
                this.setSpeed(0.0);
//                this.stop();
            };

            try { Thread.sleep(100); }
            catch (InterruptedException e) { }
        }

    };


    public void init() {
        System.out.println("Ball>>init");
        this.reshape(position.x-durchmesser/2, position.y-durchmesser/2,durchmesser,durchmesser);
    };


    public void paint(Graphics g)
    {
//        System.out.println("Ball wird gezeichnet bei: ("+position.x+","+position.y+") mit v: ("+speedX+","+speedY+")");
//        System.out.println("Ball wird gezeichnet bei: ("+position.x+","+position.y+") mit v: "+speed+" und D:"+direction);
        // verschiebe ganzer Canvas
        this.move (position.x-durchmesser/2, position.y-durchmesser/2);
        g.setColor(colorBall);
        g.fillOval(0,0, durchmesser, durchmesser);
    };


    public void drawArrow (Graphics g)
    {
        // ACHTUNG Graphic g in Minigolf Applet Koordinaten !!!
        // direction Arrow
        if (showDirectionArrow) {
            g.setColor(Color.white);
            g.drawLine(position.x,position.y,position.x+(int)(30*Math.cos(direction)),position.y+(int)(30*Math.sin(direction)));
            g.drawLine(position.x+(int)(30*Math.cos(direction)),position.y+(int)(30*Math.sin(direction)),  (int)(position.x+30*Math.cos(direction)+5*Math.cos(direction+Math.PI*3/4)),(int)(position.y+30*Math.sin(direction)+5*Math.sin(direction+Math.PI*3/4))  );
            g.drawLine(position.x+(int)(30*Math.cos(direction)),position.y+(int)(30*Math.sin(direction)),  (int)(position.x+30*Math.cos(direction)+5*Math.cos(direction-Math.PI*3/4)),(int)(position.y+30*Math.sin(direction)+5*Math.sin(direction-Math.PI*3/4))  );
        };

    };


    boolean newDirectionSet(int mouseX, int mouseY) {
        // distance to Ball
        int deltaX = mouseX-position.x;
        int deltaY = mouseY-position.y;
        double distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);
        if ((distance < 30) && (distance > 0)) {
//            System.out.println("Mose near Ball with distance: "+distance);
            showDirectionArrow = true;
            if (deltaX >0) {
                direction = Math.asin(deltaY/distance);}
            else {
                direction = Math.PI - Math.asin(deltaY/distance);};
//            System.out.println("new Direction:"+direction);
//            this.repaint();
            return true;
        };
        return false;
    };



};