/* images.java - jpq - 03/01/03 - 20/01/03 - 12/04/09
 * ajout de main() le 03/02/18
 * modification 02/02/21
 */

import java.awt.event.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;

public class images extends JPanel {
  static final long serialVersionUID = 020221L;
  controles C;
  dessin D;
  table T;

  public images (int nsimul, int nimages, int max) {
	setLayout (new BorderLayout ());
    D = new dessin (nsimul, nimages, max);
    T = new table();
    C = new controles();
    add ("North", C);
    add ("South", T);
    add ("Center", D);
  }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Panel {
  static final long serialVersionUID = 020221L;
  Image img;
  Graphics g;
  int nsimul, nimages, max, bsup, w, h, hmax;
  int [] histogramme;
  boolean [] bimg;
  boolean retrace;
  Random rnd;

  public dessin (int nsimul, int nimages, int max) {
    this.nsimul = nsimul;
    this.nimages = nimages;
    this.max = max;
    retrace = false;
    rnd = new Random();
  }

  private void h (Graphics g) {
	bsup = max - 1;
    while (bsup >= 0 && histogramme [bsup] == 0)
	  bsup --;
    bsup ++;
    hmax = 0;
    for (int i = 0; i < bsup; i ++) {
	  int hi = histogramme [i];
      if (hi > hmax)
	    hmax = hi;
    }
    g.setColor (Color.white);
    g.fillRect (1, 1, w - 2, h - 2);
    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 (Integer.toString (hmax) + "_", 5, 40);

    for (int j = 0; j < bsup; j ++) {
	  int x = j * (w - 50) / bsup + 50;
      int y = h - 40 - (int)((double)(histogramme [j] * (h - 80)) / hmax);
      g.setColor (Color.black);
      g.drawLine (x, y, x, h - 40);
      if (j % 10 == 9) {
		g.setColor (Color.blue);
        g.drawString (Integer.toString (j + 1), x, h - 10);
      }
    }
    g.setColor (Color.black);
    g.drawRect (0, 0, w - 1, h - 1);
  }

  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 = new int [max];
    if (bimg == null || bimg.length < nimages)
	  bimg = new boolean [nimages];
    if (retrace) {
	  retrace = false;
      for (int j = 0; j < histogramme.length; j ++)
	    histogramme [j] = 0;
      max = 0;
      for (int i = 0; i < nsimul; i ++) {
		  for (int j = 0; j < nimages; j ++) bimg [j] = false;
          int na = 0;
          while (true) {
// on obtient au hasard l'image numéro no (0<=no<nimages)
            int no = (int) Math.floor (rnd.nextDouble () * nimages);
            bimg [no] = true;
// et on regarde si on les a toutes
            int j = 0;
            for (j = 0; j < nimages && bimg [j]; j ++);
// si on les a toutes na contient le nbre de boîtes achetées
            if (j == nimages)
			  break;
            na ++;
          }
          if (na >= max)
		    max = na + 1;
          if (max > histogramme.length) {
		    int [] nh = new int [max];
            System.arraycopy (histogramme, 0, nh, 0, histogramme.length);
            histogramme = nh;
          }
          histogramme [na] ++;
          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 = 020221L;
  TextField tnsimul, tnimages;
  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() {
	f = new Font ("Arial", Font.PLAIN, 10);
//    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    add (ajoutlbl ("Simulations :"));
    add (tnsimul = ajouttf (5, D.nsimul));
    add (ajoutlbl ("images :"));
    add (tnimages = ajouttf (5, D.nimages));
    add (ok = new Button ("Ok"));
    ok.setFont (f);
    ok.addActionListener (this);
  }

  private int pint (TextField tf, int i) {
	try {
	  i = Integer.parseInt(tf.getText());
	}
    catch (NumberFormatException nfe) { }
    if (i <= 0)
	  i = 1;
    tf.setText (Integer.toString (i));
    return i;  
  }

  public void actionPerformed (ActionEvent e) {
	if (e.getSource () == ok) {
	  D.nsimul = pint (tnsimul, D.nsimul);
//      D.max = pint (tmax, D.max);
      D.nimages = pint (tnimages, D.nimages);
      D.retrace = T.retrace = true;
      T.ta.setText ("");
      D.repaint();
      T.repaint();
    }
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class table extends Panel {
  static final long serialVersionUID = 020221L;
  TextArea ta;
  boolean retrace;

  public table() {
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    add (ta = new TextArea ("", 5, 50, TextArea.SCROLLBARS_HORIZONTAL_ONLY));
    retrace = false;
  }

  public void paint (Graphics g) {
	if (retrace) {
	  retrace = false;
      int n = 0;
      double somme = 0.0;
      double somme2 = 0.0;
      int pdec = 0;
      int ddec = 0;
      int med = 0;
	  int i95 = 0;
      double dsimul = (double)(D.nsimul);
      double pdsimul = dsimul * 0.1;
      double dmed = dsimul * 0.5;
      double ddsimul = dsimul * 0.9;
	  double d95 = dsimul * 0.95;
      String s1 = "nombres\t";
      String s2 = "effectifs    \t";
      for (int i = 0; i < D.max; i ++) {
		int ip1 = i + 1;
        int dhi = D.histogramme [i];
        s1 += Integer.toString (ip1) + "\t";
        s2 += Integer.toString (dhi) + "\t";
        n += dhi;
        if ((n >= pdsimul) && (pdec == 0))
		  pdec = ip1;
        if ((n >= dmed) && (med == 0))
		  med = ip1;
        if ((n >= ddsimul) && (ddec == 0))
		  ddec = ip1;
        if ((n >= d95) && (i95 == 0))
		  i95 = ip1;
        somme += dhi * ip1;
        somme2 += dhi * ip1 * ip1;
      }
      double moy = somme / n;
      double var = somme2 / n - moy * moy;
      ta.setText (s1 + "\n" + s2 + "\n1er décile = " + pdec + " ; médiane = " + med + " ; 9e décile = " + ddec
                  + " ; seuil 95% = " + i95 + "\ntotal = " + n + "; moyenne = " + moy + "; variance = " + var);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

	public static void main (String [] args) {
		int w = 600;
		int h = 400;
        int nsimul = 1000;
        int nimages = 6;
        int max = 50;

		images i = new images (nsimul, nimages, max);

		JFrame f = new JFrame ("images");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (i);
		f.setSize (w, h);
		f.setVisible (true);
	}
}
