/* tind.java - jpq - 19/01/03
 * teste (fAB * fNANB - fANB * fNAB) / sqrt (fA * fNA * fB * fNB)
 * par simulation
 * modification et ajout de main() le 18/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.*;

public class tind extends java.applet.Applet {
  static final long serialVersionUID = 180218L;
  controles C;
  dessin D;

private int gparmi (String s, int i) {
    try {
      s = getParameter (s);
      i = Integer.parseInt (s);
    }
    catch (NumberFormatException e) {}
    catch (NullPointerException e) {}
    return i;
  }

 private double gparmd (String s, double d) {
    try {
      s = getParameter (s);
      d = Double.parseDouble (s);
    }
    catch (NumberFormatException e) {}
    catch (NullPointerException e) {}
    return d;
  }

  public void init ()
  { setLayout (new BorderLayout ());
    int N = gparmi ("N", 10);
    int nsimul = gparmi ("nsimul", 500);
    double p = gparmd ("p", 0.5);
    double q = gparmd ("q", 0.5);
    double min = gparmd ("min", -2.0);
    double max = gparmd ("max", 2.0);
    D = new dessin (N, p, q, min, max, nsimul);
    C = new controles ();
    add (C, BorderLayout.NORTH);
    add (D, BorderLayout.CENTER);
  }

  public void destroy ()
  { remove (D); remove (C); }

  public String getAppletInfo ()
  { return "tind par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Panel {
  static final long serialVersionUID = 180218L;
  Image img;
  Graphics g;
  int N, bsup, w, h, nsimul;
  double [] hw;
//  double valeurs [];
  double [] [] histo;
  double p, q, hmax, min, max, moyenne, variance;
  boolean retrace;
  Random rnd;

  public dessin (int N, double p, double q, double min, double max, int nsimul)
  { this.N = N;
    this.p = p;
    this.q = q;
    this.min = min;
    this.max = max;
    this.nsimul = nsimul;
//    valeurs = new double [nsimul];
    histo = new double [2][2];
    retrace = false;
    rnd = new Random ();
  }

  private void h (Graphics g)
  { bsup = hw.length - 1;
    hmax = 0;
    for (int i = 0; i < bsup; i ++)
    { double hi = hw [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);
    int mwmm0 = - (int)(min * w / (max - min));
    g.drawLine (mwmm0, 40, mwmm0, h - 20);
    g.setColor (Color.blue);
    g.drawString ("0", mwmm0, h - 20);
    g.drawString (Double.toString (hmax) + "_", 5, 40);
    g.drawString (Double.toString (min), 5, h - 20);
    g.drawString (Double.toString (max), w - 40, h - 20);
    int wd2 = w / 2;
    double dbsup = (double) bsup;
    g.setColor (Color.black);
    for (int j = 0; j < bsup; j ++)
    { double dhwj = hw [j];
      if (dhwj > 0.0)
      { int x = (int)((j * w) / dbsup);
        int y = h - 40 - (int)(dhwj * (h - 80) / hmax);
        g.drawLine (x, y, x, h - 40);
      }
    }
    g.drawString ("Moyenne = " + moyenne + "; variance = " + variance, 20, 20);
    g.drawRect (0, 0, w - 1, h - 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);
        hw = new double [w];
		retrace = true;
      }
    if (retrace)
    { retrace = false;
      g.setColor (Color.white);
      g.fillRect (1, 1, w - 2, h - 2);
      g1.drawImage (img, 0, 0, this);
      for (int i = 0; i < w; i++) hw [i] = 0.0;
//      if (nsimul > valeurs.length) valeurs = new double [nsimul];
      moyenne = variance = 0.0;
      for (int i = 0; i < nsimul; i ++)
      { histo [0] [0] = histo [0] [1] = histo [1] [0] = histo [1] [1] = 0.0;
        for (int j = 0; j < N; j ++)
        { double d = rnd.nextDouble ();
          int ii = 0; int jj = 0;
          if (d > p) ii = 1;
          d = rnd.nextDouble ();
          if (d > q) jj = 1;
          histo [ii] [jj] ++;
        }
        double d = histo [0] [0] * histo [1] [1] - histo [0] [1] * histo [1] [0];
        d /= Math.sqrt ((histo [0] [0] + histo [0] [1])*(histo [1] [0] + histo [1] [1])*(histo [0] [0] + histo [1] [0])*(histo [0] [1] + histo [1] [1]));
        if ((d >= min) && (d <= max))
        { int ind1 = (int)((d - min) / (max - min) * w);
//          valeurs [i] = d;
          moyenne += d;
          variance += d * d;
          if ((ind1 >= 0) && (ind1 < hw.length))
          hw [ind1] ++;
        }
      }
      moyenne /= nsimul;
      variance = variance / nsimul - moyenne * moyenne;
    }
    h (g);
    g1.drawImage (img, 0, 0, this);
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener {
  static final long serialVersionUID = 180218L;
  TextField tN, tp, tq, tmin, tmax, tnsimul;
  Button ok;
  Font f;
  GridBagLayout gbl;
  GridBagConstraints gbc;

  private Label ajoutlbl (String s)
  { Label lbl = new Label (s);
    lbl.setFont (f);
    lbl.setBackground (Color.lightGray);
    gbl.setConstraints(lbl, gbc);
    return lbl;
  }

  private TextField ajouttf (int n, int n1)
  { TextField tf = new TextField (n);
    tf.setFont (f);
    tf.setText (Integer.toString (n1));
    gbl.setConstraints(tf, gbc);
    return tf;
  }

  private TextField ajouttfd (int n, double d)
  { TextField tf = new TextField (n);
    tf.setFont (f);
    tf.setText (Double.toString (d));
    gbl.setConstraints(tf, gbc);
    return tf;
  }

  public controles ()
  { f = new Font ("Arial", Font.PLAIN, 10);
    gbl = new GridBagLayout ();
    gbc = new GridBagConstraints ();
    setLayout (gbl);
    gbc.fill = GridBagConstraints.BOTH;
    setBackground (Color.lightGray);
    add (tN = ajouttf (5, D.N));
    add (ajoutlbl (" tirages simulés "));
    add (tnsimul = ajouttf (5, D.nsimul));
    add (ajoutlbl (" fois; p = "));
    add (tp = ajouttfd (5, D.p));
    add (ajoutlbl (" q = "));
    add (tq = ajouttfd (5, D.q));
    add (ajoutlbl (" min = "));
    add (tmin = ajouttfd (5, D.min));
    add (ajoutlbl (" max = "));
    add (tmax = ajouttfd (5, D.max));
    add (ok = new Button ("Ok"));
    ok.setFont (f);
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbl.setConstraints(ok, gbc);
    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;  
  }

  private double pdbl (TextField tf, double d)
  { try { d = new Double (tf.getText ()) . doubleValue (); }
    catch (NumberFormatException nfe) { }
    tf.setText (Double.toString (d));
    return d;
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { D.N = pint (tN, D.N);
      D.nsimul = pint (tnsimul, D.nsimul);
      D.p = pdbl (tp, D.p);
      D.q = pdbl (tq, D.q);
      D.min = pdbl (tmin, D.min);
      D.max = pdbl (tmax, D.max);
      D.retrace = true;
      D.repaint ();
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

    public static void main (String [] args) {

        tind a = new tind();
        a.init ();
        a.start ();

        Frame f = new Frame ("tind");
        f.addWindowListener (new fermer ());
        f.add (a);
        f.setSize (500, 400);
        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);
        }
    }
}
