#include <qubit/platform/platform.h>
#include <qubit/platform/platform_winapi.h>

#include <stdbool.h>

#include <windows.h>
#include <glad/wgl.h>

#include <qubit/qubit.h>

struct platform_context {
	HDC device_context;
	HGLRC opengl_context;
};

static struct platform_context _context;

void
platform_opengl_setup(void)
{
	gladLoaderLoadGL();
	if (GLAD_GL_VERSION_4_0 == false) {
		// TODO: Error
		qb_log_error("Failed to load GL.");
		qb_abort("Failed to load GL.");
	}
}

void
platform_opengl_terminate(void)
{
}

void
platform_opengl_extension_setup(void)
{
	gladLoaderLoadWGL(_context.device_context);
	if (GLAD_WGL_VERSION_1_0 == false) {
		// TODO: Error
	}
}

void
platform_opengl_extension_terminate(void)
{
}

void
platform_opengl_context_create(void)
{
	const PIXELFORMATDESCRIPTOR pfd_sbuf = {
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
		PFD_TYPE_RGBA,
		32,
		0, 0, 0, 0, 0, 0,
		0,
		0,
		0,
		0, 0, 0, 0,
		24,
		8,
		0,
		PFD_MAIN_PLANE,
		0,
		0, 0, 0
	};

	const PIXELFORMATDESCRIPTOR pfd_dbuf = {
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		32,
		0, 0, 0, 0, 0, 0,
		0,
		0,
		0,
		0, 0, 0, 0,
		24,
		8,
		0,
		PFD_MAIN_PLANE,
		0,
		0, 0, 0
	};

	const int context_attribs[] = {
		WGL_CONTEXT_MAJOR_VERSION_ARB, PLATFORM_GL_VERSION_MAJOR,
		WGL_CONTEXT_MINOR_VERSION_ARB, PLATFORM_GL_VERSION_MINOR,
		WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
		None,
	};

	int pixel_format_id;
	// TODO: More thorough checking of supported extensions
	if (GLAD_WGL_ARB_create_context == 0 || 
		GLAD_WGL_ARB_create_context_profile == 0) {
		// TODO: Error
		abort();
	}

	// makecontextcorrentarb
	if (GLAD_WGL_ARB_make_current_read == 0) {
		
	}

// TODO: Replace with wgl calls

	_context.device_context = GetDC(_context_data.window);
	if (_context.device_context == NULL) {
		// TODO: Error
	}
	pixel_format_id = ChoosePixelFormat(_context.device_context, &pfd_dbuf);
	if (pixel_format_id == 0) {
		pixel_format_id = ChoosePixelFormat(_context.device_context, &pfd_sbuf);
		if (pixel_format_id == 0) {
			// TODO: Error
		}

		// TODO: Log single buffer pixel format
	}

	if (SetPixelFormat(_context.device_context, pixel_format_id, &pfd_dbuf) == FALSE) {
		// TODO: Error
	}

	_context.opengl_context = wglCreateContextAttribsARB(_context.device_context, None, 
		context_attribs);
	if (_context.opengl_context == NULL) {
		// TODO: Error
	}

	wglMakeContextCurrentARB(_context.device_context, _context.device_context,
		_context.opengl_context);
}

void
platform_opengl_context_destroy(void)
{
	wglMakeContextCurrentARB(_context.device_context, _context.device_context,
		NULL);
	wglDeleteContext(_context.opengl_context);
	DeleteDC(_context.device_context);
}

void
platform_opengl_swap_buffers(void)
{
	SwapBuffers(_context.device_context);
}