/* fluctuation.java - jpq - 08/02/00 - 03/03/00
 * 8/05/00
 * ajout de main() le 05/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 = 180205L;
  controles C;
  dessin D;

  public void init ()
  { setLayout (new BorderLayout ());
    D = new dessin (313, 414, 20, 100, 50);
    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 = 180205L;
  Image img;
  Graphics g;
  int w, w1, h, totaln, totalb;
  double he;
  boolean retrace;
  int dt, nN, nB, nt, Nsimul;
  Random rnd;

  public dessin (int nN, int nB, int nt, int Nsimul, int dt)
  { retrace = true;
    this.nN = nN;
    this.nB = nB;
    this.nt = nt;
    this.Nsimul = Nsimul;
    this.dt = dt;
    rnd = new Random ();
  }

  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 || h != getSize().height)
    { w = getSize().width;
      w1 = w - 50;
      h = getSize().height;
      img = createImage (w, h);
      g = img.getGraphics ();
    }
    if (retrace)
    { retrace = false;
      totaln = 0;
      totalb = 0;
      int i = w1;
      for (int j = 0; j < Nsimul; j ++)
      { if (i >= w1)
        { i = 0;
          efface (g);
        }
        int dn = 0, db = 0;

        int nNpnB = nN + nB;
        for (int k = 0; k < nt; k ++) if ((int)(rnd.nextDouble () * nNpnB --) + 1 <= nB - db) db ++; else dn ++;

        totaln += dn;
        totalb += db;
        g.setColor (Color.white);
        g.fillRect (w1, 0, 50, h);
        g.setColor (Color.black);
        g.drawRect (w1, 0, 49, h - 1);
        g.fillRect (w1 + 10, (int)((1.0 - (double)(dn) / (double)(dn + db)) * h), 10, h);
        g.drawRect (w1 + 30, (int)((1.0 - (double)(db) / (double)(dn + db)) * h), 10, h);
        he = (double)(totaln) / (totaln + totalb);
        g.fillRect (i, (int)((1.0 - he) * h), 3, 3);
        i = i + 3;
        g1.drawImage (img, 0, 0, this);
        try { Thread.sleep (dt); }
        catch (InterruptedException e) {}
      }
    }

    g.drawString ("nbre de boules tirées : " + Integer.toString (totaln + totalb) + "; boules noires obtenues : " + Integer.toString (totaln), 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 = 180205L;
  dessin D;
  TextField tNsimul, tdt;
  Button ok;
  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)
  { TextField tf = new TextField (Integer.toString (n));
    tf.setFont (f);
    return tf;
  }

  public controles (dessin D)
  { f = new Font ("Arial", Font.PLAIN, 10);
    this.D = D;
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    add (ajoutlbl ("Nombre de boules tirées : " + Integer.toString (D.nt) + ". Nbr. de simulations :"));
    add (tNsimul = ajouttf (D.Nsimul));
    add (ajoutlbl ("dt :"));
    add (tdt = ajouttf (D.dt));
    add (ok = new Button ("Ok"));
    ok.setFont (f);
    ok.addActionListener (this);
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { try { D.Nsimul = Integer.parseInt (tNsimul.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.Nsimul <= 0) D.Nsimul = 1;
      tNsimul.setText (Integer.toString (D.Nsimul));
      try { D.dt = Integer.parseInt (tdt.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.dt < 0) D.dt = 0;
      tdt.setText (Integer.toString (D.dt));
      D.retrace = true;
      D.repaint ();
    } 
  }

}

////////////////////////////////////////////////////////////////////////////////

	public static void main (String [] args) {

// Création et lancement de l'applet
		fluctuation a = new fluctuation();
		a.init ();
		a.start ();

// Création de la fenêtre contenant l'applet
		Frame f = new Frame ("fluctuation");
		f.addWindowListener (new fermer ());
		f.add (a);
		f.setSize (500, 200);
		f.setVisible (true);
	}

// Permet la fermeture de la fenêtre contenant l'applet
	protected static final class fermer extends WindowAdapter {
		public void windowClosing (WindowEvent we) {
			System.exit (0);
		}
	}
}
