package j3dtest;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.geometry.Text2D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.PolygonAttributes;


public class Plot extends Applet
{
      private BranchGroup my_BG = new BranchGroup();

      public Plot()
      {

        // TransformGroup for MouseBehavior
        TransformGroup mouse = new TransformGroup();
        // set Capabilites for MouseTransform
        mouse.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        mouse.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        my_BG.addChild(mouse);

////////////////////////////////////////////////////////////////
//
//                    Axis
//
////////////////////////////////////////////////////////////////
        // x-Axis
        LineArray x_axis = new LineArray(2, LineArray.COORDINATES);
        x_axis.setCoordinate(0, new Point3d(-0.8d, 0.0d, 0.0d));
        x_axis.setCoordinate(1, new Point3d(0.8d, 0.0d, 0.0d));
        mouse.addChild(new Shape3D(x_axis));
        // y-axis
        LineArray y_axis = new LineArray(2, LineArray.COORDINATES);
        y_axis.setCoordinate(0, new Point3d(0.0d, -0.8d, 0.0d));
        y_axis.setCoordinate(1, new Point3d(0.0d, 0.8d, 0.0d));
        mouse.addChild(new Shape3D(y_axis));
        // z-Axis
        LineArray z_axis = new LineArray(2, LineArray.COORDINATES);
        z_axis.setCoordinate(0, new Point3d(0.0d, 0.0d, -0.8d));
        z_axis.setCoordinate(1, new Point3d(0.0d, 0.0d, 0.8d));
        mouse.addChild(new Shape3D(z_axis));
        // ******* Titles for the axis ************* //
        // x-axis
        Text2D xText = new Text2D("x-axis", new Color3f(1.0f, 1.0f, 1.0f), "Arial", 18, Font.PLAIN);
        Appearance xTextAppear = xText.getAppearance();
        PolygonAttributes xpolyAttrib = new PolygonAttributes();
        xpolyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
        xpolyAttrib.setBackFaceNormalFlip(true);
        xTextAppear.setPolygonAttributes(xpolyAttrib);
        mouse.addChild(xText);
        // z-axis
        Text2D zText = new Text2D("z-axis", new Color3f(1.0f, 1.0f, 1.0f), "Arial", 18, Font.PLAIN);
        Appearance zTextAppear = zText.getAppearance();
        PolygonAttributes zpolyAttrib = new PolygonAttributes();
        zpolyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
        zpolyAttrib.setBackFaceNormalFlip(true);
        zTextAppear.setPolygonAttributes(zpolyAttrib);
        // for rotating the z-axis title
        Transform3D rotate90 = new Transform3D();
        rotate90.rotZ(Math.PI/2);
        TransformGroup objRotate = new TransformGroup(rotate90);
        objRotate.addChild(zText);
        mouse.addChild(objRotate);
        // y-axis
        Text2D yText = new Text2D("y-axis", new Color3f(1.0f, 1.0f, 1.0f), "Arial", 18, Font.PLAIN);
        Appearance yTextAppear = yText.getAppearance();
        PolygonAttributes ypolyAttrib = new PolygonAttributes();
        ypolyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
        ypolyAttrib.setBackFaceNormalFlip(true);
        yTextAppear.setPolygonAttributes(ypolyAttrib);
        // for rotating the y-axis title
        Transform3D rotaY = new Transform3D();
        rotaY.rotY(Math.PI/2);
        TransformGroup yobjRotate = new TransformGroup(rotaY);
        yobjRotate.addChild(yText);
        mouse.addChild(yobjRotate);
        // ******* Titles END *******//
/////////////////////////////////////////////////////////
// Axis End
/////////////////////////////////////////////////////////


/////////////////////////////////////////////////////
///
///   Triangles  (TESTS!!!)
///
////////////////////////////////////////////////////

        // data for rendering:

         double a11 = 0.1d;
         double a12 = 0.2d;
         double a13 = 0.3d;
         double a21 = 0.4d;
         double a22 = 0.5d;
         double a23 = 0.6d;

        /*
        double[][] matrix =
                {
                    {a11,  a12,  a13 },
                    {a21,  a22,  a23 }
                }; */

        Point3d[] vertices = new Point3d[6];

        vertices[0] = new Point3d(0.0,  a11, 0.0);
        vertices[1] = new Point3d(0.0, a21, 0.1);
        vertices[2] = new Point3d(0.1, a12, 0.0);
        vertices[3] = new Point3d(0.1d, a22, 0.1d);
        vertices[4] = new Point3d(0.2d, a13, 0.0d);
        vertices[5] = new Point3d(0.2d, a23, 0.1d);

        int[] StripCount = {vertices.length};

        // TriangleStripArray
        TriangleStripArray tsa = new TriangleStripArray(vertices.length, GeometryArray.COORDINATES, StripCount);

        tsa.setCoordinates(0, vertices);

        // Shape3D with TriangleStripInformationen
        Shape3D t = new Shape3D();
        t.setAppearance(createTriangleAppearance());
        t.setGeometry(tsa);

        mouse.addChild(t);

///////////////////////////////////////////////////////////
//        Triangles End
///////////////////////////////////////////////////////////


///////////////////////////////////////
// define MouseBehaviour
//////////////////////////////////////
        // Mouse Translate
        MouseTranslate m_trans = new MouseTranslate();
        m_trans.setTransformGroup(mouse);
        m_trans.setSchedulingBounds(new BoundingBox());
        my_BG.addChild(m_trans);
        // Mouse Zoom
           /*
              INSTRUCTION:
              Press ALT+Mouse Up|Down to zoom in|out
           */
        MouseZoom m_zoom = new MouseZoom();
        m_zoom.setTransformGroup(mouse);
        m_zoom.setSchedulingBounds(new BoundingBox());
        my_BG.addChild(m_zoom);
        // Mouse Rotate
        MouseRotate m_rot = new MouseRotate();
        m_rot.setTransformGroup(mouse);
        m_rot.setSchedulingBounds(new BoundingBox());
        my_BG.addChild(m_rot);
////////////////////////////////////
// MouseBehaviour end
///////////////////////////////////
 }

//////////////////////////////////////////
// creating appearance of the triangles:
//////////////////////////////////////////

