/* Mandle Brot 4.0 */

import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.*;
import java.awt.Font;


public class mb extends java.applet.Applet implements Runnable{
	
  Thread runner;
// window TextFields info
   Canvas swatch;
   mb_con Data_controls;
//   mb_jxy julia_info;
// Set info varibles
  final boolean mandel_set=true;
  final boolean julia_set=false;
  boolean set_style=mandel_set;
// Constants for reset values
   final double TopLeftx=-2.25; 
   final double TopLefty=1.75;
   final double BottomRightx=1.75;
   final double BottomRighty=-1.75;
// current point value, differrence between points
   double cx,cy,dx,dy;
// view area coordinates
   double tlx,tly,brx,bry;
// Julia set point to be determined
   double Jx=-0.225,Jy=0.7;
// array of visual data of sets
   final int width=260;
   final int height=240; 
   int data[][] = new int[width][height];


// regular junk varibles
  int ctrx,ctry,iter,iter_result=0,
      tempx=0,tempy=0; //mouse cords
  final int num_colors=100;
  final int ajustx=15;
  final int ajusty=50;
  int max_iter=500; //limit on iterations

  final double pert=0.999995;

// Constructors
public  mb() {
	cx=0;cy=0;max_iter=100;
	}
// Thread stuff
public void start() {
	if (runner == null) {
		runner = new Thread(this);
		runner.start();
		}
}
public void stop() {
	if (runner != null) {
		runner.stop();
		runner=null;
		}
}
// set up varibles
public void init() {
// int varibles
	tlx=TopLeftx;
	tly=TopLefty;
	brx=BottomRightx;
	bry=BottomRighty;
	dx = Math.abs((brx-tlx)/(width));  
	dy = Math.abs((tly-bry)/(height)); 
	setFont(new Font("Helvetica",Font.BOLD,12));
	setLayout(new GridLayout(2,1,0,0));
	setForeground(Color.green);
// Color swatch
	swatch = new Canvas();
	swatch.setBackground(Color.white);
	swatch.setForeground(Color.green);
// sub panels for Julia input
	Data_controls = new mb_con(this,"Jx:","Jy:");
	add(Data_controls);
}
public Insets insets() {
	return new Insets(0,0,240,0);
}

public int calc_brot(double x,double y,int num) {
// varible declarations
   double x1=x,y1=y;
   double x2=x*x,y2=y*y,temp;
   int ctr=0;
   while ( (ctr++<max_iter) & ((x2+y2) < 10000.0)  )
	 {
 	 temp=(x2 - y2 +x);
   	y1=2*x1*y1 + y;
	x1=temp;
	x2=x1*x1;
	y2=y1*y1;
	}
	return ctr;
}
public int calc_julia(double x,double y,
		      double jx,double jy,int num) {
// varible declarations
  double x1=x,y1=y;
  double x2=x*x,y2=y*y,temp;
  int ctr=0;
  while ( (ctr++<max_iter) & ((x2+y2) < 10000.0)  )
	{
	temp=(x2 - y2 + jx);
	y1=2*x1*y1 + jy;
	x1=temp;
	x2=x1*x1;
	y2=y1*y1;
	}
	return ctr;
}

public void paint(Graphics g) {
int xctr,yctr,result;
float cl2;
	cl2=(float)(0.01);
	for (xctr=0;xctr<(ctrx);xctr++)
	{
	for (yctr=0;yctr<(height);yctr++)
	{
	if (data[xctr][yctr]>=(max_iter*pert))
	   g.setColor(Color.black);
	else
	{
	result=data[xctr][yctr]%100;
	g.setColor(Color.getHSBColor(cl2*result,(float)1.0,(float)1.0));
	}
	g.drawLine(ajustx+xctr,ajusty+yctr,ajustx+xctr,ajusty+yctr);
	}//yctr
	}//xctr
}

public void run() {
	while (true) {
	cx=tlx;
	ctrx=0;
     if (set_style==mandel_set)
	while (ctrx++<width) {
		cy = tly;
		for (ctry=0; ctry<height;ctry++)
			{
			data[ctrx][ctry]=calc_brot(cx,cy,max_iter);
			cy=cy-dy;
			}; // ctry
		repaint(ctrx,0,1,height);
		cx=cx+dx;
		try { Thread.sleep(10); }
		catch (InterruptedException e) { }
	}// ctrx
     else  // Julia set
	while (ctrx++<width) {
		cy = tly;
		for (ctry=0; ctry<height;ctry++)
			{
			data[ctrx][ctry]=calc_julia(cx,cy,Jx,Jy,max_iter);
			cy=cy-dy;
			}; // ctry
		repaint(ctrx,0,1,height);
		cx=cx+dx;
		try { Thread.sleep(10); }
		catch (InterruptedException e) { }
	}// while ctrx
	
	}// while (true)
}// run
// julia set selected by mouse
public boolean mouseDown(Event evt,int x,int y)
	{
//	tempx=x;tempy=y;
     // Julia Cords has changed,
	Jx=(x-ajustx)*dx+tlx;
	Jy=tly-(y-ajusty)*dy;
	Data_controls.Juliax.setText(String.valueOf(Jx));
	Data_controls.Juliay.setText(String.valueOf(Jy));
	return true;
	}
void update(mb_con controlPanel) {
	Color c;
// get string values from text fields, convert to doubles
Double	Jxobj = Double.valueOf(controlPanel.Juliax.getText());
Double	Jyobj = Double.valueOf(controlPanel.Juliay.getText());
	Jx = Jxobj.doubleValue();
	Jy = Jyobj.doubleValue();
		
if (controlPanel == Data_controls) 
   {  
   if (controlPanel.Reset) 
      {
      tlx=TopLeftx;
	tly=TopLefty;
	brx=BottomRightx;
	bry=BottomRighty;
	dx = Math.abs((brx-tlx)/(width));  
	dy = Math.abs((tly-bry)/(height));
	Jx=-0.225;
	Jy=0.7;
	set_style=mandel_set;
      }
   else 
     {  // something else has changed
     };
  // set Julia fields
     Data_controls.Juliax.setText(String.valueOf(Jx));
     Data_controls.Juliay.setText(String.valueOf(Jy));
     if (controlPanel.ButtonPressed)
	run();
     }
  }//update
}// class

