// PickScreenObject - Class to pick Shape3D objects interactively
// from the screen. Returns a Shape3D object/objects depending upon
// the mode of picking (closets/any etc...)
// Written by Anand B Pillai abpillai@excite.com
// CopyRight(C) 2001 Anand B Pillai.

import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.picking.behaviors.*;
import java.util.Enumeration;
import com.sun.j3d.utils.behaviors.picking.PickObject;
import javax.media.j3d.SceneGraphPath;
import javax.vecmath.Point3d;
import javax.vecmath.Color3f;

public class PickScreenObject extends Behavior {

    private TransformGroup targetTG;
    private BranchGroup scene;
    private Canvas3D canvas;

    public static final int GET_CLOSEST=0;
    public static final int  GET_ANY = 1;
    public static final int  GET_ALL = 2;
    public static final int GET_ALLSORTED = 3;

    private int retparam;
    public Shape3D shape;
    public Shape3D shapes[];
    
//    private WakeupOnAWTEvent trigger = new WakeupOnAWTEvent(MouseEvent.MOUSE_ENTERED);
    private WakeupOnAWTEvent select = new WakeupOnAWTEvent(MouseEvent.MOUSE_CLICKED);

    PickScreenObject(TransformGroup  targetTG, BranchGroup scene, Canvas3D canvas)
        {
            this.targetTG=targetTG;
            this.scene=scene;
            this.canvas=canvas;
        }

    public void setRetParam(int ret_param)
	{
	    this.retparam=ret_param;
	}

    public void initialize()
	{
	    this.wakeupOn(select);
	}

    public void processStimulus(Enumeration criteria)
	{
	    PickObject obj = new PickObject(canvas,scene);
	    this.wakeupOn(select);

            int mouseX=0, mouseY=0;
	    AWTEvent myEvent[] = select.getAWTEvent();
	    MouseEvent event1=null;
	    
	    try{
		event1 = (MouseEvent) myEvent[0];
	    }
	    catch (ArrayIndexOutOfBoundsException a){}

	    if ( event1 != null )
	    {
		mouseX = event1.getX();
		mouseY = event1.getY();
		System.out.println(mouseX + " " + mouseY);
	    }

	    SceneGraphPath path=null;
	    SceneGraphPath[] paths=null;
	     
	    switch (this.retparam)
	    {
		case GET_CLOSEST:
		    path = obj.pickClosest(mouseX, mouseY);
		    break;
		case GET_ANY:
		    path = obj.pickAny(mouseX, mouseY);
		    break;
		case GET_ALL:
		    paths = obj.pickAll(mouseX, mouseY);
		    break;
		case GET_ALLSORTED:
		    paths = obj.pickAllSorted(mouseX, mouseY);
		    break;
	    }
		     
	    switch (this.retparam)
	    {
		case GET_CLOSEST:
		case GET_ANY:
		    if ( path != null )
		    {

			Node shape = path.getObject();
			if ( shape != null )
			{
			    System.out.println("Shape is  " + path);
			}

			this.shape = (Shape3D) shape;
		    }
		    else
		    {
			System.out.println("No hits!");
		    }
		    break;
		case GET_ALL:
		case GET_ALLSORTED:

		    if ( paths != null )
		    {
			int size = paths.length;
			this.shapes = new Shape3D[size];
		     
			for( int hitI=0; hitI<size; hitI++ ) 
			{
			    System.out.println("Shape is hit [" + hitI+ "]= " + paths[hitI]);
			     
			    // get the first node in the path		    
			    Node shape = paths[hitI].getObject();
			    shapes[hitI] = (Shape3D) shape;

			}
		    }
		    else
		    {
			System.out.println("No hits!");
		    }

		    // Draw line between shapes
/*		    Color3f col = new Color3f(1.0f, 0.0f, 0.0f);
		    LineArray myline = new LineArray(size+1, LineArray.COORDINATES|LineArray.COLOR_3);
		    for ( int i=0; i<size; i++ )
		    {
			myline.setCoordinate(i, parray[i]);
			myline.setColor(i, col);
		    }
		    myline.setCoordinate(size, parray[0]);
		    myline.setColor(size, col);
		    targetTG.addChild(new Shape3D(myline));*/
		    

		    break;
	    }

	}
}
		 
