package java3d;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Label;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.behaviors.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.event.*;

import java.util.ArrayList;



public class TestApp extends Applet
{
    private int m_numOfSpheres = 1000;

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

    public BranchGroup createSceneGraph()
    {
                BranchGroup bg = new BranchGroup();

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

        Sphere utilSphere = new Sphere(0.4f, Sphere.GENERATE_NORMALS ,15,createAppearance());

                SharedGroup sg = new SharedGroup();
        sg.addChild(utilSphere);

        Transform3D t3d = new Transform3D();
        Vector3f vec3f = new Vector3f(0.25f,0.0f,0.0f);

        for ( int i = 0; i <m_numOfSpheres; i++)
        {
            Link link = new Link(sg);

            vec3f.set(i*0.25f,0f,0f);
            t3d.setTranslation(vec3f);
            TransformGroup trans = new TransformGroup(t3d);
            trans.addChild(link);

            transGrp.addChild(trans);
        }

        bg.addChild(transGrp);

        MouseRotate myMouseRotate = new MouseRotate();
        myMouseRotate.setTransformGroup(transGrp);
        myMouseRotate.setSchedulingBounds(new BoundingSphere());
        bg.addChild(myMouseRotate);


        return bg;
    }

    public TestApp()
    {
        setLayout(new BorderLayout());
        Canvas3D c = new Canvas3D(null);
        add("Center", c);

        long initTime = System.currentTimeMillis();
                BranchGroup scene = createSceneGraph();
                System.out.println("Time taken to create BranchGroup:"+(System.currentTimeMillis() - initTime));

        SimpleUniverse u = new SimpleUniverse(c);
        u.getViewingPlatform().setNominalViewingTransform();

        attachLightSources(scene);
        setBackGround(scene);

        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 TestApp(), 556, 556);

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

    }
}
