#include "GL/glut.h"
#include "GL/gl.h"

#include "displayers.h"
#include "DataHandling/Texture.h"
#include "DataHandling/Model3D.h"


volatile unsigned long long int timer_ticks = 0;
static Texture tree_texture;
static Model3D raptor;
static Texture raptor_texture;

void display()
{
    float angleY = 1*timer_ticks;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    // Prepare view
    glLoadIdentity();
    gluPerspective(60,(double)glutGet(GLUT_WINDOW_WIDTH)/(double)glutGet(GLUT_WINDOW_HEIGHT),10,30000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(7.5, 7.5, 7.5,
              0, 0, 1,
              0, 1, 0);


    display_rotating_pyramid(-5,-2,-5,2,4,angleY);
    display_rotating_pyramid(5,-2,0,1,5,angleY);
    display_rotating_pyramid(-2,-2,4,3,2,angleY);

    display_tree(0,-5,0,3,5,tree_texture);

    glPushMatrix();
    glRotatef(angleY,0,-1,0);
    raptor.draw_model();
    glPopMatrix();

    glutSwapBuffers();
}

void update_angle(int value)
{
    timer_ticks++;
    glutTimerFunc(50,update_angle,0);
}

int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    // Generate window with GLUT
    glutInitDisplayMode(GLUT_RGB| GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow("Hello");

    // Init OpenGL
    glClearColor(0,0,0,1);
    glClearDepth(1.0);
//    glEnable(GL_LIGHTING);
//    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);

    // Setup OPenGL to use textures
    glEnable(GL_TEXTURE_2D);
    glAlphaFunc(GL_GREATER, 0.5);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT/GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT/GL_CLAMP);
    glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    // Load and generate tree texture
    tree_texture.load_rgba_tga("resources/arbre.tga","resources/arbre_masque.tga");
    glGenTextures(1,tree_texture.opengl_id);
    // TODO : Put in the Texture class
    glBindTexture(GL_TEXTURE_2D,tree_texture.opengl_id[0]);
    gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8,tree_texture.width,tree_texture.height,GL_RGBA,GL_UNSIGNED_BYTE,tree_texture.image_data);

    // Load and generate raptor texture
    raptor_texture.load_rgb_tga("resources/RAPTOR.tga");
    glGenTextures(1, raptor_texture.opengl_id);
    // TODO : Put in the Texture class
    glBindTexture(GL_TEXTURE_2D, raptor_texture.opengl_id[0]);
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, raptor_texture.width, raptor_texture.height, GL_RGB, GL_UNSIGNED_BYTE, raptor_texture.image_data);


    raptor.load_ascii_off_file("resources/RAPTOR.off");
    raptor.assign_texture(raptor_texture);
    raptor.set_scaling(0.01,0.01,0.01);
    raptor.set_rotation(-90,1,0,0);

    glViewport(0,0,glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));

    glutIdleFunc(display);
    glutTimerFunc(50,update_angle,0);

    // Enters main loop, managed by GLUT
    glutMainLoop();
	return 0;
}
