/* fluctuation.java - jpq - 08/02/00 - 03/03/00
 * 8/05/00 - 06/02/02
 * ajout de main() le 01/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;

public class fluctuation extends java.applet.Applet {
  static final long serialVersionUID = 180201L;
  controles C;
  dessin D;

  private int gparm (String s, int n) {
    try {
	  s = getParameter (s);
	  n = Integer.parseInt (s);
	}
	catch (NumberFormatException e) {}
    catch (NullPointerException e) {}
	return Math.max (n, 0);
  }

  public void init() {
	setLayout (new BorderLayout ());
    int NTR = gparm ("brouges", 35);
    int NTV = gparm ("bvertes", 65);
    int nt = gparm ("nt", 10);
    D = new dessin (NTR, NTV, nt);
    C = new controles (D);
    add (C, BorderLayout.NORTH);
    add (D, BorderLayout.CENTER);
  }

  public void destroy ()
  { remove (D); remove (C); }

  public String getAppletInfo ()
  { return "fluctuation par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Canvas {
  static final long serialVersionUID = 180201L;
  Image img;
  Graphics g;
  int w, w1, h, totR, totV, pos, yind;
  int [] y;
  double he;
  boolean retrace;
  int /* dt, */ nR, nV, nRpnV, nt;
  Random rnd;

  public dessin (int nR, int nV, int nt)
  { this.nR = nR;
    this.nV = nV;
    nRpnV = nR + nV;
    this.nt = nt;
//    dt = 0;
    totR = totV = 0;
    rnd = new Random ();
    retrace = true;
  }

  public void update (Graphics g)
  { paint (g); }

  private void efface (Graphics g)
  { g.setColor (Color.white);
    g.fillRect (0, 0, w, h);
    g.setColor (Color.black);
    g.drawRect (0, 0, w - 1, h - 1);
    g.setColor (Color.yellow);
    g.drawLine (0, h / 2, w1, h / 2);
    g.setColor (Color.blue);
    g.drawString ("1.0", w1 - 20, 11);
    g.drawString ("0.0", w1 - 20, h - 2);
    g.drawString ("0.5", w1 - 20, h / 2 - 2);
  }

  public void paint (Graphics g1)
  { if (img == null)
    { w = getSize().width;
      w1 = w - 50;
      h = getSize().height;
      img = createImage (w, h);
      g = img.getGraphics ();
      pos = 0;
      y = new int [w1];
      yind = 0;
    }
    if (retrace)
    { retrace = false;
      efface (g);
      g.setColor (Color.red);
      for (int j = 0; j < yind; j++)
        g.fillRect (j * 3, y [j], 3, 3);
      for (int j = 0; j < nt; j ++)
      { if (pos >= w1)
        { pos = yind = 0;
          efface (g);
        }
        if ((int)(rnd.nextDouble () * nRpnV) + 1 <= nR) totR ++; else totV ++;
        g.setColor (Color.white);
        g.fillRect (w1, 0, 50, h);
        g.setColor (Color.black);
        g.drawRect (w1, 0, 49, h - 1);
        he = (double)(totR) / (totR + totV);
        g.setColor (Color.red);
        g.fillRect (w1 + 10, (int)((1.0 - he) * h), 10, h);
        g.setColor (Color.green);
        g.fillRect (w1 + 30, (int)(he * h), 10, h);
        g.setColor (Color.red);
        int hi = (int)((1.0 - he) * h);
        g.fillRect (pos, hi, 3, 3);
        y [yind ++] = hi;
        pos += 3;
        g1.drawImage (img, 0, 0, this);
//        try { Thread.sleep (dt); }
//        catch (InterruptedException e) {}
      }
    }
    g.setColor (Color.black);
    int totRpV = totR + totV;
    if (totRpV != 0)
    { g.drawString ("nbr de boules tirées : " + Integer.toString (totRpV) + "; boules rouges obtenues : " + Integer.toString (totR), 0, 10);
      g.drawString ("soit une proportion de : " + new Double(he).toString(), 0, 20);
    }
    g1.drawImage (img, 0, 0, this);
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener {
  static final long serialVersionUID = 180201L;
  dessin D;
  TextField tnt /*, tdt */;
  Button ok, plus;
  Font f;

  private Label ajoutlbl (String s)
  { Label lbl = new Label (s);
    lbl.setBackground (Color.lightGray);
    lbl.setFont (f);
    return lbl;
  }

  private TextField ajouttf (int n, int k)
  { TextField tf = new TextField (Integer.toString (n), k);
    tf.setFont (f);
    return tf;
  }

  public controles (dessin D)
  { f = new Font ("Arial", Font.PLAIN, 10);
    this.D = D;
    setBackground (Color.lightGray);
//    add (ajoutlbl ("dt :"));
//    add (tdt = ajouttf (D.dt, 1));
    add (ajoutlbl ("Nombre de boules tirées : "));
    add (tnt = ajouttf (D.nt, 5));
    add (ok = new Button ("Ok"));
    ok.setFont (f);
    ok.addActionListener (this);
    add (plus = new Button ("+"));
    plus.setFont (f);
    plus.addActionListener (this);
  }

  public void actionPerformed (ActionEvent e)
  { if ((e.getSource () == ok) || (e.getSource () == plus))
    { int nn = D.nt;
      try { nn = Integer.parseInt (tnt.getText ()); }
      catch (NumberFormatException nfe) { }
      if (nn >= 0) D.nt = nn;
      tnt.setText (Integer.toString (D.nt));
//      try { D.dt = Integer.parseInt (tdt.getText ()); }
//      catch (NumberFormatException nfe) { }
//      if (D.dt < 0) D.dt = 0;
//      tdt.setText (Integer.toString (D.dt));
      if (e.getSource () == ok)
      { D.totR = D.totV = 0;
        D.pos = D.w1;
        D.yind = 0;
      }
      else if (D.nt == 0) tnt.setText (Integer.toString (++ D.nt));
      D.retrace = true;
      D.repaint ();
    } 
  }

}

////////////////////////////////////////////////////////////////////////////////

  public static void main (String [] args) {

    fluctuation fl = new fluctuation();
    fl.init();
    fl.start();

    Frame f = new Frame ("fluctuation");
    f.addWindowListener (new fermer ());
    f.add (fl);
    f.setSize (500, 200);
    f.setVisible (true);
  }

  protected static final class fermer extends WindowAdapter {
    public void windowClosing (WindowEvent e) {
      System.exit (0);
    }
  }
}
