package ps;

import java.awt.*;
import java.awt.geom.*;
import tiler.*;
import java.util.*;
import java.io.*;

public class Tiling {
    public static void main(String[] args) {
	int LEVEL = 8;
	int width = 500; int height = 500;
	int initType = Rhomb.FAT;

	Rhomb.setFatColor(new Color(0.7f, 0.7f, 1f));
	Rhomb.setSkinnyColor(new Color(0.6f, 0.8f, 0.6f));

	Rectangle2D.Double border = 
	    new Rectangle2D.Double(0, 0, width, height);

	double angle;
	if (initType == Rhomb.FAT) angle = Math.PI*2/5;
	else angle = Math.PI/5;

	double s = Math.sin(angle/2);
	double c = Math.cos(angle/2);
	double W = (height*c + width);
	int side = (int) (W/c)+1;
	AffineTransform transform = new AffineTransform();
	transform.translate(width/2, height/2);
	transform.translate(-W, 0);
	transform.rotate(-Math.PI/5);

	ToPS ps;
	try {
	    ps = new ToPS("tiling.eps", 0, 0, 500, 500);
	} catch(FileNotFoundException ex) {
	    System.err.println("File not found");
	    return;
	}

	ZZeta zero = new ZZeta(0, 0, 0, 0, 0);
	ZZeta one = new ZZeta(side, 0, 0, 0, 0);
	Edge e = new Edge(new Vertex(zero), new Vertex(one), 1);
	Edge[] edges = Rhomb.getEdges(e, Edge.LEFT, initType);
	Rhomb initialRhomb = new Rhomb(edges, initType);

	BinarySearchTree intermediateRhombs = new BinarySearchTree();
	Stack stack = new Stack();
	stack.push(initialRhomb);
	initialRhomb.initializeDeflates();

	while(stack.isEmpty() == false) {
	    Rhomb rhomb = (Rhomb) stack.peek();
	    Rhomb nextRhomb = rhomb.getNextDeflate();
	    if (nextRhomb == null) {
		stack.pop();
		continue;
	    }
	    if (intermediateRhombs.contains(nextRhomb) != null
		|| !nextRhomb.intersects(transform, border)) continue;

	    if (stack.size() == LEVEL) {
		ps.appendToPath(nextRhomb.getShape(transform));
		ps.gsave();
		ps.setrgbcolor(nextRhomb.getColor());
		ps.fill();
		ps.grestore();
		ps.stroke();
		continue;
	    }
	    nextRhomb.initializeDeflates();
	    intermediateRhombs.insert(nextRhomb);
	    stack.push(nextRhomb);
	}
	
	ps.showpage();
    }
}

