/* reversihisto.java - jpq - 18/12/04
 * modification et ajout de main() le 13/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;

public class reversihisto extends java.applet.Applet {
  static final long serialVersionUID = 180213L;
  controles C;
  dessin D;
  table T;

  public void init ()
  { setLayout (new BorderLayout ());
    setFont (new Font ("Arial", Font.PLAIN, 10));
    setBackground (Color.lightGray);
    D = new dessin (10, 50);
    T = new table ();
    C = new controles ();
    add (C, BorderLayout.NORTH);
    add (T, BorderLayout.SOUTH);
    add (D, BorderLayout.CENTER);
  }

  public void destroy ()
  { remove (D); remove (C); }

  public String getAppletInfo ()
  { return "reversihisto par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Panel {
  static final long serialVersionUID = 180213L;
  Image img;
  Graphics g;
  int w, h;
  int nl, bsup, n, nsimul;
  int histogramme [];
  boolean [] [] grille1;
  boolean retrace, stopgg;
  Random r;

  public dessin (int nl, int nsimul)
  { this.nl = nl;
    this.nsimul = nsimul;
    r = new Random ();
    init1 ();
  }

  public void init1 ()
  { if (reversitab.grille != null) n = reversitab.grille.length;
    bsup = n * n + 1;
    retrace = false;
  }

  private void h (Graphics g)
  { 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), 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);
      }
    if (histogramme == null || histogramme.length < bsup)
    { histogramme = new int [bsup];
    }
    if (retrace)
    { retrace = false;
      for (int k = 0; k < bsup; k ++) histogramme [k] = 0;
      int n = reversitab.grille.length;
      grille1 = new boolean [n] [n];
for (int l = 0; l < nsimul; l ++)
{     for (int k = 0; k < n; k ++)
        System.arraycopy (reversitab.grille [k], 0, grille1 [k], 0, n);
      for (int k = 0; k < nl; k ++)
      { if (stopgg)
        { boolean b = true;
          for (int ii = 0; ii < n; ii ++)
            for (int jj = 0; jj < n; jj ++)
              { b = b && (grille1 [ii] [jj]);
                if (! b) break;
              }
          if (b) break;
        }
      	int i = (int)(r.nextDouble () * n);
        int j = (int)(r.nextDouble () * n);
        grille1 [i] [j] = ! grille1 [i] [j];
        if (i > 0) grille1 [i - 1] [j] = ! grille1 [i - 1] [j];
        if (j > 0) grille1 [i] [j - 1] = ! grille1 [i] [j - 1];
        if (i < n - 1) grille1 [i + 1] [j] = ! grille1 [i + 1] [j];
        if (j < n - 1) grille1 [i] [j + 1] = ! grille1 [i] [j + 1];          
      }
      int njn = 0;
      for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++)
          njn += (grille1 [i] [j]) ? 0 : 1;
      histogramme [njn] ++;
      h (g);
      g1.drawImage (img, 0, 0, this);
}
    }
    else g1.drawImage (img, 0, 0, this);
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener {  //, ItemListener
  static final long serialVersionUID = 180213L;
  TextField tnl, tnsimul;
  Button ok;
  Checkbox cbstopgg;

  private TextField ajouttf (int n, int n1)
  { TextField tf = new TextField (n);
    tf.setText (Integer.toString (n1));
    return tf;
  }
  public controles ()
  { add (tnl = ajouttf (5, D.nl));
    add (new Label ("clics simulés"));
    add (tnsimul = ajouttf (5, D.nsimul));
    add (new Label ("fois"));
    add (ok = new Button ("Ok"));
    ok.addActionListener (this);
    add (cbstopgg = new Checkbox ("arrêt partie gagnante", true));
//    cbstopgg.addItemListener (this);
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { try { D.nl = Integer.parseInt (tnl.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.nl <= 0) D.nl = 1;
      tnl.setText (Integer.toString (D.nl));
      try { D.nsimul = Integer.parseInt (tnsimul.getText ()); }
      catch (NumberFormatException nfe) { }
      if (D.nsimul <= 0) D.nsimul = 1;
      tnsimul.setText (Integer.toString (D.nsimul));
      D.stopgg = cbstopgg.getState ();
      D.init1 ();
      D.retrace = T.retrace = true;
      D.repaint ();
      T.repaint ();
    }
  }

//  public void itemStateChanged (ItemEvent evt) { }
}
////////////////////////////////////////////////////////////////////////////////
protected class table extends Panel {
  static final long serialVersionUID = 180213L;
  TextArea ta;
  boolean retrace;

  public table ()
  { add (ta = new TextArea ("", 5, 50, TextArea.SCROLLBARS_HORIZONTAL_ONLY));
    retrace = false;
  }

  public void paint (Graphics g)
  { if (retrace)
    { retrace = false;
      double som = 0;
      double som2 = 0;
      int q1 = -1;
      int q2 = -1;
      int q3 = -1;
      int cumul = 0;
      int effectif = D.nsimul;
      String s1 = "jetons noirs\t";
      String s2 = "effectif       \t";
      int nn = D.n * D.n + 1;
      for (int i = 0; i < nn; i ++)
      { s1 += Integer.toString (i) + "\t";
        int dhi = D.histogramme [i];
        s2 += dhi + "\t";
        cumul += dhi;
        som += dhi * i;
        som2 += dhi * i * i;
        if ((q1 == -1) && (cumul * 4 >= effectif)) q1 = i;
        if ((q2 == -1) && (cumul * 2 >= effectif)) q2 = i;
        if ((q3 == -1) && (cumul * 4 >= effectif * 3)) q3 = i;
      }
      double moy = som / effectif;
      double var = (som2 - som * moy) / effectif;
      ta.setText (s1 + "\n" + s2
                  + "\nmoyenne : " + moy + "\técart-type : " + Math.sqrt(var)
                  + "\nmédiane : " + q2 + "\tquartiles : " + q1 + " et " + q3);
    }
  }
}

}

class reversitab {
  static final long serialVersionUID = 180213L;
  static boolean [] [] grille;
}
