import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.picking.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.geometry.Sphere;
import javax.swing.JOptionPane;

public class PickDragBehavior extends Behavior {
   int x, y;
   Canvas3D canvas3D;
   BranchGroup branchGroup;
   Material highlight;
   Shape3D selectedShape = null;
   WakeupCriterion mouseEvent;
   PickRay pickRay = new PickRay();
   PickCanvas pickCanvas;
   PickResult pickResult;

   PickDragBehavior(Canvas3D canvas3D, BranchGroup branchGroup, Bounds bounds) {
//      super(canvas3D, branchGroup, bounds);

      this.canvas3D = canvas3D;
      this.branchGroup = branchGroup;

      pickCanvas = new PickCanvas(canvas3D, branchGroup);
      pickCanvas.setTolerance(5.0f);
      pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO);

      Color3f black  = new Color3f(0.0f, 0.0f, 0.0f);
      Color3f yellow = new Color3f(1.0f, 1.0f, 0.5f);

      highlight = new Material(black, yellow, black, black, 128f);
   }

   public void initialize() {
      mouseEvent = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
      wakeupOn(mouseEvent);
   }

   public void processStimulus(Enumeration criteria) {
      WakeupCriterion wakeup;
      AWTEvent[] event;
      int id;

    while (criteria.hasMoreElements()) {
      wakeup = (WakeupCriterion) criteria.nextElement();
      if (wakeup instanceof WakeupOnAWTEvent) {
              event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
              for (int i=0; i<event.length; i++) {
                id = event[i].getID();
                if (id == MouseEvent.MOUSE_PRESSED) {
                  x = ((MouseEvent)event[i]).getX();
                  y = ((MouseEvent)event[i]).getY();
                  pickCanvas.setShapeLocation(x, y);

                  Point3d eyePos = pickCanvas.getStartPosition();
                  pickResult = pickCanvas.pickClosest();

                  if (pickResult != null) {
                            // Get node info
                          Node curNode = pickResult.getObject();
                          Geometry curGeom = ((Shape3D)curNode).getGeometry();
                            GeometryArray curGeomArray = (GeometryArray)curGeom;
                Shape3D shape = new Shape3D();
                shape = (Shape3D)curNode;
                            // Get closest intersection results
                            PickIntersection pi = pickResult.getClosestIntersection(eyePos);

                          // Position sphere at intersection point
                            Vector3d v = new Vector3d();
                            Point3d intPt = pi.getPointCoordinatesVW();
                v.set(intPt);
                            //spht3.setTranslation(v);
                            //sphTrans[0].setTransform(spht3);
/*
                Transform3D spht3 = new Transform3D();
                            spht3.setTranslation(v);
                TransformGroup sphTrans = new TransformGroup();
                            sphTrans.setTransform(spht3);
                sphTrans.addChild(new Sphere(0.1f));
                BranchGroup newBranchGroup = new BranchGroup();
                newBranchGroup.addChild(sphTrans);
                branchGroup.addChild(newBranchGroup);
*/
                          // Position sphere at closest vertex
                          Point3d closestVert = pi.getClosestVertexCoordinatesVW();
                            v.set(closestVert);
                            //spht3.setTranslation(v);
                            //sphTrans[1].setTransform(spht3);

                          Point3d []ptw = pi.getPrimitiveCoordinatesVW();
                          Point3d []pt = pi.getPrimitiveCoordinates();
                            int []coordidx = pi.getPrimitiveCoordinateIndices();
                            Point3d ptcoord = new Point3d();
                            for (int k=0; k<pt.length; k++) {
                              v.set(ptw[k]);
                            //spht3.setTranslation(v);
                            //sphTrans[k+2].setTransform(spht3);
                            }

                if (selectedShape != null) {
                   selectedShape.getAppearance().setMaterial(shape.getAppearance().getMaterial());
                }
                shape.getAppearance().setMaterial(highlight);
                selectedShape = shape;

                        System.out.println ("=============");
                            System.out.println ("Coordinates of intersection pt:"+intPt);
                        System.out.println ("Coordinates of vertices: ");
                            for (int k=0; k<pt.length; k++) {
                          System.out.println (k + ":" + ptw[k].x + " " + ptw[k].y + " " + ptw[k].z);
                        }
                        System.out.println ("Closest vertex: "+closestVert);
              } // if (pickResult != null)
                } // if (id == MouseEvent.MOUSE_PRESSED)
          } // for (int i=0; i<event.length; i++)
      } // if (wakeup instanceof WakeupOnAWTEvent)
    } // while (criteria.hasMoreElements())
    wakeupOn(mouseEvent);

//*******************
// NOSTRO CODICE
//*******************
/*
      while (criteria.hasMoreElements()) {
         wakeup = (WakeupCriterion)criteria.nextElement();
         if (wakeup instanceof WakeupOnAWTEvent) {
            event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
            for (int i=0; i<event.length; i++) {
               id = event[i].getID();
               if (id == MouseEvent.MOUSE_CLICKED) {
                  x = ((MouseEvent)event[i]).getX();
                  y = ((MouseEvent)event[i]).getY();

                  SceneGraphPath sgp = pickScene.pickClosest(x, y, PickObject.USE_GEOMETRY);
                  Shape3D shape = new Shape3D();
                  shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
                  shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
                  shape = (Shape3D)pickScene.pickNode(sgp, PickObject.SHAPE3D);

                  if (sgp == null) {
                    wakeupOn(mouseEvent);
                    break;
                  }

/*
                  Point3d eyePos = new Point3d();
                  canvas3D.getCenterEyeInImagePlate(eyePos);

                  Point3d mousePos = new Point3d();
                  canvas3D.getPixelLocationInImagePlate(x, y, mousePos);

                  // transform the current ImagePlate coordinates to Virtual World coordinates
                  Transform3D transform3D = new Transform3D();
                  canvas3D.getImagePlateToVworld(transform3D);
                  transform3D.transform(eyePos);
                  transform3D.transform(mousePos);

                  // prospective
                  Vector3d mouseVec = new Vector3d();
                  mouseVec.sub(mousePos, eyePos);
                  mouseVec.normalize();

                  // pick a ray in depth from mousePos in direction of mouseVec
                  pickRay.set(mousePos, mouseVec);


                  pickRay = (PickRay)pickScene.generatePickRay(x, y);
                  double distance[] = new double[1];

                  if (shape.intersect(sgp, pickRay, distance)) {
                    if (selectedShape != null) {
                      selectedShape.getAppearance().setMaterial(shape.getAppearance().getMaterial());
                    }
                    shape.getAppearance().setMaterial(highlight);
                    selectedShape = shape;
                    Point3d mousePos = new Point3d();
                    Vector3d mouseVec = new Vector3d();
                    pickRay.get(mousePos,mouseVec);
                    mouseVec.scale(distance[0]);
                    mousePos.add(mouseVec);
                    //JOptionPane.showMessageDialog(null,"Face Selected: "+shape.getUserData()+"\nPicked Point: "+mousePos.toString());
                  }
               } // end if (id == MouseEvent.MOUSE_CLICKED)
            } // end for
         } // end if (wakeup instanceof WakeupOnAWTEvent)
      } // end while

      wakeupOn(mouseEvent);
*/
   } // end processStimulus

   public void updateScene(int x, int y) {
   }

}

