package javacodebook.thread.animation;

import java.util.Random;
import java.awt.*;

/**
 * Der Thread für die eigentliche Animation. Er dient dazu, alle 200 ms einen
 * Kreis einer zufälligen Farbe an eine zufällige Stelle im Zeichenbereich
 * zu zeichnen.
 *
 * @author Mark Donnermeyer
 */
public class AnimatorThread extends Thread {
    private static Random random = new Random(System.currentTimeMillis());
    
    // Die Grösse der Kreise.
    private static int SIZE = 80;
    
    private Canvas animationArea;
    private Color  color;
    private int xMax;
    private int yMax;
    
    private boolean stop = false;
    
    /**
     * Ein neuer AnimatorThread zum zeichnen von Kreisen.
     * @param color Die Farbe, in der die Kreise gezeichnet werden sollen
     * @param animationArea Hier soll reingezeichnet werden
     */
    public AnimatorThread(Color color, Canvas animationArea) {
        this.animationArea = animationArea;
        this.color = color;
        
        // Die Grösse des Zeichenbereiches. Da sie sich nicht ändert, kann man
        // sie einmal am Anfang abfragen und dann speichern.
        xMax = (int)animationArea.getSize().getWidth();
        yMax = (int)animationArea.getSize().getHeight();
    }
    
    public void run() {
        int x,y;
        
        // Der Thread läuft solange, bis er ein Stop-Signal empfangen hat.
        while(!stop) {
            // Wo soll der Kreis hin?
            // Aufpassen, dass kein Kreis über den Rand gezeichnet wird!
            x = random.nextInt(xMax - SIZE);
            y = random.nextInt(yMax - SIZE);
            
            // Das Zeichnen erfolgt in einem synchronisierten Block. Damit wird
            // sichergestellt, dass während des Zeichnens eines Kreises kein
            // anderer Thread in den Bereich zeichnet.
            synchronized(animationArea) {
                Graphics g = animationArea.getGraphics();
                g.setColor(color);
                g.fillArc(x, y, SIZE, SIZE, 0, 360);
            }
            
            // Nach getaner Arbeit legt sich der Thread für 200 ms schlafen.
            try {
                sleep(200);
            }
            catch (Exception ignore) {}
        }
    }
    
    /**
     *  Mit dieser Methode kann der Thread gestoppt werden.
     */
    public void stopExecution() {
        stop = true;
    }
}

