import java.awt.*;

public class ObjetGraphique implements Runnable, Dessinable {
    static ThreadGroup tg = new ThreadGroup("ObjetsDessinables");

    protected int x, y;  // position du centre
    protected int largeur, hauteur; // Boite englobante de l'objet
    static int zone_l, zone_h; // taille de la zone ou l'objet a le droit de se promener
    static int nbObjetsCrees = 0;
    static int tempsEntreDeplacements = 10;

    // Constructeurs
    public ObjetGraphique(int x, int y, int largeur, int hauteur) {
        this.x = x;
        this.y = y;
        this.largeur = largeur;
        this.hauteur = hauteur;
        nbObjetsCrees++;
        new Thread(tg, this).start();
    }


    // Méthodes statiques
    
    /** On réveille tous les threads des objets graphiques */
    static public void suspend() {
        tg.suspend();
    }

    /** On stoppe les threads de tous les objets */
    static public void resume() {
        tg.resume();
    }

    /** Réglage de la zone rectangulaire dans laquelle vont se déplacer les objets */
    static public void setZoneEvolution(int w, int h) {
        zone_l = w;
        zone_h = h;
    }
    
    /** Renvoie le nombre d'instances d'ObjectGraphique */
    static public int getNbObjetsCrees() {
        return nbObjetsCrees;
    }
    
    /** Réglage du temps entre chaque déplacement des objets graphiques */
    static public void setTempsEntreDeplacements(int temps) {
        tempsEntreDeplacements = temps;
    }
    
    /** Renvoie le temps entre chaque déplacement des objets graphiques */
    static public int getTempsEntreDeplacements() {
        return tempsEntreDeplacements;
    }

    // Méthodes publiques
    public int getX() {
        return x;
    }

     public int getY() {
        return y;
    }
    
    public int getHauteur() {
        return hauteur;
    }
    
    public int getLargeur() {
        return largeur;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setHauteur(int hauteur) {
        this.hauteur = hauteur;
    }
    
    public void setLargeur(int largeur) {
        this.largeur = largeur;
    }

    public void move(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public String toString() {
        return((String) ("x = " + x + "\n" +
                         "y = " + y + "\n" +
                         "zone_l = " + zone_l + "\n" +
                         "zone_h = " + zone_h + "\n"));
    }

    public void dessineToi(Graphics gc) {
        gc.drawRect(x-1, y-1, 2, 2);
    }

    public void run() {
        int incX=1, incY=1;

        while(true) {

            int x = this.x, y = this.y;

            // On calcule la nouvelle position de l'objet

            x += Math.rint(Math.random() * incX);
            y += Math.rint(Math.random() * incY);


            // Pour ne pas que l'objet sorte de l'ecran
            if ((incX == 1) && ((x + (largeur/2)) > zone_l))
                incX = -1;

            if ((incX == -1) && (x - (largeur/2) < 0))
                incX = 1;

            if ((incY == 1) && (y + (hauteur/2) > zone_h))
                incY = -1;

            if ((incY == -1) && (y - (hauteur/2) < 0))
                incY = 1;


            // On déplace l'objet
            move(x, y);

            // On "dort" tempsEntreDeplacement millisecondes
            try {
                Thread.currentThread().sleep(tempsEntreDeplacements);
            } catch(InterruptedException e) {
                System.out.println("Erreur dans le sleep(tempsEntreDeplacements);");
                e.printStackTrace();
            }
        }
    }
}
