import com.sun.j3d.utils.behaviors.mouse.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
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.*; 
import java.util.ArrayList;



public class TestApp2 extends Applet
{
    private int m_numOfSpheres = 5000;

    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);

	Appearance appearance = createAppearance();

        Sphere utilSphere = new Sphere(0.4f, Sphere.GENERATE_NORMALS ,15);
	Shape3D s3d = utilSphere.getShape();
	Geometry geom = s3d.getGeometry();
	
	
        Transform3D t3d = new Transform3D();
        Vector3f vec3f = new Vector3f(0.25f,0.0f,0.0f);

        for ( int i = 0; i <m_numOfSpheres; i++)
        {
            vec3f.set(i*0.25f,0f,0f);
            t3d.setTranslation(vec3f);
            TransformGroup trans = new TransformGroup(t3d);
            trans.addChild(new Shape3D(geom, appearance));

            transGrp.addChild(trans);
        }

        bg.addChild(transGrp);

        return bg;
    }

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

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

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


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

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

    }
}
