import java.applet.Applet;
import java.awt.*;
import com.sun.j3d.utils.picking.PickTool;
import com.sun.j3d.utils.picking.behaviors.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.picking.*;
import java.util.Enumeration;
import javax.media.j3d.GeometryStripArray.*;
import java.awt.event.*;
import com.sun.j3d.utils.behaviors.picking.PickObject;
import com.sun.j3d.utils.picking.behaviors.PickMouseBehavior;
import java.util.*;
import java.awt.*;
import java.awt.Event;
import java.awt.AWTEvent;
import java.awt.event.MouseEvent;
import javax.vecmath.*;

public class SimplePicking extends Applet 
{
public static TransformGroup objTran1 = new TransformGroup();
public static TransformGroup objTran = new TransformGroup();
public static int i=0;
public static Node ash;

public BranchGroup createSceneGraph(Canvas3D canvas) 
{
      BranchGroup objRoot = new BranchGroup();
      objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      
      BoundingSphere bounds;
      bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0),1.0);

      BoundingSphere bounds1;
      bounds1= new BoundingSphere(new Point3d(0.0,0.0,0.0),30.0);

      
      Vector3f ldir = new Vector3f(1.0F,1.0F,-1.0F);
      Color3f lcouldl = new Color3f(1.0F,1.0F,1.0F);
      DirectionalLight dl = new DirectionalLight(lcouldl,ldir);
      dl.setInfluencingBounds(bounds);
      objRoot.addChild(dl);
      Color3f lcoulal = new Color3f(0.3F,0.3F,0.1F);
      AmbientLight al = new AmbientLight(lcoulal);
      al.setInfluencingBounds(bounds);
      objRoot.addChild(al);
      
      objTran1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      objTran1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      objTran1.setCapability(Group.ALLOW_CHILDREN_EXTEND);
      objTran1.setCapability(Group.ALLOW_CHILDREN_READ);
      objTran1.setCapability(Group.ALLOW_CHILDREN_WRITE);
      objRoot.addChild(objTran1);

      objTran.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      objTran.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      objTran.setCapability(Group.ALLOW_CHILDREN_EXTEND);
      objTran.setCapability(Group.ALLOW_CHILDREN_READ);
      objTran.setCapability(Group.ALLOW_CHILDREN_WRITE);
      objRoot.addChild(objTran);
      
      BranchGroup bg1 = new BranchGroup();
      bg1.setCapability(BranchGroup.ALLOW_DETACH);
      bg1.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      bg1.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      bg1.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      bg1.setCapability(BranchGroup.ENABLE_PICK_REPORTING);
      TransformGroup objTrans1 = new TransformGroup();
      Transform3D t1 = new Transform3D();
      t1.setTranslation(new Vector3d(-0.7,0.0,0.0)) ;
      objTrans1.setTransform(t1);
      objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      objTrans1.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
      Appearance a1 = new Appearance();
      Material m1 = new Material();
      a1.setMaterial(m1);
      Sphere s = new Sphere(0.18F,Sphere.GENERATE_NORMALS|Sphere.ENABLE_GEOMETRY_PICKING,70,a1);
      s.setCapability(Geometry.ALLOW_INTERSECT);
      objTran.addChild(bg1);
      Group gp1=new Group();
      bg1.addChild(gp1);
      gp1.addChild(objTrans1);
      objTrans1.addChild(s);
           
      BranchGroup bg2 = new BranchGroup();
      bg2.setCapability(BranchGroup.ALLOW_DETACH);
      bg2.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      bg2.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      bg2.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      bg2.setCapability(BranchGroup.ENABLE_PICK_REPORTING);
      TransformGroup objTrans2 = new TransformGroup();
      Transform3D t2 = new Transform3D();
      t2.setTranslation(new Vector3d(-0.25,0.0,0.0)) ;
      objTrans2.setTransform(t2);
      objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      objTrans2.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
      Appearance a2 = new Appearance();
      Material m2 = new Material();
      m2.setDiffuseColor(0.5f,1.0f,0.2f);
      m2.setAmbientColor(0.5f,0.6f,0.8f);
      a2.setMaterial(m2);
      Cone cn = new Cone(0.14F,0.28F,Cone.GENERATE_NORMALS|Cone.ENABLE_GEOMETRY_PICKING,50,50,a2);
      cn.setCapability(Geometry.ALLOW_INTERSECT);
      objTran.addChild(bg2);
      Group gp2=new Group();
      bg2.addChild(gp2);
      gp2.addChild(objTrans2);
      objTrans2.addChild(cn);
 
      BranchGroup bg3 = new BranchGroup();
      bg3.setCapability(BranchGroup.ALLOW_DETACH);
      bg3.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      bg3.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      bg3.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      bg3.setCapability(BranchGroup.ENABLE_PICK_REPORTING);
      TransformGroup objTrans3 = new TransformGroup();
      Transform3D t3 = new Transform3D();
      t3.setTranslation(new Vector3d(0.25,0.0,0.0)) ;
      objTrans3.setTransform(t3);
      objTrans3.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      objTrans3.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      objTrans3.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
      Appearance a3 = new Appearance();
      Material m3= new Material();
      m3.setDiffuseColor(0.1f,0.1f,0.9f);
      m3.setSpecularColor(1.0f,0.0f,0.0f);
      m3.setAmbientColor(0.9f,0.9f,0.9f);
      m3.setShininess(25.0f);
      a3.setMaterial(m3);
      Cylinder c = new Cylinder(0.14F,0.28F,Cylinder.GENERATE_NORMALS|Cylinder.ENABLE_GEOMETRY_PICKING,50,50,a3);
      c.setCapability(Geometry.ALLOW_INTERSECT);
      objTran.addChild(bg3);
      Group gp3=new Group();
      bg3.addChild(gp3);
      gp3.addChild(objTrans3);
      objTrans3.addChild(c); 
    
      BranchGroup bg4 = new BranchGroup();
      bg4.setCapability(BranchGroup.ALLOW_DETACH);
      bg4.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      bg4.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      bg4.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      bg4.setCapability(BranchGroup.ENABLE_PICK_REPORTING);
      TransformGroup objTrans4 = new TransformGroup();
      Transform3D t4 = new Transform3D();
      t4.setTranslation(new Vector3d(0.7,0.0,0.0)) ;
      objTrans4.setTransform(t4);
      objTrans4.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      objTrans4.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      objTrans4.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      objTrans4.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      objTrans4.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      objTrans4.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
      Appearance a4 = new Appearance();
      Material m4 = new Material();
      m4.setDiffuseColor(0.9f,0.8f,0.4f);
      m4.setAmbientColor(0.6f,0.0f,0.6f);
      a4.setMaterial(m4);
      Box b = new Box(0.05F,0.13F,0.22F,Box.GENERATE_NORMALS|Box.ENABLE_GEOMETRY_PICKING,a4);
      b.setCapability(Geometry.ALLOW_INTERSECT);
      objTran.addChild(bg4);
      bg4.addChild(objTrans4);
      objTrans4.addChild(b); 

    /*MouseRotate behavior = new MouseRotate(objTran1);
    MouseTranslate behavior1 = new MouseTranslate(objTran1);
    objTran1.addChild(behavior);
    objTran1.addChild(behavior1);
    behavior.setSchedulingBounds(bounds1);
    behavior1.setSchedulingBounds(bounds1);*/

    MouseRotate behavior2 = new MouseRotate(objTran);
    MouseTranslate behavior3 = new MouseTranslate(objTran);
    objTran.addChild(behavior2);
    objTran.addChild(behavior3);
    behavior2.setSchedulingBounds(bounds);
    behavior3.setSchedulingBounds(bounds);

    
    PickRotateBehavior behavior4 = new PickRotateBehavior(objRoot, canvas, bounds1);
    behavior4.setMode(PickTool.GEOMETRY);
    objTran1.addChild(behavior4);
    PickZoomBehavior behavior5 = new PickZoomBehavior(objRoot, canvas, bounds1);
    behavior5.setMode(PickTool.GEOMETRY);
    objTran1.addChild(behavior5);
    PickTranslateBehavior behavior6 = new PickTranslateBehavior(objRoot, canvas, bounds1);
    behavior6.setMode(PickTool.GEOMETRY);
    objTran1.addChild(behavior6);
    
    slbehavior b1=new slbehavior(objTran,canvas,objRoot);
    b1.setSchedulingBounds(bounds);
    objTran.addChild(b1); 
    
    objRoot.compile();
    return objRoot;
    }
  public SimplePicking() 
{
    setLayout(new BorderLayout());
    GraphicsConfiguration config;
    config = SimpleUniverse.getPreferredConfiguration();
    Canvas3D c = new Canvas3D(config);
    add("Center",c);
    SimpleUniverse u = new SimpleUniverse(c);
    BranchGroup scene = createSceneGraph(c);
    u.getViewingPlatform().setNominalViewingTransform();
    u.addBranchGraph(scene);
}

  public static void main(String[] args) 
{
    new MainFrame(new SimplePicking(),600,150);
}

