// Draws a fractal with double buffering, has indicator line, and draws a button
// that alternates when pushed between start and stop. Uses randomly generated
// colortable.               Chris Seidel, April 1996

import java.awt.*;
import java.applet.*;

public class Frac_gen extends java.applet.Applet implements Runnable {
	public int x, y, n, iter=75, answer=0;
	Color colors[] = new Color[76];
	Thread runThread = null;
	Image fractal;
	Graphics offscreenFractal;
	private Button control_button;
	Graphics g;
	boolean please_stop = false;
	TextField tf1, tf2, tf3, tf4, tf5, tf6;
	Panel field_panel;

	public void init() {
		fractal = createImage(200, 200);
		offscreenFractal = fractal.getGraphics();
		g = this.getGraphics();
		tf1 = new TextField("0.20", 10);
		tf2 = new TextField("0.40", 10);
		tf3 = new TextField("0.001", 10);
		tf4 = new TextField("0.001", 10);
		tf5 = new TextField("0.40", 10);
		tf6 = new TextField("0.32", 10);
		control_button = new Button("stop");
		this.setLayout (new BorderLayout ());
		this.add("South", control_button);
		field_panel = new Panel();
		field_panel.setLayout (new GridLayout (6, 2));
		field_panel.add(new Label("initial X"));
		field_panel.add(tf1);
		field_panel.add(new Label("initial Y"));
		field_panel.add(tf2);
		field_panel.add(new Label("X increment"));
		field_panel.add(tf3);
		field_panel.add(new Label("Y increment"));
		field_panel.add(tf4);
		field_panel.add(new Label("Value of a"));
		field_panel.add(tf5);
		field_panel.add(new Label("Value of b"));
		field_panel.add(tf6);
		this.add("East", field_panel);	
		show();
	}

	public void start() {
			runThread = new Thread(this);
			runThread.start();
	}

	public void stop() {
		if (runThread != null)
			runThread.stop();
		runThread = null;
	}

	public boolean action(Event event, Object arg){
		if (runThread != null)
			please_stop = true;
		else {
			please_stop = false;
			start();
		}
		if( event.target == control_button ){
			if( arg.equals("stop") )
		      control_button.setLabel("start");
		   else if( arg.equals("start") )
			         control_button.setLabel("stop");
		return true;
		} else return super.action(event, arg);
	}

	public void run() {
		int rval, gval, bval;
		
		while(!please_stop){
		    // Pick a bunch of Random Colors
			for (int i = 0; i < colors.length; ++i) {
				rval = (int)Math.floor(Math.random()*256);
				gval = (int)Math.floor(Math.random()*256);
				bval = (int)Math.floor(Math.random()*256);
				colors[i] = new Color( rval, gval, bval );
			}
		
		FractalMaker();
		}
		runThread = null;
	}

	public void FractalMaker() {
		double xi=0.001000, yi=0.0010000, c, d, l, a=0.40, b=0.320, h, xj, yj, x_k=0.2, y_k=0.4, x_f, y_f;
		String v1 = tf1.getText();
		String v2 = tf2.getText();
		String v3 = tf3.getText();
		String v4 = tf4.getText();
		String v5 = tf5.getText();
		String v6 = tf6.getText();
		
		x_k = Double.valueOf(v1).doubleValue();
		y_k = Double.valueOf(v2).doubleValue();
		xi = Double.valueOf(v3).doubleValue();
		yi = Double.valueOf(v4).doubleValue();
		a = Double.valueOf(v5).doubleValue();
		b = Double.valueOf(v6).doubleValue();

		offscreenFractal.setColor(Color.red);
		n = 0;
		x_f = x_k;
		y_f = y_k;

/*System.out.println(n+" "+x_k+" "+y_k+"\t"+xi+" "+yi+"\t"+x+" "+y); */


 for( x=0; x < 200 && please_stop != true; x++){  // increment along x
	for( y=0; y < 200; y++){  // increment along y

	  xj = x_k;
	  yj = y_k;

      /*  Calculate the Dwell  */
      while(  n < iter && answer == 0){  /* the new point is still within */
          c = (xj*xj)-(yj*yj)+a;     /* a distance of 2 from the ori.  */
          d = (2*xj*yj) - b;         /* should be + b, but - b gives interesting results*/
          h = (c*c)+(d*d);
          l = Math.sqrt(h);
        
          if( l > 2 )
            answer = 1;
          else
            ++n;

          xj = c;       /* jump to the new location for reiteration  */
          yj = d;
      }

     // assign a color based on the dwell value
     if(  n >= 0 && n <= 75 )
        offscreenFractal.setColor(colors[n]);

							
     offscreenFractal.drawLine(x, y, x, y);
/* System.out.println(n+" "+x_k+" "+y_k+"\t"+xi+" "+yi+"\t"+x+" "+y);*/

    n = 0;
    answer = 0;
    y_k = y_k + yi;

    }
	 /* g.drawLine(x, y-10, x, y-10);*/
	  g.drawImage(fractal, 0,0, this);
					y = 0;
					x_k = x_k + xi;
          y_k = y_f;
		}

	g.drawImage(fractal, 0,0, this);
  }


}
