import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;

import javax.media.j3d.*;
import javax.vecmath.*;

import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Cylinder;

/**
Solution to Lab 9 by Rod Harris
*/

public class Lab9
{
	private MyVirtualUniverse vu = new MyVirtualUniverse();

	private JTextArea selectedArea = new JTextArea(1, 10);

	private Board3D board = null;

	private BranchGroup pickBG = new BranchGroup();

	private Box			box			= null;
	private Sphere		sphere		= null;
	private Cone		cone		= null;
	private Cylinder	cylinder	= null;


	public static void main(String[] args)
	{
		new Lab9();
	}


	public Lab9()
	{
		ApplicationFrame appFrame = new ApplicationFrame("Lab 9", 800, 600);
		appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		board = vu.getBoard();

		JPanel mainPanel = new JPanel(new BorderLayout());
		JPanel eastPanel = new JPanel(new BorderLayout());

		eastPanel.add(selectedArea, BorderLayout.CENTER);

		eastPanel.setBorder(new EmptyBorder(5,5,5,5));

		mainPanel.add(board, BorderLayout.CENTER);

		mainPanel.add(eastPanel, BorderLayout.EAST);

		appFrame.getContentPane().add(mainPanel);

		addContent();

		board.addMouseListener(new MouseHandler());

		appFrame.setVisible(true);
	}


	public void addContent()
	{
		Appearance redApp = new Appearance();
		ColoringAttributes redCA = new ColoringAttributes();
		redCA.setColor(new Color3f(1, 0, 0));
		redApp.setColoringAttributes(redCA);

		Appearance greenApp = new Appearance();
		ColoringAttributes greenCA = new ColoringAttributes();
		greenCA.setColor(new Color3f(0, 1, 0));
		greenApp.setColoringAttributes(greenCA);

		Appearance blueApp = new Appearance();
		ColoringAttributes blueCA = new ColoringAttributes();
		blueCA.setColor(new Color3f(0, 0, 1));
		blueApp.setColoringAttributes(blueCA);

		Appearance yellowApp = new Appearance();
		ColoringAttributes yellowCA = new ColoringAttributes();
		yellowCA.setColor(new Color3f(1, 1, 0));
		yellowApp.setColoringAttributes(yellowCA);


		TransformGroup tg1 = new TransformGroup();
		Transform3D t3d1 = new Transform3D();
		t3d1.set(new Vector3d(0,0,-15));
		tg1.setTransform(t3d1);
		tg1.addChild(box = new Box(1f, 1f, 1f, redApp));
		pickBG.addChild(tg1);

		TransformGroup tg2 = new TransformGroup();
		Transform3D t3d2 = new Transform3D();
		t3d2.set(new Vector3d(3,1,-15));
		tg2.setTransform(t3d2);
		tg2.addChild(sphere = new Sphere(.9f, blueApp));
		pickBG.addChild(tg2);

		TransformGroup tg3 = new TransformGroup();
		Transform3D t3d3 = new Transform3D();
		t3d3.set(new Vector3d(-3,-1,-15));
		tg3.setTransform(t3d3);
		tg3.addChild(cone = new Cone(1f, 1.5f, greenApp));
		pickBG.addChild(tg3);

		TransformGroup tg4 = new TransformGroup();
		Transform3D t3d4 = new Transform3D();
		t3d4.set(new Vector3d(-1,.5,-15));
		tg4.setTransform(t3d4);
		tg4.addChild(cylinder = new Cylinder(.75f, 2f, yellowApp));
		pickBG.addChild(tg4);

		vu.addBranchGraph(pickBG);
	}

	private void mouseClick(int x, int y)
	{
		Point3d eye_pos = new Point3d();
		Point3d mouse_pos = new Point3d();

		board.getCenterEyeInImagePlate(eye_pos);
		board.getPixelLocationInImagePlate(x, y, mouse_pos);

		Transform3D motion = new Transform3D();
		board.getImagePlateToVworld(motion);
		motion.transform(eye_pos);
		motion.transform(mouse_pos);

		Vector3d direction = new Vector3d(mouse_pos);
		direction.sub(eye_pos);

		PickRay pickRay = new PickRay(eye_pos, direction);

		SceneGraphPath[] path = pickBG.pickAll(pickRay);


		String s = "";
		s += "\n";

		if (path != null)
		{
			for (int i=0; i<path.length; i++)
			{
				for (int j=0; j<path[i].nodeCount(); j++)
				{
					if (path[i].getNode(j) == box)
					{
						s += "Box";
					}
					else if (path[i].getNode(j) == sphere)
					{
						s += "Sphere";
					}
					else if (path[i].getNode(j) == cone)
					{
						s += "Cone";
					}
					else if (path[i].getNode(j) == cylinder)
					{
						s += "Cylinder";
					}
				}
				s += "\n";
			}

		}
		else
		{
			s += "null";
		}

		selectedArea.setText(s);
	}

	private class MouseHandler extends MouseAdapter
	{
		public void mousePressed(MouseEvent e)
		{
			int x = e.getX();
			int y = e.getY();

			mouseClick(x, y);
		}
	}
}
