// Michael Tartaglia
// 18 July 2002
// Nested Boxes: program creates boxes in boxes and so on recursively

import java.awt.*;
import java.applet.Applet;

public class NestedBoxes extends Applet {
	public Image backBuffer, nameBuffer;		// IMAGE AND NAMEPLATE BUFFERS
	public Graphics bufferPaint, namePaint;	// IMAGE AND NAMEPLATE GRAPHICS PKGS
	public int width = 83,			// APPLET WIDTH
				  step,					// NESTED BOX'S ORIGIN PADDING WIDTH FOR DRAWING
				  boxes = 4;			// NUMBER OF NESTED BOXES, AKA RECURSION DEPTH
	public boolean go;				// LOOP CONTROL BOOLEAN
	public Color[] colors = {new Color(180,0,0),new Color(180,180,60),Color.white};

	public void init() {
		// CREATE BUFFER FOR IMAGE
		backBuffer = this.createImage(width,width);
		bufferPaint = backBuffer.getGraphics();
		setBackground(Color.white);

		// CREATE NAMEPLATE
		nameBuffer = this.createImage(width,24);
		namePaint = nameBuffer.getGraphics();
		namePaint.setColor(Color.gray);
		namePaint.setFont(new Font("Arial",Font.BOLD,11));
		namePaint.drawString("Square Dance",3,10);
		namePaint.setColor(Color.black);
		namePaint.setFont(new Font("Arial",Font.PLAIN,10));
		namePaint.drawString("by M Tartaglia",3,21);
		namePaint.drawRect(0,0,width-2,23);

		go = true;		// SET VARIABLES
		width-=2;		// ADJUST WIDTH FOR 1 PX BORDER
	}
	public void stop() {go = false;}
	public void destroy() {go = false;}

	public void update(Graphics g) {paint(g);}
	public void paint(Graphics g) {
		// THE BOXES ARE ARRANGED IN A CHECKERBOARD PATTERN INITIALLY,
		//		THEREFORE, ONE BOX IN, SAY, THE TOP ROW IS DRAWN AT POINT (0,0)
		//		AND THE OTHER ONE IS DRAWN AT POT (2/3*WIDTH,0), BECAUSE THE WIDTH
		//		OF THE NESTED BOXES IS EQUAL TO THE WIDTH OF THE PARENT BOX * 2/3
		if (step == 0) step = width*2/3;
		
		// RECURSIVELY DRAW IMAGES
		drawBoxes(bufferPaint, width, 1, 1, boxes, --step);
		
		g.drawImage(backBuffer,1,1,this);
		g.drawImage(nameBuffer,2,width+2,this);

		if (go) {	// LOOP
			try {Thread.sleep(20);repaint();}
			catch (InterruptedException ie) {};
		}
	}

	public void drawBoxes(Graphics g,
								 int curWidth,	// CURRENT BOX WIDTH
								 int curX,		// CURRENT BOX'S X POSITION
								 int curY,		// CURRENT BOX'S Y POSITION
								 int curBox,	// CURRENT BOX DEPTH IN RECURSION
								 int step)		// PADDING
	{
		if (curBox > 0) {
			curBox -= 1;										// CURRENT BOX LEVEL
			g.setColor(colors[curBox%colors.length]);	// SET BOX COLOR
			g.fillRect(curX,curY,curWidth,curWidth);	// FILL BOX
			g.setColor(Color.black);
			g.drawRect(curX,curY,curWidth,curWidth);	// DRAW BOX'S BORDER
			curWidth /= 3;				// RESET BOX WITH FOR NESTED BOXES
			drawBoxes(g, curWidth, curX, curY+step, curBox, step/3);
			drawBoxes(g, curWidth, curX+(2*curWidth)-step, curY, curBox, step/3);
			drawBoxes(g, curWidth, curX+step, curY+(2*curWidth), curBox, step/3);
			drawBoxes(g, curWidth, curX+(2*curWidth), curY+(2*curWidth)-step, curBox, step/3);
		}
	}
}
