package classwork;

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

/**
 * GLART_4_light_triangle.java
 *
 * Very basic lighting demo.  Shines a light on a triangle.
 * Calculates the triangle normal and draws it.
 *
 * use glLight() to set inidivual light parameters.
 * use glLightModel() to set overall light parameters.
 * use glNormal3f() to set the face normal.
 */
public class GLART_4_light_triangle extends JOApp {
    float rotation = 0;
    // Color value for the overall scene lighting
    float sceneAmbientLight[]  = { 0.18f, 0.1f, .15f, 1f };
    // Color values for light
    float lightDiffuse[]  = { 1f, 1f, .8f, 1f };
    float lightSpecular[] = { 1f, 1f, .8f, 1f };
    float lightAmbient[]  = { 0.5f, 0.5f, .4f, 1f };
    // Light position: if last value is 0, then this describes light direction.  If 1, then light position.
    float lightPosition[] = { -4f, 3f, 3f, 1f };

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

    /**
     * Initialize OpenGL
     *
     */
    public void setup() {
        // Select the Projection Matrix (controls perspective)
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();    // Reset The Projection Matrix

        // Define perspective
        glu.gluPerspective(
            45.0f,        // Field Of View
            (float)getWidth() / (float)getHeight(), // aspect ratio
            0.1f,         // near Z clipping plane
            100.0f);      // far Z clipping plane

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

        // make sure OpenGL correctly layers objects
        gl.glEnable(GL.GL_DEPTH_TEST);

        // OpenGL won't draw backward facing triangles ("back faces")
        gl.glEnable(GL.GL_CULL_FACE);

        // turn lighting on (does not create a light)
        gl.glEnable(GL.GL_LIGHTING);

        // Create a light
        // diffuse is the color of direct light from this light source
        // specular is the color of the reflected light
        // ambient is the color of scattered light from this source
        // position is where the light is, or it's direction
        setLight( GL.GL_LIGHT1, lightDiffuse, lightAmbient, lightSpecular, lightPosition );

        // no overall scene lighting
        setAmbientLight(sceneAmbientLight);
    }

    /**
     * Render the scene.
     */
    public void draw() {
    	// hold triangle vertex positions in Vector objects
        JOVector v1 = new JOVector( 0.0f, 1.0f, 0.0f);
        JOVector v2 = new JOVector(-1.0f,-1.0f, 0.0f);
        JOVector v3 = new JOVector( 1.0f,-1.0f, 0.0f);

		// calculate normal of triangle
		JOVector normal = JOVector.getNormal(v1, v2, v3);

		// calculate center of triangle
		JOVector center = JOVector.avg(v1,v2,v3);

        // increment
    	rotation += .5f;

		// 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 coordinate system to center of screen
        gl.glLoadIdentity();

        // Where is the 'eye'
        glu.gluLookAt(
            0f, 0f, 4f,   // eye position
            0f, 0f, 0f,    // target to look at
            0f, 1f, 0f);   // which way is up

        // lines will be 2 pixels
        gl.glLineWidth(2);

        // turn lighting on
        gl.glEnable(GL.GL_LIGHTING);
        
        // if you disable lighting, the glColor() command will work, turning the triangle green.
        // with lighting enabled, use glMaterial() commands to control color.  glColor() is ignored.
        //gl.glDisable(GL.GL_LIGHTING);

        // Draw the triangle and normal, rotating
        gl.glPushMatrix();
        {
        	// rotate on X Y and X axes
        	gl.glRotatef(rotation, .5f, 1, .5f);
        	gl.glRotatef(rotation/2f, 0, 1, 0);

            // draw a green triangle (lighting overrides vertex color)
            gl.glColor4f(0, 1, 0, 1);
			gl.glBegin(GL.GL_TRIANGLES);
			{
				// set the normal (affects all following verts)
		        gl.glNormal3f(normal.x, normal.y, normal.z);
				gl.glVertex3f(0.0f, .75f, 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();

			// draw a line to indicate where the normal is
	        // turn lighting off (so glColor() will work)
	        gl.glDisable(GL.GL_LIGHTING);
			gl.glColor4f(1, 0, 0, 1);
			gl.glBegin(GL.GL_LINES);
			{
				gl.glVertex3f(center.x, center.y, center.z);
				gl.glVertex3f(center.x+normal.x, center.y+normal.y,	center.z+normal.z);
			}
			gl.glEnd();
		}
        gl.glPopMatrix();
    }

}
