/* pcubealea.java - jpq - 15/09/99 - 27/03/00 - 30/08/00
 * modification et ajout de main() le 11/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;

public class pcubealea extends java.applet.Applet {
  static final long serialVersionUID = 180211L;
  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 Nsimul = gparmi ("ns", 100);
    String s = "oui";
	try {
      s = getParameter ("calcmoy");
	}
	catch (NullPointerException e) {}
    boolean calcmoy = (s != null) && (s.equals ("oui"));
	s = "G";
	try {
      s = getParameter ("pa");
	}
	catch (NullPointerException e) {}
    D = new dessin (s, Nsimul, calcmoy);
    T = new table (D);
    C = new controles (D, T);
    add ("North", C);
    add ("South", T);
    add ("Center", D);
  }

  public void destroy ()
  { remove (D); remove (C); }

  public String getAppletInfo ()
  { return "pcubealea par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Panel {
  static final long serialVersionUID = 180211L;
  Image img;
  Graphics g;
  int w, h;
  int ipa, Nsimul, bsup;
  double somme;
  boolean calcmoy;
  int histogramme [] = new int [20];
  int ts [] [] = { {1, 3, 4}, {0, 2, 5}, {1, 3, 6}, {0, 2, 7},
                   {0, 5, 7}, {1, 4, 6}, {2, 5, 7}, {3, 4, 6}};
  Random r;
  boolean retrace;
  String AH = "ABCDEFGH";

  public dessin (String s, int Nsimul, boolean calcmoy)
  { sversipa (s);
    this.Nsimul = Nsimul;
    this.calcmoy = calcmoy;
    r = new Random ();
    retrace = false;
  }

  public void sversipa (String s)
  { ipa = 0;
    if (s != null)
    { try { ipa = Math.max (0, AH.indexOf (Character.toUpperCase (s.charAt (0)))); }
      catch (IndexOutOfBoundsException ioobe) { }
    }
  }


  public String Spa ()
  { return AH.substring (ipa, ipa + 1);
  }

  private void h (Graphics g, int i)
  { bsup = histogramme.length;
    do { bsup --; } while (bsup >= 0 && histogramme [bsup] == 0);
    bsup ++;
    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 (Integer.toString (i + 1), 5, 40);

    for (int j = 0; j < bsup; j ++)
    { int x = j * (getSize().width - 50) / bsup + 50;
      int y = getSize().height - 40 - histogramme [j] * (getSize().height - 80) / (i + 1);
      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 (w, h);
      g = img.getGraphics ();
      g.setColor (Color.white);
      g.fillRect (1, 1, w - 2, h - 2);
      g.setColor (Color.black);
      g.drawRect (0, 0, w - 1, h - 1);
	  retrace = true;
    }
    if (retrace)
    { retrace = false;
      for (int i = 0; i < histogramme.length; i ++) histogramme [i] = 0;
      somme = 0.0;
      for (int i = 0; i < Nsimul; i ++)
      { int position = 0; int compte = 0;
        do
        { position = ts [position] [(int)(r.nextDouble () * 3.0)];
          compte ++;
        }
        while (position != ipa);
        if (compte > histogramme.length)
        { int nh [] = new int [(compte / 20 + 1 ) * 20];
          System.arraycopy (histogramme, 0, nh, 0, histogramme.length);
          histogramme = nh;
        }
        histogramme [compte - 1] ++;
        somme += compte;
        h (g, i);
        if (calcmoy)
        { g.setColor (Color.white);
          g.fillRect (1, 1, getSize().width - 2, 12);
          g.setColor (Color.black);
          g.drawString ("nombre d'étapes en moyenne : " + Double.toString (somme / (i + 1)), 2,10);
        }
        g1.drawImage (img, 0, 0, this);
      }
    }
    else g1.drawImage (img, 0, 0, this);
//    else h (g, Nsimul -1);
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener {
  static final long serialVersionUID = 180211L;
  dessin D;
  table T;
  TextField tPA, tNsimul;
  Button ok;

  public controles (dessin D, table T)
  { this.D = D;
    this.T = T;
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    Label l;
    add (l = new Label ("Point de départ : A - Point d'arrivée :"));
    l.setBackground (Color.lightGray);
    add (tPA = new TextField (1));
    add (l = new Label ("- Nb de simulations :"));
    l.setBackground (Color.lightGray);
    add (tNsimul = new TextField (5));
    tPA.setText (D.Spa ());
    tNsimul.setText (Integer.toString (D.Nsimul));
    add (ok = new Button ("Ok"));
    ok.addActionListener (this);
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { D.sversipa (tPA.getText());
      tPA.setText (D.Spa ());
      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 = 180211L;
  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 = "nb d'étapes\t";
      String s2 = "effectifs  \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 = 600;
        int h = 400;

// Création et lancement de l'applet
        pcubealea p = new pcubealea();
        p.init ();
        p.start ();

// Création de la fenêtre contenant l'applet
        Frame f = new Frame ("pcubealea");
        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);
        }
    }

}
