/* rang.java - jpq - 27/06/00 - 30/08/00
 * modification et ajout de main() le 13/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;


public class rang extends java.applet.Applet {
  static final long serialVersionUID = 180213L;
  controles C;
  dessin D;
  table T;

  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 ()
  { setLayout (new BorderLayout ());
    int n = gparmi ("n", 52);
    int k = gparmi ("k", 4);
    int nsimul = gparmi ("nsimul", 100);
    D = new dessin (n, k, nsimul);
    T = new table (D);
    C = new controles (D, T);
    add (C, BorderLayout.NORTH);
    add (D, BorderLayout.CENTER);
    add (T, BorderLayout.SOUTH);
  }

  public void destroy ()
  { remove (D); remove (C);}

  public String getAppletInfo ()
  { return "rang par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Canvas {
  static final long serialVersionUID = 180213L;
  Image img;
  Graphics g;
  int n, bsup, h, w, N;
  double max, somme;
  int [] histogramme;
  boolean retrace;
  int k, nsimul;
  double darrond = 100.0;
  Random rnd;

  public dessin (int n, int k, int nsimul)
  { this.n = n;
    this.k = k;
    this.nsimul = nsimul;
    rnd = new Random ();
    retrace = false;
    bsup = n - k + 1;
    histogramme = new int [bsup];
    rnd = new Random ();
  }

  private String sarrondi (double d)
  { return Double.toString (Math.floor (d * darrond) / darrond); }

  public void message (Graphics g, String s)
  { g.drawString (s, 10, 10);
  }

  public void update (Graphics g)
  { paint (g); }

  private void affiche (Graphics g)
  { g.setColor (Color.white);
    g.fillRect (0, 0, w, h);
    g.setColor (Color.yellow);
    g.drawLine (20, h - 40, w, h - 40);
    g.drawLine (20, 40, 20, h - 40);
    g.setColor (Color.blue);
    g.drawString ("0", 5, h - 40);
    g.drawString (sarrondi (max / N), 5, 40);

    for (int j = 0; j < bsup; j ++)
    { int x = j * (w - 50) / bsup + 20;
      int y = h - 40 - (int)(histogramme [j] / max * (h - 80));
      g.setColor (Color.black);
      g.drawLine (x, y, x, h - 40);
      g.setColor (Color.blue);
      g.drawString (Integer.toString (j + 1), x, h - 10);
    }
  }

  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 ();
      g.setColor (Color.white);
      g.fillRect (0, 0,  w - 2, h - 2);
      g.setColor (Color.black);
      g.drawRect (0, 0, w - 1, h - 1);
	  retrace = true;
    }
    if (retrace)
    { retrace = false;
      double valmin = Double.MAX_VALUE;
      double valmax = - valmin;
      max = 0; N = 0;
      if (bsup < histogramme.length)
           for (int i = 0; i < bsup; i ++) histogramme [i] = 0;
      else histogramme = new int [bsup];
      somme = 0;
      for (int i = 0; i < nsimul; i ++)
      { int cr = n;
        boolean pasfini = true;
        do
        { if (pasfini = ((int)(rnd.nextDouble () * cr ) >= k)) cr --;
        }
        while (pasfini);
        int nmcr = n - cr;
        histogramme [nmcr] ++;
        somme = somme + nmcr + 1;
        if (histogramme [nmcr] > max) max = histogramme [nmcr];
        N ++;
//        try { Thread.sleep (dt); }
//        catch (InterruptedException e) {}
        affiche (g);

        g.setColor (Color.white);
        g.fillRect (1, 1, getSize().width - 2, 12);
        g.setColor (Color.black);
        g.drawString ("rang moyen = " + Double.toString (somme / (i + 1)), 2,10);

        g1.drawImage (img, 0, 0, this); 
      }
	  T.retrace = true;
	  T.repaint();
    }
//    affiche (g);
    g1.drawImage (img, 0, 0, this); 
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener {
  static final long serialVersionUID = 180213L;
  dessin D;
  table T;
  TextField tn, tk, tnsimul;
  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;
  }

  private Button ajoutb (String s)
  { Button b = new Button (s);
    b.setFont (f);
    b.addActionListener (this);
    return b;
  }

  public controles (dessin D, table T)
  { this.D = D;
    this.T = T;
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    f = new Font ("Arial", Font.PLAIN, 10);
    add (ajoutlbl ("n ="));
    add (tn = ajouttf (D.n));
    add (ajoutlbl (" k ="));
    add (tk = ajouttf (D.k));
    add (ajoutlbl ("nb simul. ="));
    add (tnsimul = ajouttf (D.nsimul));
    add (ok = ajoutb ("Ok"));
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { try { D.n = Integer.parseInt (tn.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.n <= 0) D.n = 1;
      tn.setText (Integer.toString (D.n));
      try { D.k = Integer.parseInt (tk.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.k <= 0) D.k = 1;
      if (D.k > D.n) D.k = D.n;
      tk.setText (Integer.toString (D.k));
      D.bsup = D.n - D.k + 1;
      try { D.nsimul = Integer.parseInt (tnsimul.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.nsimul <= 0) D.nsimul = 1;
      tnsimul.setText (Integer.toString (D.nsimul));
      D.retrace = T.retrace = true;
      D.repaint ();
      T.repaint ();
    }
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class table extends Panel {
  static final long serialVersionUID = 180213L;
  TextArea ta;
  dessin D;
  boolean retrace;

  public table (dessin D)
  { this.D = D;
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    add (ta = new TextArea ("", 3, 50, TextArea.SCROLLBARS_HORIZONTAL_ONLY));
    retrace = false;
  }

  public void paint (Graphics g)
  { if (retrace)
    { retrace = false;
      String s1 = "rang....\t";
      String s2 = "effectif\t";
      for (int i = 0; i < D.bsup; i ++)
      { s1 = s1 + Integer.toString (i + 1) + "\t";
        s2 = s2 + Integer.toString (D.histogramme [i]) + "\t";
      }
      ta.setText (s1 + "\n" + s2);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

    public static void main (String [] args) {
        int w = 500;
        int h = 400;

// Création et lancement de l'applet
        rang a = new rang();
        a.init ();
        a.start ();

// Création de la fenêtre contenant l'applet
        Frame f = new Frame ("rang");
        f.addWindowListener (new fermer ());
        f.add (a);
        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);
        }
    }

}
