/**
 *  CS 467. Cornell University.
 */

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import net.java.games.jogl.*;
import net.java.games.cg.*;

public class Vertex extends JFrame implements GLEventListener {
  public static final int VIEWPORT_WIDTH = 512;
  public static final int VIEWPORT_HEIGHT = 512;
  protected GLCanvas canvas;

  // Cg context and profiles
  protected CGcontext cgContext;
  protected int cgVertexProfile;

  // the Cg programs
  protected static CGprogram cgVertexProgram;

  // Cg program parameters
  protected static CGparameter cgModelViewProjMatrix;

  public Vertex() {
    super("Simple Vertex Normal Shader");
    setLocation(100, 100);
    setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);

    canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
    canvas.addGLEventListener(this);

    JPanel glPanel = new JPanel(new BorderLayout());
    glPanel.add(canvas, BorderLayout.CENTER);
    glPanel.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    getContentPane().add(glPanel);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    show();
  }

  public void display(GLDrawable gLDrawable) {
    final GL gl = gLDrawable.getGL();

    CgGL.cgGLBindProgram(cgVertexProgram);
    CgErrorException.checkCgError();

    // set up the transformation matrix
    CgGL.cgGLSetStateMatrixParameter( cgModelViewProjMatrix, CgGL.CG_GL_MODELVIEW_PROJECTION_MATRIX, CgGL.CG_GL_MATRIX_IDENTITY);
    CgErrorException.checkCgError();

    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();

    gl.glBegin(gl.GL_QUADS);

    // Front Face
    gl.glNormal3f(0.0f,0.0f,1.0f);
    gl.glVertex3f(-1.0f, -1.0f, 1.0f);
    gl.glVertex3f(1.0f, -1.0f, 1.0f);
    gl.glVertex3f(1.0f, 1.0f, 1.0f);
    gl.glVertex3f(-1.0f, 1.0f, 1.0f);

    // Back Face
    gl.glNormal3d(0.0,0.0,-1.0);
    gl.glVertex3f( -1.0f, -1.0f, -1.0f);
    gl.glVertex3f( -1.0f, 1.0f, -1.0f);
    gl.glVertex3f(1.0f, 1.0f, -1.0f);
    gl.glVertex3f(1.0f, -1.0f, -1.0f);

    // Top Face
    gl.glNormal3d(0.0, 1.0,0.0);
    gl.glVertex3f( -1.0f, 1.0f, -1.0f);
    gl.glVertex3f( -1.0f, 1.0f, 1.0f);
    gl.glVertex3f(1.0f, 1.0f, 1.0f);
    gl.glVertex3f(1.0f, 1.0f, -1.0f);

    // Bottom Face
    gl.glNormal3d(0.0, -1.0, 0.0);
    gl.glVertex3f( -1.0f, -1.0f, -1.0f);
    gl.glVertex3f(1.0f, -1.0f, -1.0f);
    gl.glVertex3f(1.0f, -1.0f, 1.0f);
    gl.glVertex3f( -1.0f, -1.0f, 1.0f);

    // Right Face
     gl.glNormal3d(1.0, 0.0, 0.0);
    gl.glVertex3f(1.0f, -1.0f, -1.0f);
    gl.glVertex3f(1.0f, 1.0f, -1.0f);
    gl.glVertex3f(1.0f, 1.0f, 1.0f);
    gl.glVertex3f(1.0f, -1.0f, 1.0f);

    // Left Face
    gl.glNormal3d(1.0, 0.0, 0.0);
    gl.glVertex3f( -1.0f, -1.0f, -1.0f);
    gl.glVertex3f( -1.0f, -1.0f, 1.0f);
    gl.glVertex3f( -1.0f, 1.0f, 1.0f);
    gl.glVertex3f( -1.0f, 1.0f, -1.0f);

    gl.glEnd();

    //gl.glFlush();
  }

  public void displayChanged(GLDrawable gLDrawable, boolean modeChanged,
                             boolean deviceChanged) {
  }

  public void reshape(GLDrawable gLDrawable, int x, int y, int width,
                      int height) {
    final GL gl = gLDrawable.getGL();
    final GLU glu = gLDrawable.getGLU();

    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(gl.GL_PROJECTION);
    gl.glLoadIdentity();
    glu.gluPerspective(45.0f, (float) width / (float) height, 0.2f, 100.0f);
    glu.gluLookAt(3.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
    gl.glMatrixMode(gl.GL_MODELVIEW);
    gl.glLoadIdentity();
  }

  public void init(GLDrawable gLDrawable) {
    final GL gl = gLDrawable.getGL();

    gl.glEnable(gl.GL_DEPTH_TEST);

    initializeCg();
}

protected void initializeCg() {
    cgContext = CgGL.cgCreateContext();
    CgErrorException.checkCgError();

    cgVertexProfile = CgGL.CG_PROFILE_VP20;

    CgGL.cgGLEnableProfile( cgVertexProfile);
    CgErrorException.checkCgError();

    cgVertexProgram  = CgGL.cgCreateProgramFromFile( cgContext, CgGL.CG_SOURCE, "Normal.cg", cgVertexProfile, "Normal", null);

    CgGL.cgGLLoadProgram(cgVertexProgram);
    CgErrorException.checkCgError();

    cgModelViewProjMatrix = CgGL.cgGetNamedParameter( cgVertexProgram, "ModelViewProjMatrix");
    CgErrorException.checkCgError();
}


  public static void main(String[] args) {
    new Vertex();
  }
}
