/* racine2courbe.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 racine2courbe 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));
    C = new controles (D, gparmi ("delai", 10));
    add (C, BorderLayout.NORTH);
    add (D, BorderLayout.CENTER);
  }

  public String getAppletInfo ()
  { return "racine2courbe par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Panel {
  static final long serialVersionUID = 180212L;
  Image img;
  Graphics g;
  int nboulesb, nboulesr, total, w, h, abs, racine2, ntirages;
  boolean retrace, reinit;
  Random rnd;
  
  public dessin (int nboulesb, int nboulesr)
  { this.nboulesb = nboulesb;
    this.nboulesr = nboulesr;
    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 ();
      racine2 = (int)((1.0 - Math.sqrt (0.5)) * h);
      abs = w;
	  reinit = true;
    }
    if ((reinit) || (abs >= w))
    { if (reinit)
    	{ reinit = false;
    		total = nboulesb + nboulesr;
    		ntirages = 0;
    	}
      g.setColor (Color.white);
      g.fillRect (0, 0, w, h);      
      abs = 0;
    	g.setColor (Color.yellow);
     	g.drawLine (0, racine2, w, racine2);
    }
    if (retrace)
    { retrace = false;
    	g.setColor (Color.blue);
      g.fillRect (abs ++, h - nboulesb * h / total, 1, 1);
      ntirages ++;
    }
    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, tntirages;
  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 ("Boules bleues :", 5, D.nboulesb));
    add (tboulesr = ajouttf ("Boules rouges :", 5, D.nboulesr));
    add (ok = ajoutb ("ok"));
    tntirages = new Label ("nbre tirages =      ");
    tntirages.setBackground (Color.white);
    add (tntirages);
    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 i1 = D.rnd.nextInt (D.total);
      int j1 = D.rnd.nextInt (D.total);
      if ((i1 < D.nboulesb) && (j1 < D.nboulesb))
      { D.nboulesb --;
      	D.nboulesr ++;
      }
      else
      { D.nboulesb ++;
      	D.nboulesr --;
      }
      D.retrace = true;
      D.repaint ();
      C.tntirages.setText ("nbre tirages = " + D.ntirages);
      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
        racine2courbe p = new racine2courbe();
        p.init ();
        p.start ();

// Création de la fenêtre contenant l'applet
        Frame f = new Frame ("racine2courbe");
        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);
        }
    }

}
