// Simple GLUT/GL example


#include "draw.h"
#include "shader.h"
#include "view.h"
#include "motion.h"
#include "key.h"
#include "imgtex.h"

// Apple's annoying non-standard GL include location
#if defined(__APPLE__) || defined(MACOSX)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

// initialize GLUT - windows and interaction
void initGLUT(int *argcp, char *argv[])
{
  // ask for a window at 0,0 with dimensions winWidth, winHeight 
  // need color, depth (for 3D drawing) and double buffer (smooth display) 
  glutInit(argcp, argv);
  glutInitWindowPosition(0, 0);
  glutInitWindowSize(winWidth, winHeight);
  glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  glutCreateWindow("Vertex and Fragment Shader Tester");

  // set callback functions to be called by GLUT for drawing, window
  // resize, keypress, mouse button press, and mouse movement
  glutDisplayFunc(draw);
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutMouseFunc(mousePress);
  glutMotionFunc(mouseDrag);

  // start shader updates
  glutIdleFunc(updateShaders);
}

// initialize OpenGL - rendering state 
void initGL(char *vsname, char *fsname)
{
    // One front light, yellowish, directional, and from the left
    float lightdir0[4] = {-1,.4,2,0};	// light position: directional if w=0 
    float lightcol0[4] = {.8,.8,.6,1};	// RGBA color for light
    float lightamb0[4] = {.2,.2,.1,1};
    glLightfv(GL_LIGHT0, GL_POSITION, lightdir0);
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb0);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightcol0);
    glEnable(GL_LIGHT0);			// turn on this light 

    // One backlight, dim bluish, positional, and from the right
    float lightdir1[4] = {100,40,20,1};	// light position: directional if w=0 
    float lightcol1[4] = {.1,.1,.4,1};	// RGBA color for light
    float lightamb1[4] = {0,0,0,1};
    glLightfv(GL_LIGHT1, GL_POSITION, lightdir1);
    glLightfv(GL_LIGHT1, GL_AMBIENT, lightamb1);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightcol1);
    glEnable(GL_LIGHT1);			// turn on this light 

    glEnable(GL_LIGHTING);		// turn on use of lighting in general 

    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.);

    // enable some GL features 
    glEnable(GL_DEPTH_TEST);	 // Z-buffer
    glEnable(GL_COLOR_MATERIAL); // map glColor to lighting surface col
    glEnable(GL_NORMALIZE);	 // tell GL to normalize normals

}

int main(int argc, char **argv)
{
    char *vsname=0, *fsname=0;
    int ch;

    // set up GLUT and OpenGL 
    initGLUT(&argc, argv);
    initGL(vsname, fsname);
  

    while ((ch = getopt(argc, argv, "v:f:0:1:2:3:4:5:6:7:")) != -1) {
	switch (ch) {
	case 'v': {
	    // load vertex shader
	    vertInfo.setName(optarg);
	    break;
	}
	case 'f': {
	    // load fragment shader
	    fragInfo.setName(optarg);
	    break;
	}
	case '0': case '1': case '2': case '3': 
	case '4': case '5': case '6': case '7': {
	    // load image
	    loadIMG(optarg,ch-'0');
	    break;
	}
	}

	argc -= optind;
	argc += optind;
    }

    // load shaders before first draw
    updateShaders();

    // let glut take over, it goes into a loop, checking for input and
    // calling the input callbacks, then seeing if we need to draw and
    // calling the draw callback, ad infinitum
    glutMainLoop();
    return 0;             // ANSI C requires main to return int. 
}
