/* racine2.java - jpq - 19/02/09
 * modification et ajout de main() le 12/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;

public class racine2 extends java.applet.Applet {
  static final long serialVersionUID = 180212L;
  controles C;
  dessin D;

  private int gparmi (String s, int i) {
    try {
      s = getParameter (s);
      i = Integer.parseInt (s);
    }
    catch (NumberFormatException e) {}
    catch (NullPointerException e) {}
    return i;
  }

  public void init ()
  { setFont (new Font ("Arial", Font.PLAIN, 10));
  	setLayout (new BorderLayout ());
    D = new dessin (gparmi ("nboulesb", 20), gparmi ("nboulesr", 1000), gparmi ("dimb", 3));
    C = new controles (D, gparmi ("delai", 10));
    add (C, BorderLayout.NORTH);
    add (D, BorderLayout.CENTER);
  }

  public void destroy ()
  { remove (D); remove (C); }

  public String getAppletInfo ()
  { return "racine2 par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Panel {
  static final long serialVersionUID = 180212L;
  Image img;
  Graphics g;
  int nboulesb, nboulesr, total, w, h, dimb, dimb2;
  int [] x, y;
  Color [] c;
  boolean retrace, reinit;
  Random rnd;
  
  public dessin (int nboulesb, int nboulesr, int dimb)
  { this.nboulesb = nboulesb;
    this.nboulesr = nboulesr;
    this.dimb = dimb;
    dimb2 = 2 * dimb + 1;
    rnd = new Random ();
    reinit = retrace = true;
  }

  public void update (Graphics g)
  { paint (g);
  }

  public void paint (Graphics g1)
  { if (img == null || w != getSize().width || h != getSize().height)
    { w = getSize().width;
      h = getSize().height;
      img = createImage (w, h);
      g = img.getGraphics ();
	  reinit = true;
    }
    if (reinit)
    { reinit = false;
      g.setColor (Color.black);
      g.fillRect (0, 0, w, h);
      total = nboulesb + nboulesr;
      x = new int [total];
      y = new int [total];
      c = new Color [total];
      for (int i = 0; i < nboulesb; i++)
      { x [i] = rnd.nextInt (w);
      	y [i] = rnd.nextInt (h);
       	c [i] = Color.blue;
      }
      for (int i = nboulesb; i < total; i++)
      { x [i] = rnd.nextInt (w);
        y [i] = rnd.nextInt (h);
        c [i] = Color.red;
      }
    }
    if (retrace)
    { retrace = false;
    	for (int i = 0; i < total; i++)
      { g.setColor (c[i]);
      	g.fillOval (x [i] - dimb, y [i] - dimb, dimb2, dimb2);
      }
    }
    g1.drawImage (img, 0, 0, this);
  }
}

////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener, Runnable {
  static final long serialVersionUID = 180212L;
  dessin D;
  TextField tboulesb, tboulesr;
  Button ok;
  Thread th;
  Label bsr;
  int delai;

  private TextField atf (String s, int n)
  { Label lbl = new Label (s);
    lbl.setBackground (Color.lightGray);
    add (lbl);
    TextField tf = new TextField (n);
    return tf;
  }

  private TextField ajouttf (String s, int n, int n1)
  { TextField tf = atf (s, n);
    tf.setText (Integer.toString (n1));
    return tf;
  }

  private Button ajoutb (String s)
  { Button b = new Button (s);
    b.addActionListener (this);
    return b;
  }

  public controles (dessin D, int delai)
  { this.D = D;
  	this.delai = delai;
    setBackground (Color.lightGray);
    add (tboulesb = ajouttf ("Nombre de boules bleues:", 5, D.nboulesb));
    add (tboulesr = ajouttf ("Nombre de boules rouges:", 5, D.nboulesr));
    add (ok = ajoutb ("ok"));
    bsr = new Label ("b / total =      ");
    bsr.setBackground (Color.white);
    add (bsr);
    th = new Thread (this);
    th.start ();
  }

  private int pint (TextField tf, int n)
  { int i = n;
  	try { i = Integer.parseInt (tf.getText ()); }
    catch (NumberFormatException nfe) { }
    if (i <= 0) i = n;
    tf.setText (Integer.toString (i));
    return i;  
  }

  public void run ()
  { while (D.total == 0);
  	while (true)
    { try { Thread.sleep (delai); }
      catch (InterruptedException e) { }
      int j1, i1;
      j1 = i1 = D.rnd.nextInt (D.total);
      while (j1 == i1)
        j1 = D.rnd.nextInt (D.total);
      if (D.c [i1] == D.c [j1])
      { if (D.c [i1] == Color.blue)
      	{ D.c [i1] = Color.red;
      		D.nboulesb --;
      		D.nboulesr ++;
      	}
      	else
      	{ D.c [i1] = Color.blue;
      		D.nboulesr --;
      		D.nboulesb ++;
      	}
      }
      else
      { D.c [i1] = D.c [j1] = Color.blue;
    		D.nboulesr --;
     		D.nboulesb ++;
      }
      D.retrace = true;
      D.repaint ();
      C.bsr.setText ("b / total = " + (double)(D.nboulesb * 100 / D.total) / 100.0);
    }
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { D.nboulesb = pint (tboulesb, D.nboulesb);
    	D.nboulesr = pint (tboulesr, D.nboulesr);
    	D.reinit = D.retrace = true;
      D.repaint ();
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

    public static void main (String [] args) {
        int w = 600;
        int h = 400;

// Création et lancement de l'applet
        racine2 p = new racine2();
        p.init ();
        p.start ();

// Création de la fenêtre contenant l'applet
        Frame f = new Frame ("racine2");
        f.addWindowListener (new fermer ());
        f.add (p);
        f.setSize (w, h);
        f.setVisible (true);
    }

// Permet la fermeture de la fenêtre contenant l'applet
    protected static final class fermer extends WindowAdapter {
        public void windowClosing (WindowEvent e) {
            System.exit (0);
        }
    }
}
