import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
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 java.util.Enumeration;

  
public class Teste extends Applet{  

    final static int XMax = 515;
    final static int YMax = 555;
  
    final static float ARESTA_ICOSAEDRO = 2.8f;
        
//    final static Point3f POSICAO_ICOSAEDRO = new Point3f(0.0f, 0.0f, 0.0f);        
    final static Point3f POSICAO_ICOSAEDRO = new Point3f(-6.0f, -7.0f, 0.0f);    
        
    public Teste() {
    	
        setBackground(new Color(200, 200, 200));
        setLayout(null);        
                
        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();

        Canvas3D cNormal = new Canvas3D(config);
        cNormal.setSize(XMax, YMax);                
        cNormal.setLocation(5, 5);        
                       
	      SimpleUniverse u = new SimpleUniverse(cNormal);
        
	      add(cNormal);
	      BranchGroup scene = createSceneGraph();
	      
        u.getViewingPlatform().setNominalViewingTransform();
	      u.addBranchGraph(scene);      
    }
   
   
    // Envoltorio Esferico 
    TransformGroup criaEnvoltorioEsfera(float raio, Point3f posicao, float transp){
        
        Sphere envoltorioEsfera = new Sphere(raio);
	      Appearance appEsfera = new Appearance();
	      ColoringAttributes caEsfera = new ColoringAttributes();
	      caEsfera.setColor(1.0f, 1.0f, 1.0f);	      
	      appEsfera.setColoringAttributes(caEsfera);	  	      
	      appEsfera.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.FASTEST, transp));	      	      
	      envoltorioEsfera.setAppearance(appEsfera);
	      
	      Transform3D t = new Transform3D();
	      t.set(1.0, new Vector3d(posicao.x, posicao.y, posicao.z));
	      TransformGroup esferaTrans = new TransformGroup(t);
	      
	      esferaTrans.addChild(envoltorioEsfera);
	      
        return esferaTrans;    
    }


    public BranchGroup createSceneGraph() {
    
	      BranchGroup objRoot = new BranchGroup();

        TransformGroup objScale = new TransformGroup();
        Transform3D t3d = new Transform3D();
        t3d.setScale(0.4);
        objScale.setTransform(t3d);
        objRoot.addChild(objScale);

    	  BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);

        // Luz Ambiente
	      AmbientLight aLgt = new AmbientLight(new Color3f(0.7f, 0.7f, 0.7f));
	      aLgt.setInfluencingBounds(bounds);	      
        objScale.addChild(aLgt);

  	    // Background
	      Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
	      Background bg = new Background(bgColor);
	      bg.setApplicationBounds(bounds);
	      objScale.addChild(bg);
	      
        // objTrans1  
	      TransformGroup objTrans1 = new TransformGroup();
	      objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
	      objScale.addChild(objTrans1);
	      
        // objTrans2  
  	    TransformGroup objTrans2 = new TransformGroup();
	      objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
	      objTrans1.addChild(objTrans2);
	      
        // objTrans3  
	      Transform3D t = new Transform3D();
	      t.set(0.2f ,new Vector3d(0.0, 1.5, 0.0));
	      TransformGroup objTrans3 = new TransformGroup(t);
	      objTrans2.addChild(objTrans3);
    
        // objTransObj1
  	    TransformGroup objTransObj1 = new TransformGroup();
	      objTransObj1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
	      objScale.addChild(objTransObj1);
	              
        // objTrans11  
	      Transform3D t11 = new Transform3D();
	      t11.set(0.2f, new Vector3d(0.0, 0.0, 0.0));
	      TransformGroup objTrans11 = new TransformGroup(t11);	      
	      objTrans11.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);	      
	      objTransObj1.addChild(objTrans11);
	      
        // ICOSAEDRO
        Shape3D shapeIco = new Icosahedron(POSICAO_ICOSAEDRO);  
        shapeIco.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ);                
        shapeIco.setCapability(Shape3D.ALLOW_GEOMETRY_READ);  
	      objTrans11.addChild(shapeIco);      
        // Obtem a Geometria do Octaedro
        Geometry geoIco = shapeIco.getGeometry();
        GeometryArray gaIco = (GeometryArray) geoIco;
        geoIco.setCapability(GeometryArray.ALLOW_NORMAL_READ);                     

        // 3 Little Spheres located on vertices 3,4 and 5 (see below)
        objTrans11.addChild(criaEnvoltorioEsfera(ARESTA_ICOSAEDRO * 0.15f ,new Point3f(-7.4f,-7.8652f, 0.0f), 0.0f));                 
        objTrans11.addChild(criaEnvoltorioEsfera(ARESTA_ICOSAEDRO * 0.15f ,new Point3f(-6.0f,-8.4f,0.8652f), 0.0f));                 
        objTrans11.addChild(criaEnvoltorioEsfera(ARESTA_ICOSAEDRO * 0.15f ,new Point3f(-6.8652f, -7.0f, 1.4f), 0.0f));         

        int NPoints = gaIco.getVertexCount(); //32
        



        float[] floatPontos = new float[NPoints*3]; 
        // Get the Coordenates
        gaIco.getCoordinates(0, floatPontos);                        
        System.out.println();        
        System.out.println("########## Every 32 Coordenates ##########");
        for (int j=0; j<NPoints; j++){
            System.out.println("Vertices" + j + "=> "+ new Point3f(floatPontos[j*3], floatPontos[j*3 + 1], floatPontos[j*3 + 2]));        	          	      
        }                                    
        System.out.println();




        // Normal manual calculeted
        Point3f p0 = new Point3f(-7.4f, -7.8652f, 0.0f); // vertice 3
        Point3f p1 = new Point3f(-6.0f, -8.4f, 0.8652f); // vertice 4
        Point3f p2 = new Point3f(-6.8652f, -7.0f, 1.4f); // vertice 5
      
        Vector3f vet = new Vector3f(0.0f,0.0f,0.0f);            
        Vector3f vetN1 = new Vector3f(p2.x - p0.x, p2.y - p0.y, p2.z - p0.z);
        Vector3f vetN2 = new Vector3f(p1.x - p0.x, p1.y - p0.y, p1.z - p0.z);    
      
        vet.cross(vetN1,vetN2);             
        Point3f Normal= new Point3f(vet);
        
        System.out.println("########## Normal Vector (manual calculeted) of the face with little spheres ##########");      
        System.out.println("vNormal => " + Normal); 
        System.out.println();


          
    
        float[] floatNormals = new float[NPoints*3];
        System.out.println("########## Every Normal Vectors (calculeted with GeometryArray.getNormals) ##########");                 
        // Get the Normals with getNormal
        gaIco.getNormals(0, floatNormals);                                                                          
        for (int j=0; j<NPoints; j++){
            System.out.println("vecNormal" + j + "=> "+ new Point3f(floatNormals[j*3], floatNormals[j*3 + 1], floatNormals[j*3 + 2]));        	          	                     
        }                            
  
   
   
   
        objRoot.compile();

	      return objRoot;
    }


    public static void main(String[] args) {    	    	    	    	      	
	      new MainFrame(new Teste(), XMax, YMax);
	      
    }    
    
}