/* buffon1.java - jpq - 05/03/00 - 19/03/00
 * modification et ajout de main() le 10/02/18
 */

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.util.Random;


public class buffon1 extends java.applet.Applet {
  static final long serialVersionUID = 180210L;
  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;
  }

  public void init ()
  { setLayout (new BorderLayout ());
    int n = gparmi ("n", 10);
    int c = gparmi ("c", 4);
    D = new dessin (n, c);
    C = new controles (D);
    add (C, BorderLayout.NORTH);
    add (D, BorderLayout.CENTER);
  }

  public void destroy ()
  { remove (D); remove (C); }

  public String getAppletInfo ()
  { return "buffon1 par j.-p. Quelen"; }

////////////////////////////////////////////////////////////////////////////////
protected class dessin extends Canvas {
  static final long serialVersionUID = 180210L;
  Image img;
  Graphics g;
  int n, c, w, h, a, wm1, wm2, hm1, as2, ni, wsa, hsa;
  boolean retrace, modeplus;
  double x, y, teta, ls2, xA, yA, xB, yB;
  Random rnd;

  public dessin (int n, int c)
  { this.n = n;
    this.c = c;
    rnd = new Random ();
    setFont (new Font ("Arial", Font.PLAIN, 10));
  }

  private void calcseg ()
  { double act = ls2 * Math.cos (teta);
    double ast = ls2 * Math.sin (teta);
    xA = x + act;
    yA = y + ast;
    xB = x - act;
    yB = y - ast;
  }

  private void alea (int n)
  { x = rnd.nextDouble () * as2;
    y = rnd.nextDouble () * as2;
    teta = rnd.nextDouble () * Math.PI;
    calcseg ();
    if ((xA < 0.0) || (xB < 0.0)) ni ++;
    if (yB < 0.0) ni ++;
    if (rnd.nextDouble () > 0.5) x = a - x;
    if (rnd.nextDouble () > 0.5) y = a - y;
    int nta = (int)(rnd.nextDouble () * wsa) * a + a;
    x += nta;
    nta = (int)(rnd.nextDouble () * hsa) * a + a;
    y += nta;
    g.setColor (Color.blue);
    calcseg ();
    g.drawLine ((int)xA, (int)yA, (int)xB, (int)yB);

    g.setColor (Color.white);
    g.fillRect (1, 1, wm2, 20);

    g.setColor (Color.black);
    g.drawString ("n = " + Integer.toString (n) + "; ni = " + Integer.toString (ni) + "; 4 n / ni = " + Double.toString (4.0 * (double)(n) / (double)(ni)), 10, 15);
  }

  public void update (Graphics g1)
  { paint (g1); }

  public void paint (Graphics g1)
  { if (img == null || w != getSize().width || h != getSize().height)
    { w = getSize().width; 
      h = getSize().height;
      wm1 = w - 1;
      wm2 = w - 2;
      hm1 = h - 1;
      img = createImage (w, h);
      g = img.getGraphics ();
      a = Math.min (w, h) / c;
      as2 = a / 2; a = as2 * 2;
      ls2 = (double)(a) / 2.0;
      wsa = w / a - 2;
      hsa = h / a - 2;
      retrace = true;
    }
    if (retrace)
    { retrace = false;
      g.setColor (Color.white);
      g.fillRect (0, 0, w, h);

      g.setColor (Color.green);
      for (int x = 0; x < w; x += a) g.drawLine (x, 0, x, hm1); 
      for (int y = 0; y < h; y += a) g.drawLine (0, y, wm1, y); 

      g.setColor (Color.black);
      g.drawRect (0, 0, wm1, hm1);

      ni = 0;
      for (int i = 1; i <= n; i ++)
      { alea (i);
        g1.drawImage (img, 0, 0, this);
      }
    }
    else if (modeplus)
    { modeplus = false;
      alea (n);
    }
    g1.drawImage (img, 0, 0, this);
  }
}
////////////////////////////////////////////////////////////////////////////////
protected class controles extends Panel implements ActionListener {
  static final long serialVersionUID = 180210L;
  dessin D;
  TextField tn;
  Button ok, plus;

  private TextField ajouttf (Font f, String s, int i)
  { Label l;
    add (l = new Label (s));
    l.setBackground (Color.lightGray);
    l.setFont (f);
    TextField T = new TextField (Integer.toString (i), 5);
    add (T);
    T.setFont (f);
    return T;
  }

  public controles (dessin D)
  { this.D = D;
    setLayout (new FlowLayout());
    setBackground (Color.lightGray);
    Font f = new Font ("Arial", Font.PLAIN, 10);
    tn = ajouttf (f, "n =", D.n);
    add (ok = new Button ("Ok"));
    ok.addActionListener (this);
    add (plus = new Button ("+"));
    plus.addActionListener (this);
  }

  private int maj (TextField T, int n)
  { try { n = Integer.parseInt (T.getText ()); }
      catch (NumberFormatException nfe) { }
    if (n < 0) n = 0;
    return n;
  }

  public void actionPerformed (ActionEvent e)
  { if (e.getSource () == ok)
    { D.n = maj (tn, D.n);
      tn.setText (Integer.toString (D.n));
      D.retrace = true;
      D.repaint ();
    }
    else if (e.getSource () == plus)
    { D.n ++;
      tn.setText (Integer.toString (D.n));
      D.modeplus = true;
      D.repaint ();
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

    public static void main (String [] args) {
        int w = 340;
        int h = 380;

// Création et lancement de l'applet
        buffon1 p = new buffon1 ();
        p.init ();
        p.start ();

// Création de la fenêtre contenant l'applet
        Frame f = new Frame ("buffon1");
        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);
        }
    }
}
