package classwork;

import javax.media.opengl.*;
import jocode.*;

/**
 * GLART_2_modelview_transform.java
 *
 * Use glPushMatrix() and glPopMatrix() to isolate the effect of glTranslate(),
 * glScale() and glRotate() commands.
 */
public class GLART_2_modelview_transform_pushpop extends JOApp {

    /**
     * Main function just creates and runs the application.
     */
    public static void main(String args[]) {
    	GLART_2_modelview_transform_pushpop app = new GLART_2_modelview_transform_pushpop();
        app.run();
    }

    /**
     * Render the scene.
     */
    public void draw() {
        // Clear screen and depth buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // Select The Modelview Matrix (controls model orientation)
        gl.glMatrixMode(GL.GL_MODELVIEW);

        // Reset the Modelview matrix
        // this resets the coordinate system to center of screen
        gl.glLoadIdentity();

        // Set the viewpoint
        glu.gluLookAt(
            0f, 1f, 12f,   // eye position
            0f, 1f, 0f,    // target to look at
            0f, 1f, 0f);   // which way is up

        // draw 10x10 grid centered at origin
        drawGrid();

        if (true) {
        	drawArrow();
        }
        
        if (false) {
        	// draw a doublesize arrow pointing up, and a halfsize small arrow pointing down (WRONG WAY!)
        	gl.glTranslatef(2f,0,0);
        	gl.glScalef(2f, 2f, 2f);
        	drawArrow();
        	
        	gl.glTranslatef(2f,0,0);
        	gl.glRotatef(180, 0,0,1);
        	gl.glScalef(.5f, .5f, .5f);
        	drawArrow();
        }

		if (false) {
			// draw a doublesize arrow pointing up, and a halfsize small arrow pointing down (WRONG WAY!)
			gl.glPushMatrix();
			{
				gl.glTranslatef(2f,0,0);
				gl.glScalef(2f, 2f, 2f);
				drawArrow();
			}
			gl.glPopMatrix();

			// rotate, shift 2 up, scale down, draw arrow
			gl.glPushMatrix();
			{
				gl.glTranslatef(2f,0,0);
				gl.glRotatef(180, 0,0,1);
				gl.glScalef(.5f, .5f, .5f);
				drawArrow();
			}
			gl.glPopMatrix();
		}

		if (false) {
			// same as above, but with nested push()-pop()
			gl.glPushMatrix();
			{
				gl.glTranslatef(2f,0,0);

				gl.glPushMatrix();
				{
					gl.glScalef(2f, 2f, 2f);
					drawArrow();
				}
				gl.glPopMatrix();

				gl.glRotatef(180, 0,0,1);
				gl.glScalef(.5f, .5f, .5f);
				drawArrow();
			}
			gl.glPopMatrix();
		}

        // draw background grid after transformations
        //drawGrid();
    }

    /**
     *  Draw a 10x10 grid with a crosshair at center
     */
    public void drawGrid() {
    	// draw 10x10 grid
    	gl.glColor3f(.5f, .5f, .5f);
        gl.glLineWidth(1);
        for (int c=-5; c <= 5; c++ ) {
	        gl.glBegin(GL.GL_LINES);
		    	gl.glVertex3f( c, -5f, 0f);        // bottom
		    	gl.glVertex3f( c, 5f, 0f);         // top
			gl.glEnd();
        }
        for (int r=-5; r <= 5; r++ ) {
	        gl.glBegin(GL.GL_LINES);
		    	gl.glVertex3f( -5f, r, 0f);        // left
		    	gl.glVertex3f(  5f, r, 0f);        // right
			gl.glEnd();
        }

        // draw crosshair at origin
    	gl.glColor3f(.8f, .5f, .5f);
        gl.glLineWidth(3);
        gl.glBegin(GL.GL_LINES);
	    	gl.glVertex3f( -1f, 0f, 0f);        // left
	    	gl.glVertex3f( 1f, 0f, 0f);         // right
	    	gl.glVertex3f( 0f, -1f, 0f);        // bottom
	    	gl.glVertex3f( 0f, 1f, 0f);         // top
		gl.glEnd();

		// draw a triangle
		gl.glBegin(GL.GL_TRIANGLES);
		gl.glVertex3f( -.1f, 1f, 0f);		// left bottom
		gl.glVertex3f(  .1f, 1f, 0f);		// rite bottom
		gl.glVertex3f(   0f, 1.1f, 0f);		// top
		gl.glEnd();
    }

    /**
     * draw an arrow pointing up the Y axis, 3 units tall
     */
    public void drawArrow() {
    	// green color
    	gl.glColor3f(.2f, 1f, .2f);

		// draw a quad
		gl.glBegin(GL.GL_QUADS);
		gl.glVertex3f( -.5f, 0f, 0f);       // left bottom
		gl.glVertex3f(  .5f, 0f, 0f);       // rite bottom
		gl.glVertex3f(  .5f, 2f, 0f);       // rite top
		gl.glVertex3f( -.5f, 2f, 0f);       // left top
		gl.glEnd();

		// draw a triangle
		gl.glBegin(GL.GL_TRIANGLES);
		gl.glVertex3f( -1f, 2f, 0f);       // left bottom
		gl.glVertex3f(  1f, 2f, 0f);       // rite bottom
		gl.glVertex3f(  0f, 3f, 0f);       // top
		gl.glEnd();
	}
}
