// Simple GLUT/GL example


#include "draw.h"
#include "view.h"
#include "motion.h"
#include "key.h"
#include "pngtex.h"

#include <GL/glut.h>

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

// initialize OpenGL - rendering state 
void initGL(char *vsname, char *fsname)
{
  float lightdir[4] = {1,1,2,0};	// light position: directional if w=0 
  float white[4] = {1,1,1,1}; 		// RGBA color for light
  float dim[4] = {.2,.2,.2,1};
 
  // 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

  // set up one light for both directional and ambient 
  glLightfv(GL_LIGHT0, GL_AMBIENT, dim);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
  glLightfv(GL_LIGHT0, GL_POSITION, lightdir);
  glEnable(GL_LIGHT0);			// turn on this light 
  glEnable(GL_LIGHTING);		// turn on use of lighting in general 
}

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
	    setVSname(optarg);
	    break;
	}
	case 'f': {
	    // load fragment shader
	    setFSname(optarg);
	    break;
	}
	case '0': case '1': case '2': case '3': 
	case '4': case '5': case '6': case '7': {
	    // load image
	    loadPNG(optarg,ch-'0');
	    break;
	}
	}

	argc -= optind;
	argc += optind;
    }

    // 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. 
}
