import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Arrays;

public class ModelViewer extends JFrame {
	private class Canv extends Canvas {
		public Canv() {
			setBackground(Color.white);
			setPreferredSize(new Dimension(300, 300));
		}

		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			Dimension d = getSize();
			double w = d.getWidth();
			double h = d.getHeight();
			int[] pixels = getPixels();
			Arrays.fill(pixels, 0xFFFFFFFF);
			Graphics3D g3 = new Graphics3D(pixels, (int) w, (int) h);
			g3.setViewTransform(V);
			g3.setProjectionTransform(P);
			g3.setLighting(lighting);
			g3.setViewFrameTransform(Transform.translate(1, 1, 0)
					.prepend(Transform.scale(w / 2, -h / 2, 1))
					.prepend(Transform.translate(0, h, 0)));
			model.draw(g3);
			newPixels(pixels);
		}
	}

	private class WindowCloser extends WindowAdapter {
		public void windowClosing(WindowEvent e) { System.exit(0); }
	}

	private Canv canvas;
	private Model model;
	private LightModel lighting;
	private Transform V;
	private Transform P;

	public ModelViewer() {
		canvas = new Canv();
		model = Model.EMPTY;
		V = Transform.IDENTITY;
		P = Transform.IDENTITY;

		setTitle("Model Viewer");
		addWindowListener(new WindowCloser());

		getContentPane().add(canvas);
		pack();
	}

	public void addKeyListener(KeyListener l) { canvas.addKeyListener(l); }
	public void removeKeyListener(KeyListener l) { canvas.removeKeyListener(l); }
	public void addFocusListener(FocusListener l) { canvas.addFocusListener(l); }
	public void removeFocusListener(FocusListener l) { canvas.removeFocusListener(l); }
	public void grabFocus() { canvas.grabFocus(); }

	public void setModel(Model m) {
		model = m;
		canvas.repaint();
	}

	public void setLighting(LightModel l) {
		lighting = l;
		canvas.repaint();
	}

	public void setViewTransform(Transform x) {
		V = x;
		canvas.repaint();
	}

	public void setProjectionTransform(Transform x) {
		P = x;
		canvas.repaint();
	}


}
