#include <init.h>
#include <input.h>
#include <shader.h>

// global: light 0 position vector
GLfloat l0pos[4] = {1, 0.5, 1, 0};

// global: eye point vector
GLfloat eye[3] = {0.0, 2.0, 5.0};
// global: camera center vector
GLfloat cnt[3] = {0.0, 0.0, 0.0};
// scene rotation angle
int rot;

void initGL(int argc, char *argv[]) {

    // initialize glut
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(10, 10);
    glutInitWindowSize(800, 600);
    glutCreateWindow("gltut");

    // set global states 
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.0, 0.0, 0.0, 1.0);

    // init GLew
    GLenum err = glewInit();
    if (err != GLEW_OK) {
        ERR("glewInit returned err: " << glewGetErrorString(err));
    } else {
        LOG("using GLEW version: " << glewGetString(GLEW_VERSION));
    }

    // set callbacks
    glutDisplayFunc(renderScene);
    glutIdleFunc(renderScene);
    glutReshapeFunc(resize);
    glutKeyboardFunc(handleKey);   
}

void resize(int w, int h) {
    // calc width/height ratio
    float ratio = 1.0* w / h;

    // set matrix mode
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // set new viewport and perspective
    glViewport(0, 0, w, h);
    gluPerspective(45, ratio, 1, 1000);

    // restore matrix mode
    glMatrixMode(GL_MODELVIEW);
}

void renderScene() {
    // clear buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // load identity matrix into modelview matrix
    glLoadIdentity();
    // position camera
    gluLookAt(eye[0], eye[1], eye[2],
              cnt[0], cnt[1], cnt[2],
              0.0f,   1.0f,   0.0f);

    // init a light source
    glLightfv(GL_LIGHT0, GL_POSITION, l0pos);

    // bind shaders
    bindShaders();

    // send time information to shaders
    sendTime();

    // rotate scene
    glRotatef(rot, 0.0f, 1.0f, 0.0f);

    // draw the teapot
    glutSolidTeapot(1);

    // swap back and framebuffer
    glutSwapBuffers();
}

