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

import javax.media.opengl.*;
import javax.media.opengl.glu.GLU;


public class Lesson02
{
  static class Renderer
    implements GLEventListener,
               KeyListener
  {
    /** Called by the drawable to initiate OpenGL rendering by the client.
     * After all GLEventListeners have been notified of a display event, the 
     * drawable will swap its buffers if necessary.
     * @param gLDrawable The GLDrawable object.
     */    
    public void display(GLAutoDrawable gLDrawable)
    {
      final GL gl = gLDrawable.getGL();
      gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
      gl.glLoadIdentity();
      gl.glTranslatef(-1.5f, 0.0f, -6.0f);
      gl.glBegin(GL.GL_TRIANGLES);		// Drawing Using Triangles
        gl.glVertex3f( 0.0f, 1.0f, 0.0f);	// Top
        gl.glVertex3f(-1.0f,-1.0f, 0.0f);	// Bottom Left
        gl.glVertex3f( 1.0f,-1.0f, 0.0f);	// Bottom Right
      gl.glEnd();				// Finished Drawing The Triangle
      gl.glTranslatef(3.0f, 0.0f, 0.0f);
      gl.glBegin(GL.GL_QUADS);           	// Draw A Quad
        gl.glVertex3f(-1.0f, 1.0f, 0.0f);	// Top Left
        gl.glVertex3f( 1.0f, 1.0f, 0.0f);	// Top Right
        gl.glVertex3f( 1.0f,-1.0f, 0.0f);	// Bottom Right
        gl.glVertex3f(-1.0f,-1.0f, 0.0f);	// Bottom Left
      gl.glEnd();				// Done Drawing The Quad
      gl.glFlush();
    }
    
    
	 /** Called when the display mode has been changed.  <B>!! CURRENTLY UNIMPLEMENTED IN JOGL !!</B>
    * @param gLDrawable The GLDrawable object.
    * @param modeChanged Indicates if the video mode has changed.
    * @param deviceChanged Indicates if the video device has changed.
    */
	 public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged)
    {
    }
    
	 /** Called by the drawable immediately after the OpenGL context is 
    * initialized for the first time. Can be used to perform one-time OpenGL 
    * initialization such as setup of lights and display lists.
    * @param gLDrawable The GLDrawable object.
    */
   public void init(GLAutoDrawable gLDrawable)
    {
      final GL gl = gLDrawable.getGL();
      gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
      gl.glShadeModel(GL.GL_FLAT);
      gLDrawable.addKeyListener(this);
    }
    
  
	 /** Called by the drawable during the first repaint after the component has 
    * been resized. The client can update the viewport and view volume of the 
    * window appropriately, for example by a call to 
    * GL.glViewport(int, int, int, int); note that for convenience the component
    * has already called GL.glViewport(int, int, int, int)(x, y, width, height)
    * when this method is called, so the client may not have to do anything in
    * this method.
    * @param gLDrawable The GLDrawable object.
    * @param x The X Coordinate of the viewport rectangle.
    * @param y The Y coordinate of the viewport rectanble.
    * @param width The new width of the window.
    * @param height The new height of the window.
    */
	 public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height)
    {
      final GL gl = gLDrawable.getGL();
      final GLU glu = new GLU();

      if (height <= 0) // avoid a divide by zero error!
        height = 1;
      final float h = (float)width / (float)height;
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL.GL_PROJECTION);
      gl.glLoadIdentity();
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glLoadIdentity();
    }

    /** Invoked when a key has been pressed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key pressed event.
     * @param e The KeyEvent.
     */
    public void keyPressed(KeyEvent e)
    {
      if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
        System.exit(0);
    }
    
    /** Invoked when a key has been released.
     * See the class description for {@link KeyEvent} for a definition of
     * a key released event.
     * @param e The KeyEvent.
     */
    public void keyReleased(KeyEvent e) {}
    
    /** Invoked when a key has been typed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key typed event.
     * @param e The KeyEvent.
     */
    public void keyTyped(KeyEvent e) {}
  }

  /** Program's main entry point
   * @param args command line arguments.
   */
  public static void main(String[] args)
  {
    Frame frame = new Frame("Lesson 2: Your First Polygon");
    GLJPanel canvas = new GLJPanel(new GLCapabilities());
    canvas.addGLEventListener(new Renderer());
    frame.add(canvas);
    frame.setSize(640, 480);
    frame.addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent e)
      {
        System.exit(0);
      }
    });
    frame.show();
    canvas.requestFocus();
  }
}
