// Windows utilities

internal Str8 Win32_WideStr(M_Arena *arena, Str8 v) {
	Str8 result = { 0 };

	S32 nchars = MultiByteToWideChar(CP_UTF8, 0, (LPCCH) v.data, (int) v.count, 0, 0) + 1;
	U64 nbytes = nchars << 1;

	result.count = nbytes - 2; // -2 because we don't include the null-terminator in the count
	result.data  = M_ArenaPush(arena, U8, .count = nbytes);

	MultiByteToWideChar(CP_UTF8, 0, (LPCCH) v.data, (int) v.count, (LPWSTR) result.data, nchars);

	return result;
}

internal Str8 Win32_MultiByteStr(M_Arena *arena, LPWSTR wstr) {
	Str8 result = { 0 };

	S32 nbytes = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);

	result.count = nbytes - 1;
	result.data  = M_ArenaPush(arena, U8, .count = nbytes);

	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, (LPSTR) result.data, nbytes, 0, 0);

	return result;
}

// Virtual memory

U64 VM_PageSize() {
	SYSTEM_INFO info;
	GetSystemInfo(&info);

	U64 result = info.dwPageSize;
	return result;
}

U64 VM_AllocationGranularity() {
	SYSTEM_INFO info;
	GetSystemInfo(&info);

	U64 result = info.dwAllocationGranularity;
	return result;
}

void *VM_Reserve(U64 size) {
	void *result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS);
	return result;
}

B32 VM_Commit(void *base, U64 size) {
	B32 result = VirtualAlloc(base, size, MEM_COMMIT, PAGE_READWRITE) != 0;
	return result;
}

void VM_Decommit(void *base, U64 size) {
	VirtualFree(base, size, MEM_DECOMMIT);
}

void VM_Release(void *base, U64 size) {
	(void) size;

	VirtualFree(base, 0, MEM_RELEASE);
}

#include "filesystem.c"
