HINSTANCE win32_instance = {0};
pPlatformWindow win32_window = {0};
b32 global_quit = false;

LRESULT CALLBACK WindowProc(HWND window, UINT message, WPARAM w_param, LPARAM l_param)
{
	LRESULT result = 0;

	switch (message)
	{
		case WM_SIZE: 
			{
				Printfln("Window resizing");
				win32_window.w = LOWORD(l_param);
				win32_window.h = HIWORD(l_param);
				rResolutionSet(win32_window.w, win32_window.h);
			}	break;
		case WM_DESTROY: // TODO(MA): Probably handle these separately but for now, they're together
		case WM_CLOSE:
			{
				Printf("quitting");
				global_quit = true;
			} break;
		case WM_ACTIVATEAPP:
			{
				OutputDebugStringA("WM_ACTIVATEAPP\n");
			} break;
		default:
			{
				result = DefWindowProc(window, message, w_param, l_param);
			} break;
	}

	return result;
}

b32 pLibraryLoad(const char *name, pLibrary *out_lib)
{
	b32 success = true;

	out_lib->module = LoadLibraryA("vulkan-1.dll");
	if (!out_lib->module)
		success = false;

	return success;
}

b32 pFunctionLoad(const char *name, pLibrary *lib, pFunction *out_fn)
{
	b32 success = true;

	out_fn->fn = GetProcAddress(lib->module, name);
	if (!out_fn->fn)
		success = false;

	return success;
}

usize pPageSize()
{
	return 0;
}

i32 _Write(void const *str, DWORD std_handle)
{
	DWORD written;
	BOOL success = WriteFile(GetStdHandle(std_handle), str, StrLen(str), &written, NULL);
	return success ? (i32)written : -1;
}

b32 pWindowInit(const char *window_name)
{
	b32 success = true;

	WNDCLASS window_class = {
		.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW,
		.lpfnWndProc = WindowProc,
		.hInstance = win32_instance,
		.lpszClassName = WINDOW_CLASS_NAME,
	};

	ATOM r_class_atom = RegisterClass(&window_class);
	if (!r_class_atom)
		success = false;

	if (success)
	{
		HWND window_handle = CreateWindowExA(
			0,
			window_class.lpszClassName,
			window_name,
			WS_OVERLAPPEDWINDOW|WS_VISIBLE,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			0,
			0,
			win32_instance,
			0
		);

		if (!window_handle)
			success = false;
		else
			win32_window.handle = window_handle;
	}

	return success;
}

pPlatformWindow *pWindowGet()
{
	return &win32_window;
}

void pWindowEventsGet()
{
	BOOL has_msg = false;
	MSG message;
	do 
	{
		has_msg = PeekMessage(&message, 0, 0, 0, PM_REMOVE);
		if (has_msg > 0)
		{
			TranslateMessage(&message);
			DispatchMessage(&message);
		}
	}
	while (has_msg);
}

void pWindowEventWaitFor()
{
	MSG message;
	BOOL message_result = GetMessageA(&message, 0, 0, 0);
	if (message_result > 0)
	{
		TranslateMessage(&message);
		DispatchMessage(&message);
	}
}

b32 pWindowShouldQuit()
{
	return global_quit;
}

pWindowSize pWindowGetSize()
{
	return (pWindowSize){ .w = win32_window.w, .h = win32_window.h };
}

// ::Platform::Windows::Includes::CFile::

#include "platform_windows_public.c"

