package javacodebook.thread.animation;

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Vector;

/**
 * Der Demo-Frame für die Animation
 *
 * @author Mark Donnermeyer
 */
public class AnimationFrame extends Frame implements ActionListener {
    // Der Zeichenbereich für die Thread. Quasi die Spielwiese
    private Canvas animationArea;
    
    // Eine Liste aller zur Zeit laufender AnimatorThreads.
    private Vector animatorVector;
    
    private Button more;
    private Button less;
    private Button close;
    private Label  label;
    
    private static Random random = new Random(System.currentTimeMillis());
    
    public AnimationFrame() {
        super("Animation mittels Thread");
        
        
        initComponents();
        
        animatorVector = new Vector();
        
        // Ein Thread zum Säubern des Zeichenbereiches wird gestartet.
        CleanerThread cleaner = new CleanerThread(animationArea);
        cleaner.start();
    }
    
    private void initComponents() {
        // Buttons zum Starten und Stoppen von AnimatorThreads sowie zum
        // Beenden der gesamten Anwendung.
        more  = new Button("Mehr");
        less  = new Button("Weniger");
        close = new Button("Schliessen");
        
        more.addActionListener(this);
        less.addActionListener(this);
        close.addActionListener(this);
        
        more.setActionCommand("more");
        less.setActionCommand("less");
        close.setActionCommand("close");
        
        // In diesem Label wird angezeigt, wie viele Threads zur Zeit laufen.
        // Sind am Anfang 0
        label = new Label("Anzahl Animator-Threads: 0");
        
        // Anordnung der Buttons und des Labels in einer Reihe
        Panel buttonPanel = new Panel(new FlowLayout(FlowLayout.CENTER));
        buttonPanel.add(more);
        buttonPanel.add(less);
        buttonPanel.add(close);
        buttonPanel.add(label);
        
        // Hier nun endlich der Zeichenbereich, in den die AnimatorThread
        // ihre Kreise zeichnen dürfen.
        animationArea = new Canvas();
        animationArea.setSize(new Dimension(600, 400));
        
        // Als letztes werden die Buttons und der Canvas in den Frame gesetzt.
        setLayout(new BorderLayout());
        add("South", buttonPanel);
        add("Center", animationArea);
        
        // Da zu Beginn kein Thread läuft, kann man auch den Button "weniger"
        // nicht nutzen. Daher wird er erst einmal deaktiviert.
        less.setEnabled(false);
        
        pack();
    }
    
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        // Der Benutzer möchte die Anwendung verlassen.
        if (command.equals("close")) {
            System.exit(0);
        }
        // Es soll ein weitere Thread gestartet werden.
        else if (command.equals("more")) {
            // Zunächst eine zufällige Farbe für die Kreise wählen.
            int red   = random.nextInt(255);
            int green = random.nextInt(255);
            int blue  = random.nextInt(255);
            Color color = new Color(red, green, blue);
            
            // Einen neuen AnimatorThread erzeugen und starten.
            AnimatorThread newThread = new AnimatorThread(color, animationArea);
            newThread.start();
            
            // Der Thread kommt in den Vector, damit er später wieder gestoppt
            // werden kann.
            animatorVector.add(newThread);
            
            // Da nun mind. ein Thread läuft, kann man auch den Button "weniger"
            // nutzen.
            less.setEnabled(true);
            
            // Die Anzeige für die Anzahl der laufenden Thread aktualisieren
            int threadCount = animatorVector.size();
            label.setText("Anzahl Animator-Threads: " + threadCount);
        }
        else if (command.equals("less")) {
            // Der Thread, der zuerst gestartet wurde, wird gestoppt und aus
            // der Liste der laufenden Threads entfernt.
            AnimatorThread thread = (AnimatorThread)animatorVector.remove(0);
            thread.stopExecution();
            
            // Wenn kein Thread mehr läuft muß der Button "weniger" deaktiviert
            // werden
            int threadCount = animatorVector.size();
            if (threadCount == 0)
                less.setEnabled(false);
            
            // Die Anzeige für die Anzahl der laufenden Thread aktualisieren
            label.setText("Anzahl Animator-Threads: " + threadCount);
        }
    }
}