package classwork;

import javax.media.opengl.*;
import java.awt.event.*;
import jocode.*;

/**
 * GLART_12_giantimage.java
 *
 * Save a "giant" image of a scene by rendering the scene as a series
 * of tiles and saving the tiled images.  Piece the tiles back together
 * to form a high resolution image of the scene.
 *
 * Hit  F1  to save the current scene as 16 tiled images.
 *
 * The functions:
 *
 * giantScreenShot() - render scene as tiles and saves to files
 * setPerspective()  - inititialize perspective settings for frustum
 * setFrustum()      - adjust the frustum to show one portion of scene
 * screenShot()      - save current screen to PNG file
 */
public class GLART_12_giantimage extends JOApp {
	JOGiantScreenShot gss;
	float rotation = 0f;
    float rotation2 = 0f;
    float rotationAmount = .08f;
    float aspectRatio;
    int screenShotCounter = 0;
    boolean doGiantScreenShot = false;
    int scale = 1;

    /**
     * Main function just creates and runs the application.
     */
    public static void main(String args[]) {
    	GLART_12_giantimage app = new GLART_12_giantimage();
    	windowTitle = "Giant Screenshot";
    	useCurrentDisplay = true;
    	fullScreen = true;
        app.run();
     }

    /**
     * Initialize the environment
     */
    public void setup() {
    	gss = new JOGiantScreenShot(
    	          this, method("drawFrame"), 
    	          "images",
    	          55f, (float)getWidth()/(float)getHeight(), 1f, 100f,    // same as gluPerspective()
    	          getWidth(), getHeight());

    	gl.glMatrixMode(GL.GL_PROJECTION);
    	gl.glLoadIdentity();
    	glu.gluPerspective(55f,(float)getWidth()/(float)getHeight(), 1f, 100f);  // same as JOGiantScreenShot()
    	gl.glMatrixMode(GL.GL_MODELVIEW);

    	 // Random value for rotation increment: .05 - 1.0
        rotationAmount = (float) (.05 + (Math.random()*.05));

        // No need for depth, composition is flat
        gl.glDisable(GL.GL_DEPTH_TEST);

        // set the background color
        gl.glClearColor(.1f, .1f, .12f, 1);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // To create transparencies (alpha blending)
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
    }

    /**
     * Render the scene.
     */
    public void draw() {
    	rotation += .08f;
    	rotation2 += rotationAmount;

    	drawFrame();
    }

    /**
     * Render the scene.
     */
    public void drawFrame() {
    	gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // Reset the Modelview matrix
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();

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

        // rotate scene
      	gl.glRotatef(rotation*3.3f, 0,0,1);
    	gl.glTranslatef(.5f,0,0);

    	// draw a red quad
    	gl.glColor4f(1,0f,0f,.7f);
    	gl.glPushMatrix();
    	{
        	gl.glRotatef(rotation*.7f, 0,1,1);
    		gl.glTranslatef(0,.5f,0);
    		gl.glRotatef(rotation2, 0,0,1);
    		drawQuad();
    	}
    	gl.glPopMatrix();

    	// rotate more
    	gl.glRotatef(rotation2*4.7f, 0,0,1);
    	gl.glTranslatef(1,0,0);

    	// draw a green quad
    	gl.glColor4f(0f,1,0f,.7f);
    	gl.glPushMatrix();
    	{
        	gl.glRotatef(rotation2*2f, 0,0,1);
    		gl.glTranslatef(-.5f,-.5f,0);
    		gl.glRotatef(rotation2, 0,0,1);
    		drawQuad();
    	}
    	gl.glPopMatrix();

    	// draw a blue quad
    	gl.glColor4f(0f,0f,1,.7f);
    	gl.glPushMatrix();
    	{
        	gl.glRotatef(rotation2, 1,0,1);
    		gl.glTranslatef(.5f,-.5f,0);
    		gl.glRotatef(rotation2, 0,0,1);
    		drawQuadLine();
    	}
    	gl.glPopMatrix();

    	// draw lines
    	gl.glPushMatrix();
    	{
        	gl.glRotatef(rotation2*2.1f, 1,0,1);
        	gl.glColor4f(0f,.5f,1,.7f);
    		drawQuadLine();
        	gl.glRotatef(2f, 1,0,1);
        	gl.glColor4f(0f,.6f,1,.7f);
    		drawQuadLine();
        	gl.glRotatef(3f, 1,0,1);
        	gl.glColor4f(0f,.8f,1,.7f);
    		drawQuadLine();
    	}
    	gl.glPopMatrix();
    }

    /**
     * draw a 1x1 square
     */
    public void drawQuad() {
        gl.glBegin(GL.GL_QUADS);
        {
            gl.glTexCoord2f(0, 0);
            gl.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left

            gl.glTexCoord2f(1, 0);
            gl.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right

            gl.glTexCoord2f(1, 1);
            gl.glVertex3f( 1.0f, 1.0f, 0.0f);         // Top Right

            gl.glTexCoord2f(0, 1);
            gl.glVertex3f(-1.0f, 1.0f, 0.0f);         // Top left
        }
        gl.glEnd();
    }

    /**
     * draw a 1x1 square
     */
    public void drawQuadLine() {
    	gl.glLineWidth(scale);
        gl.glBegin(GL.GL_LINE_STRIP);
        {
            gl.glTexCoord2f(0, 0);
            gl.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left

            gl.glTexCoord2f(1, 0);
            gl.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right

            gl.glTexCoord2f(1, 1);
            gl.glVertex3f( 1.0f, 1.0f, 0.0f);         // Top Right

            gl.glTexCoord2f(0, 1);
            gl.glVertex3f(-1.0f, 1.0f, 0.0f);         // Top left

            gl.glTexCoord2f(0, 0);
            gl.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
        }
        gl.glEnd();
    }

    /**
     */
    public void keyUp(int keycode) {
        // set flag to save screen (see render())
        if (keycode == KeyEvent.VK_F1) {
        	// save screen regular size (for reference)
        	screenShot("screen_capture.png");
        	// make a jumbo sized image of screen
        	scale = 8;
        	gss.screenshot(scale);    // eight times screen size
        	scale = 1;
        }
    }

    /**
     * Clean up all the resources.
     */
    public void exit() {
		super.exit();
    }
}
