#include "common_header.h"
#include "openGLControl.h"

COpenGLControl::COpenGLControl()
{
	initScene = NULL;
	renderScene = NULL;
	resizeScene = NULL;
	releaseScene = NULL;
}

COpenGLControl::~COpenGLControl()
{
}

bool COpenGLControl::initOpenGL(HWND hWnd, bool (*initScene)(), void (*renderScene)(), void (*resizeScene)(int, int), void(*releaseScene)())
{
	this->hWnd = hWnd;

	hDC = GetDC(hWnd);

	if(hDC == NULL)
	{
		MessageBox(NULL, "GetDC failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	PIXELFORMATDESCRIPTOR pfd;

	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

	pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 32;
	pfd.cDepthBits = 24;
	pfd.iLayerType = PFD_MAIN_PLANE;
 
	int PixelFormat = ChoosePixelFormat(hDC, &pfd);

	if(PixelFormat == 0)
	{
		MessageBox(NULL, "ChoosePixelFormat failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(SetPixelFormat(hDC, PixelFormat, &pfd) == FALSE)
	{
		MessageBox(NULL, "SetPixelFormat failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	hGLRC = wglCreateContext(hDC);

	if(hGLRC == NULL)
	{
		MessageBox(NULL, "wglCreateContext failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(wglMakeCurrent(hDC, hGLRC) == FALSE)
	{
		MessageBox(NULL, "wglMakeCurrent (1) failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(glewInit() != GLEW_OK)
	{
		MessageBox(NULL, "glewInit failed!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	if(WGLEW_ARB_create_context)
	{
		wglDeleteContext(hGLRC);

		int GL33RCAttribs[] =
		{
			WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
			WGL_CONTEXT_MINOR_VERSION_ARB, 3,
			WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
			0
		};

		hGLRC = wglCreateContextAttribsARB(hDC, 0, GL33RCAttribs);

		if(hGLRC == NULL)
		{
			MessageBox(NULL, "wglCreateContextAttribsARB failed!", "Error", MB_OK | MB_ICONERROR);
			return false;
		}

		if(wglMakeCurrent(hDC, hGLRC) == FALSE)
		{
			MessageBox(NULL, "wglMakeCurrent (2) failed!", "Error", MB_OK | MB_ICONERROR);
			return false;
		}
	}
	else
	{
		MessageBox(NULL, "WGL_ARB_create_context not supported!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	this->initScene = initScene;
	this->renderScene = renderScene;
	this->resizeScene = resizeScene;
	this->releaseScene = releaseScene;

	if(WGLEW_EXT_swap_control)
	{
		wglSwapIntervalEXT(0);
	}

	if(initScene != NULL)
	{
		return initScene();
	}

	return true;
}

void COpenGLControl::render()
{
	if(renderScene != NULL)
	{
		renderScene();
	}

	SwapBuffers(hDC);
}

void COpenGLControl::resize(int Width, int Height)
{
	if(resizeScene != NULL)
	{
		resizeScene(Width, Height);
	}
}

void COpenGLControl::releaseOpenGLControl()
{
	if(releaseScene != NULL && GLEW_VERSION_3_3)
	{
		releaseScene();
	}

	wglDeleteContext(hGLRC);
}
