// Rainbow.java Copyright 1996 by Andrew C Stone - All Rights Reserved

import java.awt.*;
import java.applet.*;


public class Rainbow extends java.applet.Applet implements Runnable {
    
    Thread runner;
    int colorCount;
    int rows;
    int thickness;
    int delay;
    int offset;
    int current;
    int rad;
    int hgt;
    int mode;
    
    Color colors[];
  
   private int getIntParameter(String s) {
	if (s != null) return Integer.parseInt(s);
	else return 10;
   }

   private double getDoubleParameter(String s) {
   	double val = 1.;
	if (s != null) {
	    try { val = Double.valueOf(s).doubleValue();
	    } catch (NumberFormatException e) {
	    
	    }
	}
	if (val > 1.) val = 1.;
	else if (val < 0.) val = 0.; 	// yucchy black?
	return val;
   }

 public void init() {
	double saturation = getDoubleParameter(getParameter("saturation"));
	double brightness = getDoubleParameter(getParameter("brightness"));
	delay = getIntParameter(getParameter("delay"));
	colorCount = getIntParameter(getParameter("numberColors"));
	rows = getIntParameter(getParameter("rows"));
	thickness = getIntParameter(getParameter("thickness"));
	offset = getIntParameter(getParameter("offset"));
	mode = getIntParameter(getParameter("mode"));
	rad = (int)((float)size().width/2f);
       hgt = (int)((float)size().height/2f);
       current = 0;

	getTheColors(saturation,brightness);
	getTheColors(saturation,brightness);
  }
  
  private void getTheColors(double saturation, double brightness) {
		int i;
		double inc = 1./(double)colorCount;
		double curHue = 0.;
		colors = new Color[colorCount + 1];
		for (i = 0; i <= colorCount; i++) {
		    colors[i] = 
			  Color.getHSBColor((float)curHue,
			  (float)saturation,(float)brightness);
		    curHue += inc;	// may be off by one?
		}
   }

  public void start() {
    if (runner == null) {
      runner = new Thread(this);
      runner.start();
    }
  }

  public void stop() {
    if (runner != null) {
      runner.stop();
      runner = null;
    }
  }

  public void run() {
            while (true) {
		    repaint();
		    if (delay > 0)
			pause(delay);
	    }

  }

  void pause(int time) {
    try { Thread.sleep(time); }
    catch (InterruptedException e) { }
  }

  public void paint(Graphics g) {
       int r,c;
       if (mode == 0) {
	    for (r = 0; r < rows; r++ ) {
	    int num = (current + r*offset) % colorCount;
	    g.setColor(colors[num]);
		for ( c = 0; c < thickness; c++ ) {
		    int inset = r*c + c;
		    g.drawArc( inset,inset, 2 *(rad - inset) ,2 *( hgt - inset),0,360);
		}
	    }
       } else if (mode == 1) {
	    for (r = 0; r < rows; r++ ) {
	    int num = (current + r*offset) % colorCount;
	    g.setColor(colors[num]);
		for ( c = 0; c < thickness; c++ ) {
		    int inset = r*c + c;
		    g.drawArc( inset,inset, 2 *(rad - inset) ,4 *( hgt - inset),0,360);
		}
	    }
       } else if (mode == 2) {
	    for (r = 0; r < rows; r++ ) {
	    int num = (current + r*offset) % colorCount;
	    g.setColor(colors[num]);
		for ( c = 0; c < thickness; c++ ) {
		    int inset = r*c + c;
		    g.drawArc( inset,inset, 2 *rad - inset ,4 *hgt - inset,0,360);
		}
	    }
       } else if (mode == 3) {
	    for (r = 0; r < rows; r++ ) {
	    int num = (current + r*offset) % colorCount;
	    g.setColor(colors[num]);
		for ( c = 0; c < thickness; c++ ) {
		    int inset = r*c + c;
		    g.drawArc( inset/2,inset/2, 2 *rad - inset ,4 *hgt - inset,0,360);
		}
	    }
       }
       // increment current (which is our staring point)
       if (++current > colorCount) current = 0;
  }

  public boolean mouseDown(Event evt, int x, int y) {
     if (runner == null) start();
	else stop();
     return true;
  }

  public void update(Graphics g) {
	paint(g);
  }
}



