/*
	Spirograph Applet

	File: Spiro.java
	Author: Anu Garg <http://www.wordsmith.org/~anu/anu.html>
	Email:  anu@wordsmith.org

	A Spirograph is a curve defined by the equations:

	x = (R+r)*cos(t) - (r+O)*cos(((R+r)/r)*t)
	y = (R+r)*sin(t) - (r+O)*sin(((R+r)/r)*t)

	Where R and r are the radii of fixed and moving circle,
	and O is the offset in the moving circle.

*/

import java.awt.*;
import java.applet.*;
import java.lang.*;

//===========================Class: spiro=========================

public class Spiro extends Applet{

	private int R = 50, r = 10, O = 5;      // Radii
	private int I = 400;                    // Number of Iterations

	// Scrollbars for radii and I
	Scrollbar sliderR, sliderr, sliderO, sliderI;
	String sliderTextR = "Fixed circle radius (1-100): ";
	String sliderTextr = "Moving circle radius (1-100): ";
	String sliderTextO = "Moving circle offset (1-100): ";
	String sliderTextI = "Iterations (100-400): ";
	Label sliderLabelR, sliderLabelr, sliderLabelO, labelEmpty, sliderLabelI;
	// sliderLabelR = sliderTextR + string(R)

	Panel fields;

	// Scrollbars for colors
	Scrollbar redSlider,blueSlider,greenSlider;
	Label redLabel, greenLabel, blueLabel;
	private int redBits = 90, greenBits = 246, blueBits = 255;
	String sliderTextRed = "Red (0-255): ";
	String sliderTextGreen = "Green (0-255): ";
	String sliderTextBlue = "Blue (0-255): ";
	Panel colorPanel;

	Font font;
	Panel controlPanel;
	String audioScroll = "drip.au";
	String audioButton = "clink.au";

	// Get parameters (for radii, color, #iterations)
	public void getParams()
	{
		if(getParameter("R") !=  null)
		{
			R = new Integer(new String(getParameter("R"))).intValue();
			if(R < 1)
				R = 1;
			else if(R > 100)
				R = 100;
		}

		if(getParameter("smallr") !=  null)
		{
			r = new Integer(new String(getParameter("smallr"))).intValue();
			if(r < 1)
				r = 1;
			else if(r > 100)
				r = 100;
		}

		if(getParameter("O") !=  null)
		{
			O = new Integer(new String(getParameter("O"))).intValue();
			if(O < 1)
				O = 1;
			else if(O > 100)
				O = 100;
		}

		if(getParameter("redBits") !=  null)
		{
			redBits = new Integer(new String(getParameter("redBits"))).intValue();
			if(redBits < 0)
				redBits = 0;
			else if(redBits > 255)
				redBits = 255;
		}

		if(getParameter("greenBits") !=  null)
		{
			greenBits = new Integer(new String(getParameter("greenBits"))).intValue();
			if(greenBits < 0)
				greenBits = 0;
			else if(greenBits > 255)
				greenBits = 255;
		}

		if(getParameter("blueBits") !=  null)
		{
			blueBits = new Integer(new String(getParameter("blueBits"))).intValue();
			if(blueBits < 0)
				blueBits = 0;
			else if(blueBits > 255)
				blueBits = 255;
		}

		if(getParameter("I") !=  null)
		{
			I = new Integer(new String(getParameter("I"))).intValue();
			if(I < 100)
				I = 100;
			else if(I > 400)
				I = 400;
		}
	}

