/* pfmaxth.java - jpq - 30/06/00
 * modification et ajout de main() le 12/02/18
 * JFrame, JPanel et modifications le 26/02/21
 */

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;

public class pfmaxth extends JPanel {
  static final long serialVersionUID = 210226L;
  controles C;
  dessin D;
  table T;
  int nl = 100;
  int nc = 10;
  int arrond = 2;
  double darrond = 100.0;

  public pfmaxth() {
	setLayout (new BorderLayout ());
    D = new dessin();
    T = new table();
    C = new controles();
    add ("North", C);
    add ("South", T);
    add ("Center", D);
  }

////////////////////////////////////////////////////////////////////////////////

protected class dessin extends Panel {
  static final long serialVersionUID = 210226L;
  Image img;
  Graphics g;
  int w, h;
  int bsup;
  double p2nl, histogramme [], p [], p1 [];
  boolean retrace = true;

  private void h (Graphics g) {
	bsup = nc - 1;
    while (bsup >= 0 && histogramme [bsup] == 0)
	  bsup --;
    bsup ++;
    double max = 0;
    for (int i = 0; i < bsup; i ++) {
	  double hi = histogramme [i];
      if (hi > max)
	    max = hi;
    }
    g.setColor (Color.white);
    g.fillRect (1, 1, getSize().width - 2, getSize().height - 2);
    g.setColor (Color.yellow);
    g.drawLine (20, getSize().height - 40, getSize().width, getSize().height - 40);
    g.drawLine (20, 40, 20, getSize().height - 40);
    g.setColor (Color.blue);
    g.drawString ("0", 5, getSize().height - 40);
//    g.drawString (Double.toString (max), 5, 40);

    for (int j = 0; j < bsup; j ++) {
	  int x = j * (getSize().width - 50) / bsup + 50;
      int y = getSize().height - 40 - (int)(histogramme [j] * (getSize().height - 80) / (max));
      g.setColor (Color.black);
      g.drawLine (x, y, x, getSize().height - 40);
      g.setColor (Color.blue);
      g.drawString (Integer.toString (j + 1), x, getSize().height - 10);
    }
    g.setColor (Color.black);
    g.drawRect (0, 0, getSize().width - 1, getSize().height - 1);
  }

  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 (getSize().width, getSize().height);
      g = img.getGraphics ();
      g.setColor (Color.white);
      g.fillRect (1, 1, getSize().width - 2, getSize().height - 2);
      g.setColor (Color.black);
      g.drawRect (0, 0, getSize().width - 1, getSize().height - 1);
	  retrace = true;
    }
    if (histogramme == null || histogramme.length < nl) {
	  histogramme = new double [nl];
      p = new double [nl];
      p1 = new double [nl];
    }
    if (retrace) {
	  retrace = false;
      p2nl = Math.pow (2.0, nl - 1);
      histogramme [0] = (nc == 1) ? p2nl : 1;
      for (int i = 1; i < nc; i ++)
      { histogramme [i] = 0;
        p [0] = 1;
        for (int j = 1; j <= i; j ++) p [j] = 0;
        for (int j = 1; j < nl; j++) {
		  double p10 = 0.0;
          for (int k = 0; k < i; k ++)
		    p10 += p [k];
          p1 [0] = p10;
          for (int k = 1; k <= i; k ++)
		    p1 [k] = p [k - 1];
          p1 [i] += p [i] * 2.0;
          for (int k = 0; k <= i; k ++) p [k] = p1 [k];
        }
        histogramme [i] = p [i];
      }
      for (int i = 2; i < nc; i++)
	    histogramme [i - 1] -= histogramme [i]; 
      h (g);
      g1.drawImage (img, 0, 0, this);
    } else
	  g1.drawImage (img, 0, 0, this);
  }
}

////////////////////////////////////////////////////////////////////////////////

protected class controles extends Panel implements ActionListener {
  static final long serialVersionUID = 210226L;
  TextField tnl, tnc, tar;
  Button ok;
  Font f;

  private Label ajoutlbl (String s) {
	Label lbl = new Label (s);
    lbl.setFont (f);
    lbl.setBackground (Color.lightGray);
    return lbl;
  }

  private TextField ajouttf (int n, int n1) {
	TextField tf = new TextField (n);
    tf.setFont (f);
    tf.setText (Integer.toString (n1));
    return tf;
  }

  public controles() {
	Font f = new Font ("Arial", Font.PLAIN, 10);
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    add (ajoutlbl ("Nbr de lancers :"));
    add (tnl = ajouttf (5, nl));
    add (ajoutlbl ("Calculs jusqu'à :"));
    add (tnc = ajouttf (5, nc));
    add (ajoutlbl ("déc. :"));
    add (tar = ajouttf (1, 2));
    T.arrond = 2;
    T.darrond = 100.0;
    add (ok = new Button ("Ok"));
    ok.setFont (f);
    ok.addActionListener (this);
  }

  public void actionPerformed (ActionEvent e) {
    if (e.getSource () == ok) {
	  try {
	    nl = Integer.parseInt (tnl.getText ());
	  }
      catch (NumberFormatException nfe) { }
      if (nl <= 0)
	    nl = 1;
      tnl.setText (Integer.toString (nl));
      try {
	    nc = Integer.parseInt (tnc.getText());
	  }
      catch (NumberFormatException nfe) {}
      if (nc <= 0)
	    nc = 1;
      if (nc > nl)
	    nc = nl;
      tnc.setText (Integer.toString (nc));
	  int arr = arrond;
      try {
	    arr = Integer.parseInt (tar.getText ()); }
      catch (NumberFormatException nfe) {}
      if (arr > 0) {
		arrond = arr;
		T.darrond = Math.pow (10.0, arrond);
	  }
      tar.setText (Integer.toString (arrond));
      D.retrace = T.retrace = true;
      D.repaint ();
      T.repaint ();
    }
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class table extends Panel {
  static final long serialVersionUID = 210226L;
  TextArea ta;
  boolean retrace;
  int arrond;
  double darrond;

  public table() {
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    add (ta = new TextArea ("", 5, 50, TextArea.SCROLLBARS_HORIZONTAL_ONLY));
  }

  private String DSarrondi (double d) {
	if (arrond >= 0)
	  d = Math.floor (d * darrond + 0.5) / darrond;
    return Double.toString (d);
  }

  public void paint (Graphics g) {
	if (retrace) {
	  retrace = false;
      String s1 = "nombre max.";
      String s2 = "proba * 2^" + Integer.toString (nl) + "\t";
      String s3 = "probabilités\t";
      for (int i = 0; i < nc; i ++) {
		s1 += "\t" + Integer.toString (i + 1);
        s2 += Double.toString (D.histogramme [i]) + "\t";
        s3 += DSarrondi (D.histogramme [i] / D.p2nl) + "\t";
      }
 	  if (nc == nl)
        ta.setText (s1 + "\n" + s3 + "\n\n" + s2);
	  else
        ta.setText (s1 + " et plus\n" + s3 + "\n\n" + s2);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

  public static void main (String [] args) {

// Création et lancement de l'applet
    pfmaxth app = new pfmaxth();

// Création de la fenêtre contenant l'applet
    JFrame f = new JFrame ("pfmaxth");
    f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    f.add (app);
    f.setSize (500, 400);
    f.setVisible (true);
  }

}
