#include <string>
#include <iostream>
#include <GL/glew.h>
#include <GL/glfw.h>
#include "opengl31engine.h"
#include "engine_structs.h"
#include "structures.h"
#define LOG_INFO std::cerr

int init()
{

	int w = 1280;
	int h = 800;
	bool DoubleBuffer = true;;
	bool FullScreen = false;
	bool _mouse_ = true;
	std::string _caption_ = "magic3d_test";
	GLint _max_element_vertices_;
	GLint _max_element_indeces_;
	GLint _max_point_size_;

	LOG_INFO << "w\t=" << w << std::endl;
	LOG_INFO << "h\t=" << h << std::endl;
	LOG_INFO << "_DoubleBuffer_\t=" << DoubleBuffer << std::endl;
	LOG_INFO << "FullScreen\t=" << FullScreen << std::endl;

	if ( glfwInit() != GL_TRUE ) return false;
	int ret;
	ret = glfwOpenWindow ( w, h, 8, 8, 8, 8, 0, 0, ( FullScreen ) ? GLFW_FULLSCREEN : GLFW_WINDOW );
	if ( ret != GL_TRUE ) return false;
	glfwSetWindowTitle ( _caption_.c_str() );
	if ( !_mouse_ ) glfwDisable ( GLFW_MOUSE_CURSOR );
	glfwEnable ( GLFW_KEY_REPEAT );
	GLenum err = glewInit();
	if ( err != GLEW_OK )
	{
		LOG_INFO<<"Error init glew: "<< glewGetErrorString ( err ) <<std::endl;
		return false;
	}

	GLint texts;
	glGetIntegerv ( GL_MAX_TEXTURE_SIZE, &texts );
	LOG_INFO << "OpenGL info:" << std::endl <<
	"OpenGL version: " << glGetString ( GL_VERSION ) << std::endl <<
	"Vendor:: " << glGetString ( GL_VENDOR ) << std::endl <<
	"Supported Extesions: " << glGetString ( GL_EXTENSIONS ) << std::endl <<
//	"Shading Language Version: " << glGetString( GL_SHADING_LANGUAGE_VERSION ) << std::endl <<
	"Renderer info: " << glGetString ( GL_RENDERER ) << std::endl;
	LOG_INFO << "MaxTextureSize " << texts << std::endl;
	glGetIntegerv ( GL_MAX_ELEMENTS_VERTICES, ( GLint* ) & _max_element_vertices_ );
	glGetIntegerv ( GL_MAX_ELEMENTS_INDICES, ( GLint* ) & _max_element_indeces_ );
	glGetIntegerv ( GL_POINT_SIZE_MAX_ARB, ( GLint* ) & _max_point_size_ );
	LOG_INFO << "MaxPointSize " << _max_point_size_ << std::endl;
	LOG_INFO << "Max element vertices " << _max_element_vertices_ << std::endl;
	LOG_INFO << "Max element indeces " << _max_element_indeces_ << std::endl;

	glClearColor ( 0, 0, 0, 0 );
	glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glEnable ( GL_DEPTH_TEST );
	glEnable ( GL_TEXTURE_2D );
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glShadeModel ( GL_SMOOTH );

	glViewport ( 0, 0, ( GLsizei ) ( w ), ( GLsizei ) ( h ) );


	glMatrixMode ( GL_PROJECTION );
	glPushMatrix ();
	glLoadIdentity ();
	gluPerspective (60.*(10./16.) ,16.0 / 10.0, 0.1, 10000 );
	glMatrixMode ( GL_MODELVIEW );
	glPushMatrix ();
	glLoadIdentity ();
/*	    GLfloat light_pos[4] = {0, 0, 0, 0.0};
	    glEnable (GL_LIGHTING);
	    glEnable (GL_LIGHT0);
	glLightfv (GL_LIGHT0, GL_POSITION, light_pos);*/
	
	/*
	    glMatrixMode (GL_PROJECTION);
	    glLoadIdentity ();
	    gluPerspective (60.*(9.0/16.0),16.0/9.0, 1, 200);
	    glMatrixMode (GL_MODELVIEW);
	    glLoadIdentity ();
	*/

	return 0;
}

void draw()
{
	M3D::OpenGL31Engine engine;
	M3D::EngineLimits limits;
        limits.camera_count = 10;
        limits.indeces_count = 10000;
        limits.mesh_count = 1000;
        limits.model_count = 1000;
        limits.shader_count = 100;
        limits.texture_count = 1000;
        limits.texture_size = 4096;
        limits.vertices_count = 1024 * 1024;

	engine.set_limits ( limits );
	engine._init_(1280, 800, 60.);
	std::cerr<<"Engine inited"<<std::endl;
//	M3D::ObjectId obj=engine.load_object ( "res/cube.object", M3D::OpenGL31Engine::OBJECT_DYNAMIC );
	M3D::ModelInterface obj= engine.create_model();
	obj.load ( "res/colastr1co.object" );
	engine.add_model ( obj );
	while ( !glfwGetKey ( GLFW_KEY_ESC ) && glfwGetWindowParam ( GLFW_OPENED ) )
	{
		glMatrixMode ( GL_MODELVIEW );//сменим матрицу на всякий случай
		glPushMatrix();
		glLoadIdentity();
		
		gluLookAt ( 0, 0, 0, 0, 0, 1, 0, 1, 0 );

		engine.draw();
                
		glPopMatrix();
		glfwSwapBuffers();
		glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	}
}
int main()
{
	init();
	draw();
	glfwTerminate();
}