	public void init()
	{
		getParams();

		//setBackground(Color.gray);
		setForeground(Color.white);
		font = new Font("Helvetica", Font.BOLD, 12);
		setLayout(new BorderLayout());

		controlPanel = new Panel();
		controlPanel.setLayout(new GridLayout(15,1));
		add("East", controlPanel);

		sliderLabelR = new Label(sliderTextR + Integer.toString(R));
		controlPanel.add(sliderLabelR);
		sliderR = new Scrollbar(Scrollbar.HORIZONTAL, R, 1, 1, 100);
		controlPanel.add(sliderR);

		sliderLabelr = new Label(sliderTextr + Integer.toString(r));
		controlPanel.add(sliderLabelr);
		sliderr = new Scrollbar(Scrollbar.HORIZONTAL, r, 1, 1, 100);
		controlPanel.add(sliderr);

		sliderLabelO = new Label(sliderTextO + Integer.toString(O));
		controlPanel.add(sliderLabelO);
		sliderO = new Scrollbar(Scrollbar.HORIZONTAL, O, 1, 0, 100);
		controlPanel.add(sliderO);
 
		redLabel = new Label(sliderTextRed + Integer.toString(redBits));
		controlPanel.add(redLabel);
		redSlider = new Scrollbar(Scrollbar.HORIZONTAL, redBits, 1, 0, 255);
		controlPanel.add(redSlider);

		greenLabel = new Label(sliderTextGreen + Integer.toString(greenBits));
		controlPanel.add(greenLabel);
		greenSlider = new Scrollbar(Scrollbar.HORIZONTAL, greenBits, 1, 0, 255);
		controlPanel.add(greenSlider);

		blueLabel = new Label(sliderTextBlue + Integer.toString(blueBits));
		controlPanel.add(blueLabel);
		blueSlider = new Scrollbar(Scrollbar.HORIZONTAL, blueBits, 1, 0, 255);
		controlPanel.add(blueSlider);
 
		sliderLabelI = new Label(sliderTextI + Integer.toString(I));
		controlPanel.add(sliderLabelI);
		sliderI = new Scrollbar(Scrollbar.HORIZONTAL, I, 1, 100, 400);
		controlPanel.add(sliderI);

		controlPanel.add(new Button("Random"));
	}

	public boolean handleEvent(Event e)
	{
		if (e.target instanceof Scrollbar) {
			int value = ((Scrollbar)e.target).getValue();
			if (e.target == sliderR) {
				sliderLabelR.setText(sliderTextR + Integer.toString(value));
				R = value;
			} else if (e.target == sliderr) {
				sliderLabelr.setText(sliderTextr + Integer.toString(value));
				r = value;
			} else if (e.target == sliderO) {
				sliderLabelO.setText(sliderTextO + Integer.toString(value));
				O = value;
			} else if (e.target == redSlider) {
				redLabel.setText(sliderTextRed + Integer.toString(value));
				redBits=value;
			} else if (e.target == greenSlider) {
				greenLabel.setText(sliderTextGreen + Integer.toString(value));
				greenBits=value;
			} else if (e.target == blueSlider) {
				blueLabel.setText(sliderTextBlue + Integer.toString(value));
				blueBits=value;
			} else if (e.target == sliderI) {
				sliderLabelI.setText(sliderTextI + Integer.toString(value));
				I = value;
			}
			repaint();
			play(getDocumentBase(), audioScroll);
			return true;
		}
		return super.handleEvent(e);
	}

	public boolean action(Event e, Object arg)
	{
		if("Random".equals(arg)){
			R = (int)(Math.random()*100+1);
			r = (int)(Math.random()*100+1);
			O = (int)(Math.random()*r);
			sliderLabelR.setText(sliderTextR + Integer.toString(R));
			sliderLabelr.setText(sliderTextr + Integer.toString(r));
			sliderLabelO.setText(sliderTextO + Integer.toString(O));
			sliderR.setValue(R);
			sliderr.setValue(r);
			sliderO.setValue(O);

			redBits = (int)(Math.random()*255);
			blueBits = (int)(Math.random()*255);
			greenBits = (int)(Math.random()*255);
			redLabel.setText(sliderTextRed + Integer.toString(redBits));
			greenLabel.setText(sliderTextGreen + Integer.toString(greenBits));
			blueLabel.setText(sliderTextBlue + Integer.toString(blueBits));
			redSlider.setValue(redBits);
			greenSlider.setValue(greenBits);
			blueSlider.setValue(blueBits);

			play(getCodeBase(), audioButton);
			repaint();
			return true;
		}
		return true;
	}

	public void paint(Graphics g)
	{
		int x = 0;
		int y = 0;
		int prevx = 0;
		int prevy = 0;
		int t;

		int x1, y1, x2, y2;

		g.setFont(font);
		g.clipRect(0,0,300,300);

		g.setColor(new Color(redBits, greenBits, blueBits));

		for(t=0; t<=I; t++){
			prevx = x;
			prevy = y;
			x = (int)((R+r)*Math.cos((double)t) - (r+O)*Math.cos((double)(((R+r)/r)*t)));
			y = (int)((R+r)*Math.sin((double)t) - (r+O)*Math.sin((double)(((R+r)/r)*t)));

			if (t > 0){
				//g.drawLine(x+150, y+150, x+150, y+150);
				g.drawLine(prevx+150, prevy+150, x+150, y+150);
			}
		}
	}
}
