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

// $Id: Apfel.java,v 1.2 2000/03/25 20:42:12 manfred Exp $

/*
 * Copyright (c) 1999/2000 Manfred Thole
 *      manfred@thole.org
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 */

/**
    Mandelbrot Set.
    @author Manfred Thole, manfred@thole.org
    @version $Date: 2000/03/25 20:42:12 $
  */

public class Apfel extends Applet implements Runnable {

    private Image bg;
    private Graphics bgg;

    private int size_x = 100;
    private int size_y = 100;
    private double xa  = -2.25;
    private double xe  = 0.75;
    private double ya  = -1.5;
    private double ye  = 1.5;
    private int itmax  = 10;
    private int itmax13;
    private int itmax23;

    private boolean please_stop;

    private Thread apfelPlot;
    private ThreadGroup threadGroup;   // For Netscape ...

    private String param;

    public void init() {
	param = this.getParameter("size_x");
	if ( param != null )
	    size_x = Integer.parseInt(param);
	param = this.getParameter("size_y");
	if ( param != null )
	    size_y = Integer.parseInt(param);
	param = this.getParameter("xa");
	if ( param != null )
	    xa = (new Double(param)).doubleValue();
	param = this.getParameter("xe");
	if ( param != null )
	    xe = (new Double(param)).doubleValue();
	param = this.getParameter("ya");
	if ( param != null )
	    ya = (new Double(param)).doubleValue();
	param = this.getParameter("ye");
	if ( param != null )
	    ye = (new Double(param)).doubleValue();
	param = this.getParameter("itmax");
	if ( param != null )
	    itmax = Integer.parseInt(param);
	param = null;
	itmax13 = itmax*1/3;
	itmax23 = itmax*2/3;
	//
	bg = this.createImage(size_x, size_y);
	bgg = bg.getGraphics();
	bgg.setColor(Color.white);
	bgg.fillRect(0, 0, size_x, size_y);
	bgg.setColor(Color.black);
	please_stop = false;
    }

    private final Color it2C(int it) {
	if (it < itmax13) return new Color(it*255/itmax13, 0, 0);
	if (it < itmax23) return new Color(0, (it-itmax13)*255/itmax13, 0);
	return new Color(0, 0, (it-itmax23)*255/itmax13);
    }

    public void run() {
	double		ix, iy, zr, zi, zrq, ziq;
	int             it;	
	double inx = (xe - xa) / size_x;
	double iny = (ye - ya) / size_y;

	for (ix = xa; ix <= xe; ix += 2*inx) {
	    for (iy = ya; iy <= ye; iy += 2*iny) {
		it = 0;
		zr = 0;
		zi = 0;
		do {
		    if (please_stop) return;
		    zrq = zr * zr;
		    ziq = zi * zi;
		    it++;
		    zi = 2 * zr * zi + iy;
		    zr = zrq - ziq + ix;
		} while (zrq + ziq < 4 && it < itmax);
		bgg.setColor(it2C(it));
		bgg.drawRect((int)((ix-xa)/inx), (int)((iy-ya)/iny), 1, 1);
	    }
	    repaint();
	}
	repaint();
    }


    public void update(Graphics g) {
	paint(g);
    }
    
    public void paint(Graphics g) {
	g.drawImage(bg, 0, 0, null);
    }
    
    public void stop() {
	please_stop = true;
    }
    
    public void start() {
	please_stop = false;
	// Netscape needs this (see above)
	threadGroup = Thread.currentThread().getThreadGroup();
	if (apfelPlot != null)
	    apfelPlot.stop();
	// Netscape needs the same ThreadGroup for setPriority()
	apfelPlot = new Thread(threadGroup, this, "apfelPlot");
	apfelPlot.setPriority(Thread.MIN_PRIORITY);
	apfelPlot.start();
    }
    
    public void destroy() {
	please_stop = true;
	bg.flush();
    }
    
    public String getAppletInfo()
    {
	return "Apfel.class $Date: 2000/03/25 20:42:12 $,\n" +
            "Copyright (C) 1998 Manfred Thole, manfred@thole.org\n" +
	    "\n" +
	    "This program is free software; you can redistribute it and/or modify it\n" +
	    "under the terms of the GNU General Public License as published by the\n" +
	    "Free Software Foundation; either version 2 of the License, or (at your\n" +
	    "option) any later version.\n" +
	    "\n" +
	    "This program is distributed in the hope that it will be useful, but\n" +
	    "WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
	    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" +
	    "General Public License for more details.\n" +
	    "\n" +
	    "You should have received a copy of the GNU General Public License along\n" +
	    "with this program; if not, write to the Free Software Foundation, Inc.,\n" +
	    "675 Mass Ave, Cambridge, MA 02139, USA.\n";
    }

  public String[][] getParameterInfo() {
      String[][] info = { { "size_x", "int", "100" },
			  { "size_y", "int", "100" },
			  { "xa", "double", "-2.25" },
			  { "xe", "double", "0.75" },
			  { "ya", "double", "-1.5" },
			  { "ye", "double", "1.5" },
			  { "itmax", "int", "10" } 
      };
      return info;
  } 
}
