/* @(#)Mandel.java 1.0 1/18/96 Darryll Truchan 
 *
 * Copyright (c) 1996 Darryll Truchan. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
 * without fee is hereby granted. 
 *
 */

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;

class Complex {
    private double real, imag;
    public Complex(double real, double imag) {
        this.real = real; this.imag = imag;
    }
    public static Complex add(Complex a, Complex b) {
        return new Complex(a.real + b.real,a.imag + b.imag);
    }
    public static Complex mul(Complex a, Complex b) {
        return new Complex((a.real * b.real) - (a.imag * b.imag),(a.real * b.imag) + (a.imag * b.real));
    }
    public static double norm(Complex c) {
        return (c.real * c.real) + (c.imag * c.imag);
    }
}

/**
 *  A simple Mandelbrot fractal applet.
 *
 * @version 1.0
 * @author Darryll Truchan
 */
public class Mandel extends Applet {

    private double left, top, right, bottom;
    private double xtemp, ytemp, deltaX, deltaY;
    private int iterations, bailout, width, height;
    private Color colors[][];
    private boolean done;

    public void init() {
        done = false;
        left = (new Double(getParameter("LEFT"))).doubleValue();
        top = (new Double(getParameter("TOP"))).doubleValue();
        right = (new Double(getParameter("RIGHT"))).doubleValue();
        bottom = (new Double(getParameter("BOTTOM"))).doubleValue();
         
        iterations = (new Integer(getParameter("ITERATIONS"))).intValue();
        bailout = (new Integer(getParameter("BAILOUT"))).intValue();
        width = (new Integer(getParameter("WIDTH"))).intValue();
        height = (new Integer(getParameter("HEIGHT"))).intValue();

        resize(width,height);
        deltaX = (right-left)/width;
        deltaY = (bottom-top)/height;

        colors = new Color[width][height];
    }

    public void start() {
        repaint();
    }

    public void update(Graphics g) {
        paint(g);
    }

    private Color Calculate(double X, double Y) {
        Complex C = new Complex(X,Y);
        Complex Z = new Complex(0,0);
        int cnt = 0;
        do {
            Z = Complex.mul(Z,Z);
            Z = Complex.add(Z,C);
            cnt++;
        } while((cnt<iterations)&&(Complex.norm(Z)<bailout));
        if(cnt == iterations) cnt = 8;
        switch(cnt%8) {
            case 0 : return new Color(0x00000000);
            case 1 : return new Color(0x000000FF);            
            case 2 : return new Color(0x0000FF00);
            case 3 : return new Color(0x0000FFFF);
            case 4 : return new Color(0x00FF0000);            
            case 5 : return new Color(0x00FF00FF);
            case 6 : return new Color(0x00FFFF00);
            case 7 : return new Color(0x00FFFFFF);
            default: return new Color(0x00000000);
        }
    }     

    public void paint(Graphics g) {
        ytemp = top;
        for(int y=0; y<height; y++) {
            xtemp = left;
            for(int x=0; x<width; x++) {                
                if(done == false) 
                    colors[x][y] = Calculate(xtemp,ytemp);                
                g.setColor(colors[x][y]);
                g.drawLine(x,y,x,y);
                xtemp += deltaX;
            }
            ytemp += deltaY;
        }
        done = true;
    }

    public String[][] getParameterInfo() {
        String info[][] = {
            {"Left", "double","Left bound of fractal"},
            {"Top", "double","Right bound of fractal"},
            {"Right", "double","Top bound of fractal"},
            {"Bottom", "double","Bottom bound of fractal"},
            {"Iterations", "int","Number of tests before infinity"},
            {"Bailout", "int","Bailout to infinity"},
            {"Width", "int","Width of the image"},
            {"Height", "int","Height of the image"}
        };
        return info;
    }

    public String getAppletInfo() {
        return "Mandel.java 1.0\nDarryll Truchan\nCopyright(c) 1996\nAll Rights Reseved\n";
    }

}
