import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import Cercle;

public class AnimCircle extends Applet implements Runnable,ActionListener {
    Thread threadDeApplet;
    Vector listeCercles = new Vector();

    // Un constructeur dans une Applet ? Très pratique pour gérer les événements !
    public AnimCircle() {

        // Classe anonyme interne pour gérer l'événement regetSize()
        ComponentListener resizeCallback = new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // Définition de la zone d'évolution des cercles
                Cercle.setZoneEvolution(getSize().width, getSize().height);

                System.out.println("Applet retaillée !");
            }
        }; // Fin de la classe anonyme

        // On indique qu'en cas de retaillage de l'Applet, c'est l'objet resizeCallback
        // qui va traiter l'événement
        addComponentListener(resizeCallback);
    }


    public void init() {

        // Creation de cercles animés
        listeCercles.addElement(new Cercle(100, 100, 10));
        listeCercles.addElement(new Cercle(100, 100, 20));
        listeCercles.addElement(new Cercle(100, 100, 30));

        // bouton pour suspendre l'animation des cercles
        Button b1 = new Button("Suspendre l'animation");
        add(b1);
        b1.addActionListener(this);

        // bouton pour reprendre l'animation des cercles
        Button b2 = new Button("Reprendre l'animation");
        add(b2);
        b2.addActionListener(this);

        // bouton pour ajouter un nouveau cercle
        Button b3 = new Button("Ajouter un cercle");
        add(b3);
        b3.addActionListener(this);
}

    public void start(){
        // Si le thread de l'applet vaut null
        if(threadDeApplet == null) {
             // Pn crée d'un Thread à partir de l'applet et on le lance
             threadDeApplet = new Thread(this);
             threadDeApplet.start();
        }
        else {
            // Le thread existe déjà, on le réveille
            threadDeApplet.resume();
        }

        // On réveille les cercles...
        Cercle.resume();
    }

    public void stop() {
        // On suspend tous les threads : celui de l'applet et les cercles
        threadDeApplet.suspend();
        Cercle.suspend();
    }

    /** Tache de fond executee par le Thread. Effectue l'animation du cercle en
        modifiant ses coordonnees et en invoquant repaint(), ce qui provoque l'execution
        de paint(). Notez que run() doit impérativement contenir une boucle afin de ne pas
        rendre la main tout de suite.
    */
    public void run() {

        while(true) {
            // On demande à redessiner le cercle
            repaint();

            // On "dort" 10 millisecondes
            try {
                threadDeApplet.sleep(10);
            } catch(InterruptedException e) {
                System.out.println("Erreur dans le sleep(10);");
                e.printStackTrace();
            }
        }
    }

    public void actionPerformed(ActionEvent evt) {
        String arg = evt.getActionCommand();

        if(arg.equals("Suspendre l'animation")) {
            threadDeApplet.suspend();
            Cercle.suspend();
        } else if(arg.equals("Reprendre l'animation")) {
            threadDeApplet.resume();
            Cercle.resume();
        } else if(arg.equals("Ajouter un cercle")) {
            listeCercles.addElement(new Cercle(100, 100, (int) (10 + Math.rint(Math.random() * 20))));
        }
    }



    public void paint(Graphics gc) {
        // appelé automatiquement par l'AWT, ou sur demande par repaint()
        Enumeration liste = listeCercles.elements();
        Cercle cercle;

        while(liste.hasMoreElements()) {
            cercle = (Cercle) liste.nextElement();

            gc.drawOval(cercle.getX() - cercle.getRayon(),
                    cercle.getY() - cercle.getRayon(),
                    2 * cercle.getRayon(),
                    2 * cercle.getRayon());
        }
    }
}