class slbehavior extends Behavior
{
private TransformGroup targetTG;
private BranchGroup scene;
private Canvas3D canvas;
private Shape3D x;

slbehavior (TransformGroup targetTG,Canvas3D canvas, BranchGroup scene)
{
this.targetTG=targetTG;
this.scene=scene;
this.canvas=canvas;
this.x=x;
}

public void initialize()
{
this.wakeupOn(new WakeupOnAWTEvent(MouseEvent.MOUSE_CLICKED));
}

WakeupOnAWTEvent trigger = new WakeupOnAWTEvent(MouseEvent.MOUSE_CLICKED); 

public void processStimulus (Enumeration criteria)
{
Box b=null;
Cone c=null;
PickShape shape=null; 
PickObject obj = new PickObject(canvas,scene);

if ( obj != null ) 
{ 
AWTEvent myEvent[] = trigger.getAWTEvent(); 
int xpos = 0;
int ypos = 0; 
MouseEvent event1=null; 
try
{
event1 = (MouseEvent) myEvent[0]; 
}
catch (ArrayIndexOutOfBoundsException a){}
if ( event1 != null ) 
{
 xpos = event1.getX(); 
 ypos = event1.getY();
 
// For debugging purposes 

System.out.println(xpos + " " + ypos); 
}
SceneGraphPath closest = obj.pickClosest(xpos, ypos); 
 
if (closest != null ) 
{
 Primitive myShape=null;
 
// get the first node in the path

int nodeCount = closest.nodeCount();
Node node = closest.getNode(2); 
Node node1= closest.getNode(0);

 // Identify your object
 if (node instanceof Box && node1 instanceof BranchGroup) 
{
System.out.println("Picked a box!");
b=(Box) node;
BranchGroup bg = (BranchGroup)node1;
System.out.println("Number of Children of BranchGroup before being Detached from objTran:" + bg.numChildren());
ash=bg.getChild(0);
if(ash instanceof TransformGroup)
{
System.out.println("child is TG");
TransformGroup y=(TransformGroup)ash;
int a = y.numChildren();
System.out.println("Number of Children of TransformGroup :" + a);
}
System.out.println("Number of Children of objTran before Detachment:"+ "  " + objTran.numChildren());
Node z= objTran.getChild(1);
if (z instanceof Box)
{
System.out.println("2nd Child of objTran before Detachment is TransformGroup:" );
}
bg.detach();
System.out.println("Number of Children of objTran after Detachment:" + "  " +  objTran.numChildren());
objTran1.addChild(bg);
System.out.println("Number of Children of ObjTran1 after Attachment:" + "  " + objTran1.numChildren());
Node x= objTran1.getChild(0);
if(x instanceof BranchGroup)
{System.out.println("BranchGroup is child");
}
System.out.println("Number of Children of BranchGroup after being Attached to objTran1:" +"  " +  bg.numChildren());
Node y= bg.getChild(0);
if(y instanceof TransformGroup)
{
TransformGroup k=(TransformGroup)y;
System.out.println("TransformGroup is child");
System.out.println("Number of Children of TransformGroup after being Attached to objTran1:" +"  " +  k.numChildren());
Node w= k.getChild(0);
if(w instanceof Box)
{
System.out.println("Primitive is Box");
}
} 
 }


if ( node instanceof Cylinder && node1 instanceof BranchGroup)
 {
System.out.println("Picked a cylinder");
Cylinder cyl=(Cylinder) node;
BranchGroup bg = (BranchGroup)node1;
System.out.println("Number of Children of BranchGroup before being Detached from objTran:" + bg.numChildren());
ash=bg.getChild(0);
if(ash instanceof Cylinder)
System.out.println("Cylinder is child");
System.out.println("Number of Children of objTran before Detachment:"+ "  " + objTran.numChildren());
bg.detach();
System.out.println("Number of Children of objTran after Detachment:" + "  " +  objTran.numChildren());
objTran1.addChild(bg);
System.out.println("Number of Children of ObjTran1 after Attachment:" + "  " + objTran1.numChildren());
System.out.println("Number of Children of BranchGroup after being Attached to objTran1:" +"  " +  bg.numChildren());
 }



if ( node instanceof Cone && node1 instanceof BranchGroup) 
{
System.out.println("Picked a Cone!");
c = (Cone) node;
BranchGroup bg = (BranchGroup)node1;
System.out.println("Number of Children of BranchGroup before being Detached from objTran:" + bg.numChildren());
ash=bg.getChild(0);
if(ash instanceof Cone)
System.out.println("Cone is child");
System.out.println("Number of Children of objTran before Detachment:"+ "  " + objTran.numChildren());
bg.detach();
System.out.println("Number of Children of objTran after Detachment:" + "  " +  objTran.numChildren());
objTran1.addChild(bg);
System.out.println("Number of Children of ObjTran1 after Attachment:" + "  " + objTran1.numChildren());
System.out.println("Number of Children of BranchGroup after being Attached to objTran1:" +"  " +  bg.numChildren());
 } 


if ( node instanceof Sphere && node1 instanceof BranchGroup)
 {
System.out.println("Picked a Sphere");
Sphere s= (Sphere) node;
//System.out.println("I : "+ ++i);
BranchGroup bg = (BranchGroup)node1;
System.out.println("Number of Children of BranchGroup before being Detached from objTran:" + bg.numChildren());
ash=bg.getChild(0);
if(ash instanceof Sphere)
System.out.println("Sphere is child");
System.out.println("Number of Children of objTran before Detachment:"+ "  " + objTran.numChildren());
bg.detach();
System.out.println("Number of Children of objTran after Detachment:" + "  " +  objTran.numChildren());
objTran1.addChild(bg);
System.out.println("Number of Children of ObjTran1 after Attachment:" + "  " + objTran1.numChildren());
System.out.println("Number of Children of BranchGroup after being Attached to objTran1:" +"  " +  bg.numChildren());
 }

if (node instanceof Primitive)
{
}

}
}
this.wakeupOn(trigger); 
}
}
  }
