
import com.sun.j3d.utils.geometry.*;
import java.awt.*;
import java.io.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class CoordinateSystem extends TransformGroup {

	protected double size = 0;
	protected LineArray lines = null;
	protected BoundingSphere bounds = null;
	protected Shape3D axes = null;
	protected Color3f letterColor = new Color3f(1,1,1);
	protected Color3f axisColor = new Color3f(1,1,1);
	
	// it seems like 500 makes it hang when closing
	// like it wouldn't deallocate the letters...
	protected int letterSize = 500;

	public CoordinateSystem(float size) {

		// top level stuff, you should always be able to
		// manipulate the coordinate system
		super();

		setCapability(ALLOW_TRANSFORM_WRITE);
		setCapability(ALLOW_TRANSFORM_READ);
		setCapability(ALLOW_CHILDREN_READ);
		setCapability(ALLOW_CHILDREN_WRITE);
		setCapability(ALLOW_CHILDREN_EXTEND);

		// create the 3 coordinate axes
		lines = new LineArray(6, LineArray.COORDINATES | LineArray.COLOR_3);
		Point3f[] points = new Point3f[6];
		this.size = size;
		points[0] = new Point3f(0, -size, 0);
		points[1] = new Point3f(0,  size, 0);
		points[2] = new Point3f(-size, 0, 0);
		points[3] = new Point3f( size, 0, 0);
		points[4] = new Point3f(0, 0, -size);
		points[5] = new Point3f(0, 0,  size);
		lines.setCoordinates(0, points);
		for(int i=0; i<6; i++)
			lines.setColor(i, axisColor );

		// allow lines length to change
		lines.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
		lines.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);

		axes = new Shape3D(lines);

		// to translate the letters
		Transform3D x_position = new Transform3D();
		Transform3D y_position = new Transform3D();
		Transform3D z_position = new Transform3D();
		x_position.setTranslation(new Vector3f(size, 0f , 0f));
		y_position.setTranslation(new Vector3f(0f, size , 0f));
		z_position.setTranslation(new Vector3f(0f, 0f , size));
		TransformGroup x_translate = new TransformGroup(x_position);
		TransformGroup y_translate = new TransformGroup(y_position);
		TransformGroup z_translate = new TransformGroup(z_position);

		// the targets of the Billboard behaviors
		TransformGroup x_rotate = new TransformGroup();
		TransformGroup y_rotate = new TransformGroup();
		TransformGroup z_rotate = new TransformGroup();
		x_rotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);		y_rotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);		z_rotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		Billboard x_board = new Billboard(x_rotate);
		Billboard y_board = new Billboard(y_rotate);
		Billboard z_board = new Billboard(z_rotate);
		x_board.setAlignmentMode(Billboard.ROTATE_ABOUT_POINT);
		y_board.setAlignmentMode(Billboard.ROTATE_ABOUT_POINT);
		z_board.setAlignmentMode(Billboard.ROTATE_ABOUT_POINT);

		bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0 );
		x_board.setSchedulingBounds(bounds);
		y_board.setSchedulingBounds(bounds);
		z_board.setSchedulingBounds(bounds);
		
		Text2D x_letter = new Text2D("X", letterColor, "Serif", letterSize, Font.PLAIN);
		Text2D y_letter = new Text2D("Y", letterColor, "Serif", letterSize, Font.PLAIN);
		Text2D z_letter = new Text2D("Z", letterColor, "Serif", letterSize, Font.PLAIN);		// build the tree from the top down
		addChild(axes);
		addChild(x_translate);
		addChild(y_translate);
		addChild(z_translate);
		x_translate.addChild(x_board);
		y_translate.addChild(y_board);
		z_translate.addChild(z_board);
			x_translate.addChild(x_rotate);
		y_translate.addChild(y_rotate);
		z_translate.addChild(z_rotate);				// somehow these seem to keep the outer transform from pick/rotating
    // these make it lock up
		///*		x_rotate.addChild(x_letter);		y_rotate.addChild(y_letter);		z_rotate.addChild(z_letter);
//*/
	}

	public void setScale(double scale_factor){}
	public void setSize(double size){}
	public void setAxesColor(Color3f color){}
	public double getScale(){return 1.0;}
	public double getSize(){return size;}
	public Color3f getAxesColor(){return axisColor;}
	public void useAxes(boolean use){}
	public void useLetters(boolean use){}
	
	public void setLetterColor(Color3f color){ letterColor = color; }
	public void setLetterSize(int size){ letterSize = size; }	
	public Color3f getLetterColor(){ return letterColor; }
	public int getLetterSize(){ return letterSize; }	
	
}