#ifndef _OPENGL_HPP_
#define _OPENGL_HPP_

//--------------------------------------------------------------------------------------------
//  Headers
//--------------------------------------------------------------------------------------------

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include "glext.h"
#include "wglext.h"
#include "log.hpp"
#include "enums.hpp"

//--------------------------------------------------------------------------------------------
//  This code belongs to our library namespace: TRACTION_DEMOTRACTOR
//--------------------------------------------------------------------------------------------

namespace TRACTION_DEMOTRACTOR
{
	
//--------------------------------------------------------------------------------------------
//  OpenGL Window class
//--------------------------------------------------------------------------------------------

	class GLWindow
	{	
		friend class GLSystem;

		public:

			GLWindow();
			~GLWindow();

			bool init();		
			bool kill();
			
			bool createWindow();
			bool createWindow(int w, int h, int b, bool screen, bool onTop, int fsaa);

			bool getFullscreen();
			bool getActive();
			unsigned int getWidth();
			unsigned int getHeight();
			HWND getHandle();
			HINSTANCE getInstance();
			HDC getHDC();

			void setPerspective2D();
			void setPerspective2D(int w, int h);
			void setPerspective3D();
			void setWidth(unsigned int w);
			void setHeight(unsigned int h);
			void setBpp(unsigned int b);
			void setZbpp(unsigned int z);
			void setSbpp(unsigned int s);
			void setFullscreen(bool f);
			void setTitle(char *t);
			void setClassName(char *c);
			void setActive(bool a);

			friend LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

		private:

		// Muuttujat jotka osoittavat laajennus funkkareihin //
		///////////////////////////////////////////////////////
		PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
		PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;	

		// Muut muuttujat									 //
		///////////////////////////////////////////////////////
		unsigned int bpp, zbpp, sbpp;		// Bit Depths for buffers
		unsigned int width, height;			// Window width and height
		bool fullscreen;					// Fullscreen flag
		char *title;						// Window name
		char *className;					// Class name for registeration

		int fsaa;							// Fullscreenalias multisamples
		bool onTop;							// Always-on-top 
		bool active;
		bool verticalSyncFlag;				// Flag for Vertical retrace
		int verticalSync;					// Holds the value of vertical retrace (on/off)

		HWND hwnd;
		HINSTANCE hinstance;
		HDC hdc;
		HGLRC hrc;

		// Nämä funktiot eivät näy muille
		///////////////////////////////////////////////////////
		int fetchFSAAMode(HDC hdc,int suggestedFormat, PIXELFORMATDESCRIPTOR p, int requestedmultisamples);
		bool extensionExist(const char *extension);


	};

//--------------------------------------------------------------------------------------------
//  OpenGL System class
//--------------------------------------------------------------------------------------------

	class GLSystem
	{
		friend class GLWindow;

		public:

			GLSystem();
			~GLSystem();

			bool init(int w, int h);
			void resize(int w, int h);
			void loadOMeter(int current, int max);
									
			// Setters
			void setFov(float fov);			
			void setClearColor(float r, float g, float b, float a);					

		private:		

			int width, height;			
	};

/*	
	void checkState();
	void myEnable(int c);
	void myDisable(int c);
	void myBlendFunc(int src, int dst);
*/
}

#endif

/*
bool WGLisExtensionSupported(const char *extension)
{
	const size_t extlen = strlen(extension);
	const char *supported = NULL;

	// Try To Use wglGetExtensionStringARB On Current DC, If Possible
	PROC wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB");

	if (wglGetExtString)
		supported = ((char*(__stdcall*)(HDC))wglGetExtString)(wglGetCurrentDC());

	// If That Failed, Try Standard Opengl Extensions String
	if (supported == NULL)
		supported = (char*)glGetString(GL_EXTENSIONS);

	// If That Failed Too, Must Be No Extensions Supported
	if (supported == NULL)
		return false;

	// Begin Examination At Start Of String, Increment By 1 On False Match
	for (const char* p = supported; ; p++)
	{
		// Advance p Up To The Next Possible Match
		p = strstr(p, extension);

		if (p == NULL)
			return false;						// No Match

		// Make Sure That Match Is At The Start Of The String Or That
		// The Previous Char Is A Space, Or Else We Could Accidentally
		// Match "wglFunkywglExtension" With "wglExtension"

		// Also, Make Sure That The Following Character Is Space Or NULL
		// Or Else "wglExtensionTwo" Might Match "wglExtension"
		if ((p==supported || p[-1]==' ') && (p[extlen]=='\0' || p[extlen]==' '))
			return true;						// Match
	}
}

		
	The next function is the gist of the program itself. Basically, we're going to query if our arb extention is supported on the system. From there, we'll move on to querying our device context to find out the scope of our multisample. Again... let's just jump into the code. 	
		

bool InitMultisample(HINSTANCE hInstance,HWND hWnd,PIXELFORMATDESCRIPTOR pfd)
{  
	// See If The String Exists In WGL!
	if (!WGLisExtensionSupported("WGL_ARB_multisample"))
	{
		arbMultisampleSupported=false;
		return false;
	}

	// Get Our Pixel Format
	PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
		(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");

	if (!wglChoosePixelFormatARB)
	{
		// We Didn't Find Support For Multisampling, Set Our Flag And Exit Out.
		arbMultisampleSupported=false;
		return false;
	}

	// Get Our Current Device Context. We Need This In Order To Ask The OpenGL Window What Attributes We Have
	HDC hDC = GetDC(hWnd);

	int pixelFormat;
	bool valid;
	UINT numFormats;
	float fAttributes[] = {0,0};

	// These Attributes Are The Bits We Want To Test For In Our Sample
	// Everything Is Pretty Standard, The Only One We Want To 
	// Really Focus On Is The SAMPLE BUFFERS ARB And WGL SAMPLES
	// These Two Are Going To Do The Main Testing For Whether Or Not
	// We Support Multisampling On This Hardware
	int iAttributes[] = { WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
		WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
		WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
		WGL_COLOR_BITS_ARB,24,
		WGL_ALPHA_BITS_ARB,8,
		WGL_DEPTH_BITS_ARB,16,
		WGL_STENCIL_BITS_ARB,0,
		WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
		WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
		WGL_SAMPLES_ARB, 4 ,						// Check For 4x Multisampling
		0,0};

	// First We Check To See If We Can Get A Pixel Format For 4 Samples
	valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
 
	// if We Returned True, And Our Format Count Is Greater Than 1
	if (valid && numFormats >= 1)
	{
		arbMultisampleSupported	= true;
		arbMultisampleFormat	= pixelFormat;	
		return arbMultisampleSupported;
	}

	// Our Pixel Format With 4 Samples Failed, Test For 2 Samples
	iAttributes[19] = 2;
	valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
	if (valid && numFormats >= 1)
	{
		arbMultisampleSupported	= true;
		arbMultisampleFormat	= pixelFormat;	 
		return arbMultisampleSupported;
	}
	  
	// Return The Valid Format
	return  arbMultisampleSupported;
}
*/