import java.applet.Applet;
import java.awt.*;
import java.lang.*;

public class Fraktal extends Applet implements Runnable {
	
		Thread  T;
		Graphics G;
		int		X,Y;
		double	Zx,Zy,Cx,Cy,Ux,Uy,Vx,Vy,Xx,Xy;
		volatile boolean	Slut = true;
		int		CNr;
		int Size = 256;
		int Zoom = 100;
		Color	colors[];
											
												
		public void init() {
															
		T = null;
		resize( Size,Size );
																					
		setLayout(new FlowLayout(FlowLayout.RIGHT, 10,10));
		Button B = new Button("Återställ");
		add(B);
																													Ux = -2.0;
		 Uy =  2.0;																								Vx =  2.0;
		 Vy = -2.0;
		 Xx = (Vx-Ux)/(double)Size;
		 Xy = (Vy-Uy)/(double)Size;
		 colors = new Color[64];
		 colors[ 0] = new Color(   0, 102,   0 );
		 colors[ 1] = new Color(   0, 153,   0 );
		 colors[ 2] = new Color(   0, 153, 102 );
		 colors[ 3] = new Color( 255, 255, 153 );
		 colors[ 4] = new Color( 255, 255,   0 );
		 colors[ 5] = new Color( 255, 153,   0 );
		 colors[ 6] = new Color( 255,  51,   0 );
		 colors[ 7] = new Color( 255,  51, 255 );
		 colors[ 8] = new Color( 204, 255,   0 );
		 colors[ 9] = new Color(   0, 255,   0 );
		 colors[10] = new Color(   0, 255, 128 );
		 colors[11] = new Color(   0, 255, 255 );
		 colors[12] = new Color(   0, 128, 255 );
		 colors[13] = new Color( 128,  64, 200 );
		 colors[14] = new Color( 128,   0, 128 );
		 colors[15] = new Color(   0,   0, 128 );
		 colors[16] = new Color(   0, 102,   0 );
		 colors[17] = new Color(   0, 153,   0 );
		 colors[18] = new Color(   0, 153, 102 );
	    colors[19] = new Color( 255, 255, 153 );
		 colors[20] = new Color( 255, 255,   0 );
		 colors[21] = new Color( 255, 153,   0 );
	    colors[22] = new Color( 255,  51,   0 );
		 colors[23] = new Color( 255,  51, 255 );
		 colors[24] = new Color( 204, 255,   0 );
		 colors[25] = new Color(   0, 255,   0 );
		 colors[26] = new Color(   0, 255, 128 );
		 colors[27] = new Color(   0, 255, 255 );
		 colors[28] = new Color(   0, 128, 255 );
		 colors[29] = new Color( 128,  64, 200 );
		 colors[30] = new Color( 128,   0, 128 );
		 colors[31] = new Color(   0,   0, 128 );
		 colors[32] = new Color(   0, 102,   0 );
	    colors[33] = new Color(   0, 153,   0 );
		 colors[34] = new Color(   0, 153, 102 );
		 colors[35] = new Color( 255, 255, 153 );
	    colors[36] = new Color( 255, 255,   0 );
		 colors[37] = new Color( 255, 153,   0 );
		 colors[38] = new Color( 255,  51,   0 );
		 colors[39] = new Color( 255,  51, 255 );
		 colors[40] = new Color( 204, 255,   0 );
		 colors[41] = new Color(   0, 255,   0 );
		 colors[42] = new Color(   0, 255, 128 );
		 colors[43] = new Color(   0, 255, 255 );
		 colors[44] = new Color(   0, 128, 255 );
		 colors[45] = new Color( 128,  64, 200 );
		 colors[46] = new Color( 128,   0, 128 );
		 colors[47] = new Color(   0,   0, 128 );
		 colors[48] = new Color(   0, 102,   0 );
		 colors[49] = new Color(   0, 153,   0 );
		 colors[50] = new Color(   0, 153, 102 );
		 colors[51] = new Color( 255, 255, 153 );
		 colors[52] = new Color( 255, 255,   0 );
		 colors[53] = new Color( 255, 153,   0 );
		 colors[54] = new Color( 255,  51,   0 );
		 colors[55] = new Color( 255,  51, 255 );
		 colors[56] = new Color( 204, 255,   0 );
		 colors[57] = new Color(   0, 255,   0 );
		 colors[58] = new Color(   0, 255, 128 );
		 colors[59] = new Color(   0, 255, 255 );
		 colors[60] = new Color(   0, 128, 255 );
		 colors[61] = new Color( 128,  64, 200 );
		 colors[62] = new Color( 128,   0, 128 );
		 colors[63] = new Color(   0,   0,   0 );
		 
		 G = getGraphics();
	}

	public boolean mouseDown( Event e, int x, int y ) {
      double dx,dy,xx,yy;
	   stopp();
		dx = (Vx-Ux)/Zoom;
		dy = (Vy-Uy)/Zoom;   
		xx = Ux + (double)(x)*(Vx-Ux)/(double)Size;
		yy = Uy + (double)(y)*(Vy-Uy)/(double)Size;
		Ux = xx - dx;
		Uy = yy - dy;
		Vx = xx + dx;
		Vy = yy + dy;
		Xx = (Vx-Ux)/(double)Size;
		Xy = (Vy-Uy)/(double)Size;
		T = new Thread( this );
		T.start();
		return false;
	}

	public boolean action(Event e, Object arg ) {
		if( e.target instanceof Button ) {
			String labelStr = ((Button)e.target).getLabel();
			if( labelStr.equals("Återställ")) {
				stopp();
				Xx = (Vx-Ux)/(double)Size;
				Xy = (Vy-Uy)/(double)Size;
				G.setColor( Color.white );
				G.fillRect( 0,0, Size, Size );
				start();
			}
		}
		return false;
	}
																											public void start() {

		if( T == null ) {
			Ux = -2.0;
			Uy =  2.0;
			Vx =  2.0;
			Vy = -2.0;
			Xx = (Vx-Ux)/(double)Size;
			Xy = (Vy-Uy)/(double)Size;
			T = new Thread( this );
			T.start();
		}
	}

	public void stopp() {
	
		if( T != null ) {
			Slut = true;
			T.stop();
			T = null;
		}
	}

	public void run() {

		int		f;
		double  x,y,tx,ty,le,pl,tmp;
		
		x = Ux;
		y = Uy;
		X = Y = 0;
		Slut = false;
		G.setColor( Color.white );
		G.fillRect( 0,0, Size,Size );
		while( !Slut ) {
			Zx = Zy = 0;
			Cx = x;
			Cy = y;
			for( f = 0, pl = 0.0 ; f < 639 ; f++ ) {
				tx = Zx*Zx-Zy*Zy + Cx;
				ty = 2*Zx*Zy     + Cy;
				le = tx*tx+ty*ty;
				if( le > 60 ) 
					break;
				tmp = pl - le;
				if( f > 0 && -0.001 < tmp && tmp < 0 && le < 0.0001 ) {
					f = 639;
					break;
					}
				pl = le;
				Zx = tx;
				Zy = ty;
			}
			CNr = f/10;
			G.setColor( colors[CNr] );
			G.fillRect( X, Y, 1, 1 );
			X++;
			x += Xx;
			if( X == Size ) {
				X = 0;
				x = Ux;
				Y++;
				y += Xy;
				if( Y == Size ) {
					Slut = true;
					break;
				}
			}
		}
	Slut = true;
	}
	
}