package practice;

import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.image.TextureLoader;
import java.applet.Applet;
import java.awt.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.vp.*;
import com.sun.j3d.utils.geometry.*;



public class SphereAsImage extends Applet
{
   // private int m_numOfSpheres = 100;
        //private float m_rad = 0.5f;
        //private int m_div = 15;

        //float centers[] = {
        //                                  1.0f,1.0f,1.0f,
        //                                      1.0f,1.0f,2.0f,
        //                                      0.5f,1.0f,2.0f,
        //                                      -1.0f,1.0f,2.0f,
        //                                };
        //Area m_area = new Area();
    public BranchGroup createSceneGraph()
    {
        BranchGroup bg = new BranchGroup();

        TransformGroup transGrp = new TransformGroup();
        transGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        transGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

                Transform3D t3dScale = new Transform3D();
                t3dScale.setScale(0.1);

                transGrp.setTransform(t3dScale);

            Appearance appearance = createAppearance();

       float[] verts = {
                  // Front Face
                  1.0f, -1.0f,  1.0f,     1.0f,  1.0f,  1.0f,
                 -1.0f,  1.0f,  1.0f,    -1.0f, -1.0f,  1.0f,
                  // Back Face
                  0.5f, -1.0f,  -1.0f,     0.5f,  1.0f,  -1.0f,
                 -1.5f,  1.0f,  -1.0f,    -1.5f, -1.0f,  -1.0f,
         };

       float[] textCoords = {
              // Front Face
                  1.0f,  0.0f,            1.0f,  1.0f,
                  0.0f,  1.0f,            0.0f,  0.0f,
              // Back Face
                  1.0f,  0.0f,            1.0f,  1.0f,
                  0.0f,  1.0f,            0.0f,  0.0f,
          };

       //System.out.println("quadCoordinates length: " + quadCoordinates.length);

       //String filename = "C:/inStruct/nitin/Java3DPractice/data/redsphere256_256.gif";
           String filename = System.getProperty("user.dir")
                           + System.getProperty("file.separator")
                           + "redsphere256_256.gif";
       TextureLoader loader = new TextureLoader(filename, null);
       ImageComponent2D image = loader.getImage();
           System.out.println("Image Width:"+image.getWidth());

       if(image == null)
       {
             System.out.println("load failed for texture: "+filename);
       }

      // can't use parameterless constuctor
      Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA,
                                        image.getWidth(), image.getHeight());
      texture.setImage(0, image);

      appearance.setTexture(texture);
          System.out.println("after setTexture in converter:");

      appearance.setTransparencyAttributes(
         new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.0f));


       QuadArray quad = new QuadArray(verts.length, GeometryArray.COORDINATES
                                      | GeometryArray.TEXTURE_COORDINATE_2);

       quad.setCoordinates(0, verts);
       quad.setTextureCoordinates(0, textCoords);


        PolygonAttributes pa = new PolygonAttributes();
        pa.setCullFace(pa.CULL_NONE);
        appearance.setPolygonAttributes(pa);
        pa.setPolygonOffset(2.0f);

        Shape3D planeObj = new Shape3D(quad, appearance);

        planeObj.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
        planeObj.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_READ);
        planeObj.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
        planeObj.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
        quad.setCapability(GeometryArray.ALLOW_FORMAT_READ);
        quad.setCapability(GeometryArray.ALLOW_COUNT_READ);
        quad.setCapability(GeometryArray.ALLOW_COORDINATE_READ);

                transGrp.addChild(planeObj);

                //Billboard billboardBehavior = new Billboard(transGrp);
        //billboardBehavior.setSchedulingBounds(new BoundingSphere());
                //billboardBehavior.setAlignmentMode(Billboard.ROTATE_ABOUT_POINT);
                //billboardBehavior.setRotationPoint(0f,0f,0f);



        bg.addChild(transGrp);
                //bg.addChild(billboardBehavior);


        return bg;
    }

    public Appearance createAppearance()
    {
        Appearance appear = new Appearance();
        Material material = new Material();
        appear.setMaterial(material);
        return appear;
    }



    public SphereAsImage()
    {
                setLayout(new BorderLayout());
        GraphicsConfiguration config =
           SimpleUniverse.getPreferredConfiguration();

        Canvas3D c = new Canvas3D(config);
                add("Center", c);

        BranchGroup scene = createSceneGraph();

        attachLightSources(scene);
        setBackGround(scene);


        SimpleUniverse u = new SimpleUniverse(c);

        // add mouse behaviors to the ViewingPlatform
        ViewingPlatform viewingPlatform = u.getViewingPlatform();

        // This will move the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        viewingPlatform.setNominalViewingTransform();

        // add orbit behavior to the ViewingPlatform
        OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
        orbit.setSchedulingBounds(bounds);
        viewingPlatform.setViewPlatformBehavior(orbit);

        scene.compile();

        u.addBranchGraph(scene);
   }

    private void setBackGround(BranchGroup theScene)
    {
        Background backGround = new Background();
        backGround.setColor(1.0f, 1.0f, 1.0f);
        backGround.setApplicationBounds(new BoundingSphere());
        theScene.addChild(backGround);
    }

    private void attachLightSources(BranchGroup theScene)
    {
        DirectionalLight lightD1 = new DirectionalLight();
        lightD1.setInfluencingBounds(new BoundingSphere());
        Vector3f direction1 = new Vector3f(-1.0f, -1.0f, -0.5f);
        direction1.normalize();
        lightD1.setDirection(direction1);
        lightD1.setColor(new Color3f(0.0f, 0.0f, 1.0f));
        theScene.addChild(lightD1);

        DirectionalLight lightD2 = new DirectionalLight();
        lightD2.setInfluencingBounds(new BoundingSphere());
        Vector3f direction2 = new Vector3f(1.0f, -1.0f, -0.5f);
        direction2.normalize();
        lightD2.setDirection(direction2);
        lightD2.setColor(new Color3f(1.0f, 0.0f, 0.0f));
        theScene.addChild(lightD2);
    }

    public static void main(String argv[])
    {
        long initTime = System.currentTimeMillis();

                new MainFrame(new SphereAsImage(), 556, 556);

                System.out.println("Total Time including rendering:"+(System.currentTimeMillis() - initTime));

    }
}
