package classwork;

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

/**
 * GLART_2_modelview.java
 *
 * Use glTranslate(), glScale() and glRotate() to alter the modelview matrix.  The Modelview
 * matrix affects the positioning of geometry within the scene.
 */
public class GLART_2_modelview_transform extends JOApp {

    /**
     * Main function just creates and runs the application.
     */
    public static void main(String args[]) {
    	GLART_2_modelview_transform app = new GLART_2_modelview_transform();
        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, 10f,   // 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) {
        	// draw arrow at origin
			drawArrow();
		}

    	if (false) {
	    	// shift 2 right and draw arrow
	    	gl.glTranslatef(2f,0,0);
	    	drawArrow();
    	}

    	if (false) {
	    	// shift 2 right and draw arrow
	    	gl.glTranslatef(2f,0,0);   // transformations are additive
	    	drawArrow();
    	}

    	if (false) {
	    	// shift 2 right, scale up, draw arrow
	    	gl.glTranslatef(2f,0,0);
	    	gl.glScalef(2f, 2f, 2f);
	    	drawArrow();
    	}

    	if (false) {
	    	// scale up, shift 2 right, draw arrow
	    	gl.glScalef(2f, 2f, 2f);	// "stretch" the coordinate system
	    	gl.glTranslatef(2f,0,0);	// two units now equals 4 units
	    	drawArrow();
    	}

    	if (false) {
	    	// shift 2 left and draw arrow
	    	gl.glTranslatef(-2f,0,0);	// relative to current position
	    	drawArrow();
    	}

    	if (false) {
	    	// shift 2 right, rotate 90 clockwise, draw arrow
    		// Rotation follows the right-hand rule, so if the vector XYZ points toward the user, the rotation will be counterclockwise.
	    	gl.glTranslatef(2f,0,0);
	    	gl.glRotatef(-90, 0,0,1);
	    	drawArrow();
    	}

    	if (false) {
	    	// rotate 90 clockwise, shift 2 right, draw arrow
    		// Rotation follows the right-hand rule, so if the vector XYZ points toward the user, the rotation will be counterclockwise.
	    	gl.glRotatef(-90, 0,0,1);
	    	gl.glTranslatef(2f,0,0);	// Y axis now points right
	    	drawArrow();
    	}

        // 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();
	}
}
