

import javax.media.opengl.*;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.media.opengl.awt.GLJPanel;
import com.jogamp.opengl.util.gl2.GLUT;

/**
 * This is a template for a basic OpenGL program that shows an animated
 * scene.  The shift key can be used to toggle the animation.  The arrow keys 
 * can be used to rotate the view of the scene, and the Home key will set the 
 * view rotations to zero.  The ranges of x, y, and z that are visible in the 
 * scene are determined by a "scale" property;  the scale variable is used in 
 * the display function to set up the projection.  It determines the range of 
 * x, y, and z that are visible in the scene.  x and y range from -scale to scale; 
 * z ranges from -2*scale to 2*scale. 
 *    Note that lighting IS enabled in this template; to disaable it, 
 * comment out the four lines in the init() method that configure lighting.
 */
public class JoglAnimation extends GLJPanel implements GLEventListener, KeyListener, ActionListener {

	public static void main(String[] args) {
		JFrame window = new JFrame("JOGL Scene");
		GLCapabilities caps = new GLCapabilities(null);
		JoglAnimation panel = new JoglAnimation(caps);
		window.setContentPane(panel);
		window.pack();
		window.setLocation(50,50);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setVisible(true);
		panel.requestFocusInWindow(); // to set up key events to go to the panel
	}
	
	private double scale = 5;  // determines the range of visible x, y, and z

	private float rotateX, rotateY;   // rotation amounts about axes, controlled by keyboard
	
	private GLUT glut = new GLUT();  // for use in drawing GLUT shapes.

	public JoglAnimation(GLCapabilities capabilities) {
		super(capabilities);
		setPreferredSize( new Dimension(500,500) ); // set size of viewing area
		addGLEventListener(this);
		addKeyListener(this);
		rotateX = 0;   // start with no rotations about the axes
		rotateY = 0;
		
		// TODO:  Add any other necessary initialization for the animation!

		// To start the animation as soon as the program starts, uncomment this line
		// startAnimation();
	}
	
	// ------------------ support for animation --------------------
	
	private Timer animationTimer;
	private boolean animating;
	private int frameNumber = 0;
	
	private void updateFrame() {
		// TODO:  add any other updating required for the next frame.
		frameNumber++;
	}
	
	public void startAnimation() {
		if ( ! animating ) {
			if (animationTimer == null) {
				animationTimer = new Timer(30, this);
			}
			animationTimer.start();
			animating = true;
		}
	}
	
	public void pauseAnimation() {
		if ( animating ) {
			animationTimer.stop();
			animating = false;
		}
	}
	
	public void actionPerformed(ActionEvent evt) {
		updateFrame();
		repaint();
	}



	// ------------ methods of the KeyListener interface ------------

	public void keyPressed(KeyEvent e) {
		   // responds to arrow and home keys by changing rotation amounts
		int key = e.getKeyCode();
		if ( key == KeyEvent.VK_LEFT )
			rotateY -= 15;
		else if ( key == KeyEvent.VK_RIGHT )
			rotateY += 15;
		else if ( key == KeyEvent.VK_DOWN)
			rotateX += 15;
		else if ( key == KeyEvent.VK_UP )
			rotateX -= 15;
		else if ( key == KeyEvent.VK_HOME )
			rotateX = rotateY = 0;
		repaint();
	}

	public void keyReleased(KeyEvent e) { 
	}

	public void keyTyped(KeyEvent e) { 
		char ch = e.getKeyChar();
		if (ch == ' ') {
			if (animationTimer != null && animationTimer.isRunning())
				pauseAnimation();
			else
				startAnimation();
		}
	}


	// ---------------  Methods of the GLEventListener interface -----------

	public void display(GLAutoDrawable drawable) {	
		    // called when the panel needs to be drawn

		GL2 gl = drawable.getGL().getGL2();
		gl.glClearColor(0,0,0,1);
		gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );

		gl.glMatrixMode(GL2.GL_PROJECTION);  // Set up the projection.
		gl.glLoadIdentity();
		gl.glOrtho(-scale,scale,-scale,scale,-2*scale,2*scale);
		gl.glMatrixMode(GL2.GL_MODELVIEW);

		gl.glLoadIdentity();             // Set up modelview transform. 
		gl.glRotatef(rotateY,0,1,0);
		gl.glRotatef(rotateX,1,0,0);

		// TODO:  Add drawing code!!

	}

	public void init(GLAutoDrawable drawable) {
		    // called when the panel is created
		GL2 gl = drawable.getGL().getGL2();
		gl.glClearColor(0.8F, 0.8F, 0.8F, 1.0F);
		gl.glEnable(GL.GL_DEPTH_TEST);
		
		// To disable lighting, comment out the following four lines
		gl.glEnable(GL2.GL_LIGHTING);  
		gl.glEnable(GL2.GL_LIGHT0);
		gl.glEnable(GL2.GL_COLOR_MATERIAL);
		gl.glEnable(GL2.GL_NORMALIZE);  // (Make normals work correctly with scaling.)
	}

	public void dispose(GLAutoDrawable drawable) {
		// called when the panel is being disposed
	}

	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
		// called when user resizes the window
	}

}
