#include "Screen.h"
#include "Object.h"
#include "CommandManager.h"

#include <iostream>

using namespace std;

int Screen::HEIGHT = 800;
int Screen::WIDTH = 300;

Screen* Screen::_instance = NULL;

Screen::Screen()
:_followMe(NULL)
{
	_screen.h = HEIGHT;
	_screen.w = WIDTH;
	_screen.x = 0;
	_screen.y = 0;

	_center.h = HEIGHT/3.0;
	_center.w = WIDTH/3.0;
	_center.x = WIDTH/3.0;
	_center.y = HEIGHT/3.0;

	#if defined(_WIN32)
	char *gl_library = "OpenGL32.DLL";
#elif defined(__QNXNTO__)
	char *gl_library = "libGL.so.3";
#else
	char *gl_library = "libGL.so.1";
#endif
	
	
	if (SDL_Init(SDL_INIT_VIDEO)<0)
	{
		printf("Unable to init SDL : %s\n",SDL_GetError());
		exit(1);
	}

	atexit(SDL_Quit);
	
	if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1)<0)
	{
		printf("Unable to set GL attribute : %s\n",SDL_GetError());
		exit(1);
	}
	
	if (SDL_GL_LoadLibrary(gl_library)<0)
	{
		printf("Unable to dynamically open GL lib : %s\n",SDL_GetError());
		exit(1);
	}

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);

	if (SDL_SetVideoMode(_screen.w,_screen.h,32,SDL_OPENGL)==NULL)
	{
		printf("Unable to open video mode : %s\n",SDL_GetError());
		exit(1);
	}

	/* Set the window manager title bar */
	SDL_WM_SetCaption( "SDL Dynamic OpenGL Loading Test", "testdyngl" );

	glfuncs::instance()->glViewport(0,0,_screen.w,_screen.h);
	glfuncs::instance()->glMatrixMode(GL_PROJECTION);
	glfuncs::instance()->glLoadIdentity();

	glfuncs::instance()->glOrtho(0.0f, _screen.w, _screen.h, 0.0f, -1.0f, 1.0f);
		
	glfuncs::instance()->glMatrixMode(GL_MODELVIEW);
	glfuncs::instance()->glLoadIdentity();

	glfuncs::instance()->glClearColor(0.0f,0.0f,0.0f,0.5f);
	glfuncs::instance()->glClearDepth(1.0f);
	glfuncs::instance()->glDepthFunc(GL_LEQUAL);	
	glfuncs::instance()->glEnable(GL_DEPTH_TEST);
	glfuncs::instance()->glShadeModel(GL_SMOOTH);
	glfuncs::instance()->glDisable(GL_CULL_FACE);
	glfuncs::instance()->glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	glfuncs::instance()->glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	glfuncs::instance()->glEnable( GL_BLEND );

	glfuncs::instance()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glfuncs::instance()->glEnable(GL_TEXTURE_2D);
}

Screen* Screen::instance()
{
	if(!_instance)
		_instance = new Screen();
	return _instance;
}

void Screen::drawLevel(int texture, GLfloat texCoords[4], SDL_Rect quad)
{
	if(glfuncs::intersect(quad,_screen)) {
		int x1 = quad.x - _screen.x;
		int x2 = x1 + quad.w;
		int y1 = quad.y - _screen.y;
		int y2 = y1 + quad.h;

		glfuncs::instance()->glBindTexture(GL_TEXTURE_2D, texture);
		glfuncs::instance()->glBegin(GL_QUADS);
		glfuncs::instance()->glTexCoord2f(texCoords[0],texCoords[1]);	glfuncs::instance()->glVertex2f(x1,y1);
		glfuncs::instance()->glTexCoord2f(texCoords[2],texCoords[1]);	glfuncs::instance()->glVertex2f(x2,y1);
		glfuncs::instance()->glTexCoord2f(texCoords[2],texCoords[3]);	glfuncs::instance()->glVertex2f(x2,y2);
		glfuncs::instance()->glTexCoord2f(texCoords[0],texCoords[3]);	glfuncs::instance()->glVertex2f(x1,y2);
		glfuncs::instance()->glEnd();
	}
}

void Screen::drawScreen(int texture, GLfloat texCoords[4], SDL_Rect quad)
{
	int x1 = quad.x;
	int x2 = x1 + quad.w;
	int y1 = quad.y;
	int y2 = y1 + quad.h;

	glfuncs::instance()->glBindTexture(GL_TEXTURE_2D, texture);
	glfuncs::instance()->glBegin(GL_QUADS);
	glfuncs::instance()->glTexCoord2f(texCoords[0],texCoords[1]);	glfuncs::instance()->glVertex2f(x1,y1);
	glfuncs::instance()->glTexCoord2f(texCoords[2],texCoords[1]);	glfuncs::instance()->glVertex2f(x2,y1);
	glfuncs::instance()->glTexCoord2f(texCoords[2],texCoords[3]);	glfuncs::instance()->glVertex2f(x2,y2);
	glfuncs::instance()->glTexCoord2f(texCoords[0],texCoords[3]);	glfuncs::instance()->glVertex2f(x1,y2);
	glfuncs::instance()->glEnd();
}

void Screen::drawCutScene(std::string cutSceneText)
{
	//glfuncs::instance()->glDisable(GL_TEXTURE_2D);


	glfuncs::instance()->glColor4f(0,0,0,1);
	
	glfuncs::instance()->glBegin(GL_QUADS);
	glfuncs::instance()->glVertex2f(0,0);
	glfuncs::instance()->glVertex2f(_screen.w,0);
	glfuncs::instance()->glVertex2f(_screen.w,_screen.h/CSFRAC);
	glfuncs::instance()->glVertex2f(0,_screen.h/CSFRAC);
	glfuncs::instance()->glEnd();

	glfuncs::instance()->glBegin(GL_QUADS);
	glfuncs::instance()->glVertex2f(0,_screen.h-_screen.h/CSFRAC);
	glfuncs::instance()->glVertex2f(_screen.w,_screen.h-_screen.h/CSFRAC);
	glfuncs::instance()->glVertex2f(_screen.w,_screen.h);
	glfuncs::instance()->glVertex2f(0,_screen.h);
	glfuncs::instance()->glEnd();

	glfuncs::instance()->glColor4f(1,1,1,1);

	//glfuncs::instance()->glRasterPos2f(100,_screen.h-_screen.h/CSFRAC + 20);
	glfuncs::instance()->glPrint(100,_screen.h-_screen.h/CSFRAC + 6,cutSceneText);

	//glfuncs::instance()->glEnable(GL_TEXTURE_2D);
}

void Screen::drawText(std::string text, int x, int y)
{
	y -= 14;
	//glfuncs::instance()->glEnable(GL_TEXTURE_2D);
	

	glfuncs::instance()->glColor4f(0,0,0,1);

	//glfuncs::instance()->glRasterPos2f(x,y);
	glfuncs::instance()->glPrint(x,y,text, true);

	glfuncs::instance()->glColor4f(1,1,1,1);

}

void Screen::registerFollowObj(Object * o)
{
	_followMe = o;
}

void Screen::move(int x, int y)
{
	_screen.y += y;
	_screen.x += x;
	_center.y += y;
	_center.x += x;
}


void Screen::update()
{
	if( _followMe == NULL )
		return;

	SDL_Rect follow = _followMe->getBox();

	int x,y;
	if(!glfuncs::intersectX(follow,_center,&x))
		move(x,0);
	if(!glfuncs::intersectY(follow,_center,&y))
		move(0,y);
}

