#ifndef GLFUNCS_H
#define GLFUNCS_H

#include <stdio.h>
#include <stdlib.h>
#include <string>

#include "SDL.h"
#include "SDL_image.h"
#include "SDL_opengl.h"
#include "SDL_syswm.h"

class glfuncs
{
public:
	static glfuncs* instance();

	void(APIENTRY*glBegin)(GLenum);
	void(APIENTRY*glEnd)();
	void(APIENTRY*glVertex3f)(GLfloat, GLfloat, GLfloat);
	void(APIENTRY*glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat);
	void(APIENTRY*glClear)(GLbitfield);
	void(APIENTRY*glDisable)(GLenum);
	void(APIENTRY*glEnable)(GLenum);
	void(APIENTRY*glColor4ub)(GLubyte,GLubyte,GLubyte,GLubyte);
	void(APIENTRY*glPointSize)(GLfloat);
	void(APIENTRY*glHint)(GLenum,GLenum);
	void(APIENTRY*glBlendFunc)(GLenum,GLenum);
	void(APIENTRY*glMatrixMode)(GLenum);
	void(APIENTRY*glLoadIdentity)();
	void(APIENTRY*glOrtho)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
	void(APIENTRY*glRotatef)(GLfloat,GLfloat,GLfloat,GLfloat);
	void(APIENTRY*glViewport)(GLint,GLint,GLsizei,GLsizei);
	void(APIENTRY*glFogf)(GLenum,GLfloat);
	void(APIENTRY*glGenTextures)(GLsizei,GLuint*);
	void(APIENTRY*glBindTexture)(GLenum,GLuint);
	void(APIENTRY*glTexParameteri)(GLenum,GLenum,GLint);
	void(APIENTRY*glTexImage2D)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid *);
	void(APIENTRY*glColor3f)(GLfloat,GLfloat,GLfloat);
	void(APIENTRY*glVertex2f)(GLfloat,GLfloat);
	void(APIENTRY*glTexCoord2f)(GLfloat,GLfloat);
	void(APIENTRY*glTexEnvf)(GLenum,GLenum,GLfloat);
	void(APIENTRY*glColor4f)(GLfloat,GLfloat,GLfloat,GLfloat);
	void(APIENTRY*glDepthMask)(GLboolean);
	void(APIENTRY*glClearDepth)(GLclampd);
	void(APIENTRY*glDepthFunc)(GLenum);
	void(APIENTRY*glShadeModel)(GLenum);
	void(APIENTRY*glFinish)();
	GLuint(APIENTRY*glGenLists)(GLsizei);
	void(APIENTRY*glDeleteLists)(GLuint,GLsizei);
	void(APIENTRY*glPopAttrib)();
	void(APIENTRY*glCallLists)(GLsizei,GLenum,const GLvoid*);
	void(APIENTRY*glListBase)(GLuint);
	void(APIENTRY*glPushAttrib)(GLbitfield);
	void(APIENTRY*glRasterPos2f)(GLfloat,GLfloat);
	void(APIENTRY*glGetBooleanv)(GLenum, GLboolean *);
	void(APIENTRY*glEndList)();
	void(APIENTRY*glTranslated)(GLdouble,GLdouble,GLdouble);
	void(APIENTRY*glNewList)(GLuint,GLenum);
	void(APIENTRY*glVertex2i)(GLint,GLint);
	void(APIENTRY*glPopMatrix)();
	void(APIENTRY*glPushMatrix)();
	void(APIENTRY*glDeleteTextures)(GLsizei, const GLuint *);

	void(APIENTRY*wglUseFontBitmapsA)(HDC,long,long,long);

	GLuint buildFont(double scale, double width, double height, int fontTexture);
	GLvoid killFont();
	GLvoid glPrint(GLint x, GLint y, std::string text, bool small=false);

	
	GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord);
	int loadTexture(std::string filename, GLfloat coords[4], SDL_Rect & rect);
	
	static SDL_Surface *load_image( std::string filename );
	static int power_of_two(int input);
	static bool intersect(SDL_Rect &A, SDL_Rect &B, int*x = NULL , int*y = NULL);
	static bool intersectX(SDL_Rect &A, SDL_Rect &B, int* x = NULL);
	static bool intersectY(SDL_Rect &A, SDL_Rect &B, int* y = NULL);

private:
	GLuint _bigBase;
	GLuint _smallBase;
	GLuint _bigFont;
	GLuint _smallFont;

	glfuncs();
	static glfuncs* _instance;
	void* get_funcaddr(const char* p);
	void init_glfuncs();

};

#endif