 Appearance createTriangleAppearance()

{
        Appearance app = new Appearance();
        ColoringAttributes c_att = new ColoringAttributes(0.2f, 0.1f, 0.8f, ColoringAttributes.SHADE_GOURAUD);
        //c_att.setColor(new Color3f(0.0f, 1.0f, 0.0f));
        app.setColoringAttributes(c_att);

        ///////////////////////////////////////////////////////////////////////////////
        // Material

        Material mat = new Material(new Color3f(0.0f, 0.0f, 0.0f), // ambientColor - the material's ambient color
                                    new Color3f(0.0f, 0.8f, 0.0f), // emissiveColor - the material's emissive color
                                    new Color3f(0.0f, 1.0f, 0.4f), // diffuseColor - the material's diffuse color when illuminated by a light
                                    new Color3f(1.0f, 1.0f, 0.0f), // specularColor - the material's specular color when illuminated to generate a highlight
                                    128.0f) ; // shininess - the material's shininess in the range [1.0, 128.0] with 1.0 being not shiny and 128.0 being very shiny. Values outside this range are clamped.
        app.setMaterial(mat);

        // Material End
        ////////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////////
        // Polygon attributes
        PolygonAttributes TrianglePolygonAttrib = new PolygonAttributes(
                  PolygonAttributes.POLYGON_FILL, //polygonMode - polygon rasterization mode; one of POLYGON_POINT, POLYGON_LINE, or POLYGON_FILL
                  PolygonAttributes.CULL_NONE, // Integer cullFace - polygon culling mode; one of CULL_NONE, CULL_BACK, or CULL_FRONT
                  100f, // polygonOffset - constant polygon offset
                  false, // backFaceNormalFlip - back face normal flip flag; true or false
                  100f); // polygonOffset - polygon offset factor for slope-based polygon offset
        app.setPolygonAttributes(TrianglePolygonAttrib);
        //Polygon attributes end
        ////////////////////////////////////////////////////////////////////////////////


 return app;
}
//////////////////////////////////////////
// Triangle Appearance End
//////////////////////////////////////////


public BranchGroup getBG()
       {
                return my_BG;
        }
}