package demo;

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

/**
 * Demonstrates 'ortho' mode by drawing a flat 2D image over a 3D scene. Switches
 * between ortho and perspective modes to render both 3D and 2D.  Also draws a crosshair
 * image at the cursor position, another use of ortho mode.
 * <P>
 * Move mouse to scale overlay image.
 * <P>
 * GLApp initializes the LWJGL environment for OpenGL rendering,
 * ie. creates a window, sets the display mode, inits mouse and keyboard,
 * then runs a loop that calls draw().
 * <P>
 * napier at potatoland dot org
 */
public class DemoOrtho extends JOApp {
    // Handle for texture
    int sphereTextureHandle = 0;
    // Lighting colors
    float faWhite[]      = { 1.0f, 1.0f, 1.0f, 1.0f };
    float faLightBlue[]  = { 0.8f, 0.8f, .9f, 1f };
    // Light position: if last value is 0, then this describes light direction.  If 1, then light position.
    float lightPosition[]= { -4f, 3f, 3f, 1.0f };
    // World coordinates of sphere
    float[] spherePos = {0f, 0f, 0f};
    // Rotation of sphere
    float rotation = 0f;
    // image to draw as 2D overlay over 3D scene, and texture handle for it
    JOImage overlayImage;
    int overlayTextureHandle = 0;
    // cursor is a texture drawn onto a quad
    int cursorTextureHandle = 0;

	/**
	 * Start the application.  demo.run() calls setup(), handles mouse and keyboard input,
	 * and calls draw() in a loop.
	 */
    public static void main(String args[]) {
        DemoOrtho demo = new DemoOrtho();
        windowTitle = "GLApp Ortho Demo";
        //hideNativeCursor = true;        
        displayWidth = 800;
        displayHeight = 600;
        demo.run();  // will call init(), render(), mouse functions
    }

    /**
     * Initialize the scene.  Called by GLApp.run()
     */
    @Override
    public void setup() {
        // Setup and enable perspective. Scene will be rendered in 3D.
        setPerspective();

        // Create a light (diffuse light, ambient light, position)
        setLight(GL.GL_LIGHT1, faWhite, faWhite, faLightBlue, lightPosition);

        // enable lighting and texture rendering
        gl.glEnable(GL.GL_LIGHTING);
        gl.glEnable(GL.GL_TEXTURE_2D);

        // Enable alpha transparency (for overlay image)
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

        sphereTextureHandle = makeTexture("images/eye.jpg");

        // Load a cursor image and make it a texture
        cursorTextureHandle = makeTexture("images/cursorCrosshair32.gif");

        // Load the image for 2D overlay and make it a texture
        overlayImage = loadImage("images/frame_ornate3.gif");
        overlayTextureHandle = makeTexture(overlayImage);
    }

    /**
     * set the camera position, field of view, depth.
     */
    public void setPerspective() {
    	setPerspective(30f,1f,100f);
    }

    /**
     * Render one frame.  Called by GLApp.run().
     */
    @Override
    public void render() {
        rotation += .5f;

        // clear depth buffer and color
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // select model view for subsequent transforms
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();

        // set the viewpoint
        glu.gluLookAt(0f, 0f, 15f, // where is the eye
        			0f, 0f, 0f,    // what point are we looking at
        			0f, 1f, 0f);   // which way is up

        // draw sphere at center, in perspective
        gl.glPushMatrix();
        {
            gl.glTranslatef(spherePos[0], spherePos[1], spherePos[2]);
            gl.glRotatef(-90, 1, 0, 0);       // rotate around X axis
            gl.glRotatef(rotation, 0, 0, 1);  // rotate around Y axis
            gl.glBindTexture(GL.GL_TEXTURE_2D, sphereTextureHandle); // activate texture
            renderSphere();                     // draw the sphere
        }
        gl.glPopMatrix();

        // Turn off lighting so image will draw as-is, not lit
        gl.glDisable(GL.GL_LIGHTING);

        // drawQuad() and drawCursor call setOrthoOn() to render in 2D mode
        // then call setOrthoOff() to return to previous state (perspective).

        // Overlay Image: draw image in 2D (ortho mode) as a texture on a quad.
        float zoom = ((float)cursorX/getWidth()) * 2f;   // mouse motion scales the image
        drawQuad(overlayTextureHandle,                      // image will be texture on a square
                (int)((getWidth()/2)-((overlayImage.w*zoom)/2)),  // center image
                (int)((getHeight()/2)-((overlayImage.h*zoom)/2)),
                (overlayImage.w*zoom),                   // scale width and height
                (overlayImage.h*zoom) );

        // rectangle
        setColor(.7f, .6f, .5f, 1f);
        setLineWidth(2);
        drawRect(10,10,565,40);
        print(15,22,"Use Ortho mode to render in 2D over the scene.");
        
        // draw the cursor as a 2D quad on top of scene
        drawCursor(cursorTextureHandle);

        // turn lighting back on
        gl.glEnable(GL.GL_LIGHTING);
    }
}