import java.applet.Applet;
import java.awt.Panel;
import java.awt.BorderLayout;
import java.awt.GraphicsEnvironment;
import java.util.Enumeration;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import javax.sound.sampled.*;

import javax.media.j3d.*;
import javax.vecmath.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.applet.MainFrame;

public class CollisionApp extends Applet {

    // Universe
    private SimpleUniverse universe_     = null;
    private Canvas3D can_                = null;
    private BranchGroup sceneRoot_       = null;
    private PickTool tool_               = null;

// -----------------------------------------------------------------------------
// CT
// -----------------------------------------------------------------------------
    public CollisionApp () {
        this.setLayout(new BorderLayout());

        // - Canvas
        can_ = new Canvas3D(
            SimpleUniverse.getPreferredConfiguration()
        );
        this.add("Center", can_);

        // - SimpleUniverse
        universe_ = new SimpleUniverse(can_);

        // - Scene
        sceneRoot_ = new BranchGroup();

        // - Viewing
        TransformGroup viewTr = universe_.getViewingPlatform().getViewPlatformTransform();
        Transform3D tr3d = new Transform3D();
        tr3d.setTranslation(new Vector3f(0,0,10));
        viewTr.setTransform(tr3d);

        // - Building Plane
        sceneRoot_.addChild( this.createPlane() );
        // - Tracing Collision
        sceneRoot_.addChild(new Trace(this));

        // - PickTool
        tool_ = new PickTool(sceneRoot_);
        tool_.setMode(PickTool.GEOMETRY_INTERSECT_INFO);
        this.setPickCapabilities(sceneRoot_);

        // - Liven
        universe_.addBranchGraph(sceneRoot_);
    }

// -----------------------------------------------------------------------------
// PICK TEST!!!
// -----------------------------------------------------------------------------
    public void confirmPickTest(Point3d start, Point3d end) {
        tool_.setShapeCylinderSegment(start, end, 0.5d );
        PickResult[] results = tool_.pickAll();
        System.out.println("Cylinder Segment:\nStart: " + start + "\nEnd: " + end);
        if ( results == null ) System.out.println("No intersection available!");
        else System.out.println("Intersections available!");
    }


// -----------------------------------------------------------------------------
// BUILDING PLANE AT THE ORIGIN AND PERPENDICULAR TO (xz)-PLANE
// (have a look at the mail!)
// THAT'S ALL YOU HAVE TO KNOW
// -----------------------------------------------------------------------------
    private BranchGroup createPlane() {
        QuadArray quad  = new QuadArray(4, QuadArray.COORDINATES);
        Point3d[] points = {
            new Point3d(-2, 2, 0),
            new Point3d(-2, -2, 0),
            new Point3d(2, -2, 0),
            new Point3d(2, 2, 0)
        };
        quad.setCoordinates(0, points);
        System.out.println("Plane description: QuadArray of 4 vertices");
        for ( int i = 0; i < points.length; i++ ) System.out.println("Point #" + i + ": " + points[i]);
        Appearance ap = new Appearance();
        ap.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0.4f));
        Shape3D shape = new Shape3D(quad, ap);

        BranchGroup bg = new BranchGroup();
        bg.addChild(shape);
        return bg;
    }

// -----------------------------------------------------------------------------
// SETTING PICK ATTRIBUTES OF EACH SHAPE...
// -----------------------------------------------------------------------------
    private void setPickCapabilities(Node node) {
        if ( node instanceof Group ) {
            Group group = (Group) node;
            for ( int i = 0; i < group.numChildren(); i++)
                setPickCapabilities(group.getChild(i));
        } else if ( node instanceof Shape3D ) {
            Shape3D shape = (Shape3D) node;
            PickTool.setCapabilities(shape, PickTool.INTERSECT_FULL);
            shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
            for ( int i = 0; i < shape.numGeometries(); i++ ) {
                Geometry geo = shape.getGeometry(i);
                if (geo instanceof GeometryArray ) {
                    GeometryArray array = (GeometryArray) geo;
                    array.setCapability(GeometryArray.ALLOW_FORMAT_READ);
                    array.setCapability(GeometryArray.ALLOW_COUNT_READ);
                    array.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
                    array.setCapability(GeometryArray.ALLOW_NORMAL_READ);
                    array.setCapability(GeometryArray.ALLOW_REF_DATA_READ);
                    array.setCapability(GeometryArray.ALLOW_TEXCOORD_READ);
                }
            }
        } else if (node instanceof Morph ) {
            Morph morph = (Morph) node;
            PickTool.setCapabilities(morph, PickTool.INTERSECT_FULL);
        }
        return;
    }


// -----------------------------------------------------------------------------
// MAIN
// -----------------------------------------------------------------------------
    public static void main(String[] args) {
        MainFrame frame = new MainFrame(new CollisionApp(),  args, 500, 600);
    }

} // CLASS
