import java.applet.*;
import java.awt.*;
import java.awt.event.*;

import javax.media.j3d.*;
import javax.vecmath.*;

import com.sun.j3d.utils.applet.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.universe.*;

public class GraphicsDraw extends Applet {
    public BranchGroup createSceneGraph(SimpleUniverse su) {
      BranchGroup bgRoot = new BranchGroup();
      TransformGroup tgView = su.getViewingPlatform().getViewPlatformTransform();

      // arrays of coordinates
      double[] vertex_set1 = new double[]{  -1,  0.5, 0,
                                             1,  0.5, 0,
                                             0,    1, 0};

      double[] vertex_set2 = new double[]{ 0.1,    0, 0,
                                             1,    0, 0,
                                           0.5,  0.5, 0};

      double[] vertex_set3 = new double[]{  -1, -0.5, 0,
                                             1, -0.5, 0,
                                             0,   0, 0};
      // array of indexes
      int[] index_set = new int[]{0, 1, 2};

      // geometry "blue" array by ref
      IndexedTriangleStripArray s1_geometry = new IndexedTriangleStripArray( vertex_set1.length/3,
                                                  IndexedTriangleStripArray.BY_REFERENCE| IndexedTriangleStripArray.COORDINATES,
                                                  index_set.length,
                                                  new int[]{index_set.length} );
      s1_geometry.setCoordRefDouble( vertex_set1 );
      s1_geometry.setCoordinateIndices(0, index_set );


      // geometry "green" array by ref
      IndexedTriangleStripArray s2_geometry = new IndexedTriangleStripArray( vertex_set2.length/3,
                                                  IndexedTriangleStripArray.BY_REFERENCE| IndexedTriangleStripArray.COORDINATES,
                                                  index_set.length,
                                                  new int[]{index_set.length} );
      s2_geometry.setCoordRefDouble( vertex_set2 );
      s2_geometry.setCoordinateIndices(0, index_set );

      // geometry "red" array by copying
      IndexedTriangleStripArray s3_geometry = new IndexedTriangleStripArray( vertex_set3.length/3,
                                                  IndexedTriangleStripArray.COORDINATES,
                                                  index_set.length,
                                                  new int[]{index_set.length} );
      s3_geometry.setCoordinates(0, vertex_set3 );
      s3_geometry.setCoordinateIndices(0, index_set );

      PolygonAttributes s_attr  = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0);

      // create blue Triangle
      Shape3D s1 = new Shape3D();
      s1.setGeometry(s1_geometry);
      Appearance a1 = new Appearance();
      a1.setPolygonAttributes(s_attr);
      a1.setColoringAttributes( new ColoringAttributes(0, 0, 1, ColoringAttributes.FASTEST) );
      s1.setAppearance(a1);

      // create green Triangle
      Shape3D s2 = new Shape3D();
      s2.setGeometry(s2_geometry);
      Appearance a2 = new Appearance();
      a2.setPolygonAttributes(s_attr);
      a2.setColoringAttributes( new ColoringAttributes(0, 1, 0, ColoringAttributes.FASTEST) );
      s2.setAppearance(a2);

      // create red Triangle
      Shape3D s3 = new Shape3D();
      s3.setGeometry(s3_geometry);
      Appearance a3 = new Appearance();
      a3.setPolygonAttributes(s_attr);
      a3.setColoringAttributes( new ColoringAttributes(1, 0, 0, ColoringAttributes.FASTEST) );
      s3.setAppearance(a3);
      // add triangles and behaviours to root group
      bgRoot.addChild(s1);
      bgRoot.addChild(s2);
      bgRoot.addChild(s3);
      bgRoot.compile();

      return bgRoot;
    }

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

      Canvas3D canvas = new Canvas3D(config);
      DrawMouseAdapter adapter = new DrawMouseAdapter(canvas);
      canvas.addMouseListener(adapter);
      canvas.addMouseMotionListener(adapter);

      add(canvas, BorderLayout.CENTER);

      SimpleUniverse u = new SimpleUniverse(canvas);

      u.getViewingPlatform().setNominalViewingTransform();

      u.addBranchGraph(createSceneGraph(u));
    }

    public static void main(String[] args) {
      Frame frame = new MainFrame(new GraphicsDraw(), 500, 500);
    }

    // Listener for mouse events
    private class DrawMouseAdapter implements MouseListener, MouseMotionListener{
      Point start_point = new Point();
      Canvas3D canvas;

      public DrawMouseAdapter(Canvas3D canvas){
        super();
        this.canvas = canvas;
      }

      // start draw my figure on canvas graphics
      public void mousePressed(MouseEvent e){
        start_point = e.getPoint();
        // stop renderer
        canvas.stopRenderer();
      }

      // stop draw my figure on canvas graphics
      public void mouseReleased(MouseEvent e){
        // start renderer
        canvas.startRenderer();
      }

      public void mouseDragged(MouseEvent e){
        Point end_point = e.getPoint();
        // draw figure
        Graphics g = canvas.getGraphics();
        g.setColor( Color.WHITE);
        if ( e.isControlDown() )
          g.drawOval(start_point.x, start_point.y, end_point.x - start_point.x, end_point.y - start_point.y);
        else
          g.drawRect(start_point.x, start_point.y, end_point.x - start_point.x, end_point.y - start_point.y);
        //swap canvas buffers
        canvas.swap();
      }

      // Ignore this events
      public void mouseMoved(MouseEvent e){}
      public void mouseClicked(MouseEvent e){}
      public void mouseEntered(MouseEvent e){}
      public void mouseExited(MouseEvent e){}
    }
}
