/*
 * $Id: $
 * c. 2002 publity AG
 */

import java.awt.BorderLayout;

import javax.media.j3d.TriangleStripArray;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.Shape3D;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Appearance;
import javax.media.j3d.PolygonAttributes;
import javax.swing.JFrame;
import javax.vecmath.Vector3f;
import javax.vecmath.Point3d;

import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;

/**
 *
 * @author  fherinean
 * @version $Revision: $
 */
public class SharedGeometryBugTest extends JFrame implements Runnable
{
    boolean shareGeometry = true;
    boolean sameBG = false;

    float[] coords = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.4f, 0.0f
    };

    float[] normals = {
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f
    };

    float[] colors = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    };

    int[] strips = {3};

    Appearance app = new Appearance();
    BranchGroup bg = null;
    SimpleUniverse universe;

    public SharedGeometryBugTest()
    {
        super("Shared Geometry Bug Test");
        app.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_FILL,
            PolygonAttributes.CULL_NONE, 0.0f));
        Canvas3D c3d = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
        universe = new SimpleUniverse(c3d);
        universe.getViewingPlatform().setNominalViewingTransform();
        OrbitBehavior orbit = new OrbitBehavior(c3d, OrbitBehavior.REVERSE_ALL);
        orbit.setSchedulingBounds(new BoundingSphere(new Point3d(), 10));
        universe.getViewingPlatform().setViewPlatformBehavior(orbit);
        universe.addBranchGraph(bg = createBranchBroup());
        getContentPane().add(c3d, BorderLayout.CENTER);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500,500);
        setVisible(true);
        new Thread(this).start();
    }

    public void run()
    {
        while (true)
        {
            universe.getLocale().removeBranchGraph(bg);
            System.gc();
            universe.addBranchGraph(sameBG ? bg : (bg = createBranchBroup()));
            try
            {
                Thread.currentThread().sleep(200);
            }
            catch (InterruptedException e)
            {
            }
        }
    }

    private BranchGroup createBranchBroup()
    {
        BranchGroup bg = new BranchGroup();
        TriangleStripArray g = createGeometry();
        int count = 100;
        for (int i = 0; i < count; i++)
        {
            Transform3D t3d = new Transform3D();
            t3d.set(1.0f, new Vector3f(0.0f, 0.0f, 0.5f - i / (float)count));
            TransformGroup tg = new TransformGroup(t3d);
            tg.addChild(new Shape3D(shareGeometry ? g : createGeometry(), app));
            bg.addChild(tg);
        }
        bg.setCapability(BranchGroup.ALLOW_DETACH);
        return bg;
    }

    TriangleStripArray createGeometry()
    {
        TriangleStripArray tsa = new TriangleStripArray(3,
            TriangleStripArray.COORDINATES | TriangleStripArray.NORMALS | TriangleStripArray.COLOR_3, strips);
        tsa.setCoordinates(0, coords);
        tsa.setNormals(0, normals);
        tsa.setColors(0, colors);
        return tsa;
    }

    public static void main(String[] args)
    {
        new SharedGeometryBugTest();
    }
}
