#include <9pm/windows.h>
#include <9pm/u.h>
#include <9pm/libc.h>
#pragma comment( lib, "user32.lib" )

int win_useunicode;

int
win_hasunicode(void)
{
	OSVERSIONINFOA osinfo;
	int r;

	osinfo.dwOSVersionInfoSize = sizeof(osinfo);
	if(!GetVersionExA(&osinfo))
		pm_panic("GetVersionEx failed");
	switch(osinfo.dwPlatformId) {
	default:
		pm_panic("unknown PlatformId");
	case VER_PLATFORM_WIN32s:
		pm_panic("Win32s not supported");
	case VER_PLATFORM_WIN32_WINDOWS:
		r = 0;
		break;
	case VER_PLATFORM_WIN32_NT:
		r = 1;
		break;
	}

	return r;
}

char*
win_wstr2utfn(char *s, int ns, LPCWSTR xr)
{
	int n;
	char *e, *os;
	Rune *r;

	r = (Rune*)xr;
	os = s;
	e = s+ns-1;
	while(s < e){
		n = runelen(*r);
		if(s+n > e)
			break;
		s += runetochar(s, r);
		r++;
	}
	*s = '\0';
	return os;
}

char*
win_wstr2utf(LPCWSTR xr)
{
	char *s;
	int len;
	Rune *r;

	if(xr == nil)
		return nil;
	r = (Rune*)xr;
	len = runenlen(r, runestrlen(r))+1;
	s = malloc(len);
	return win_wstr2utfn(s, len, r);
}

int
win_utf2wstrn(LPWSTR r, DWORD n, char *s)
{
	int len;
	Rune *e, *or;

	len = utflen(s);
	if(len >= n)
		return len;
	or = r;
	e = r+n-1;
	while(r<e && *s){
		s += chartorune(r, s);
		r++;
	}
	*r = '\0';
	return len;
}

LPWSTR
win_utf2wstr(char *s)
{
	Rune *r;
	int len;

	if(s == nil)
		return nil;

	len = utflen(s)+1;
	r = win_malloc(sizeof(Rune)*len);
	win_utf2wstrn(r, len, s);
	return r;
}

void*
win_malloc(int n)
{
	void *a;

	a = malloc(n);
	if(a == nil)
		pm_panic("win_malloc %d failed", n);
	return a;
}

void
win_free(const void *a)
{
	free((void*)a);
}

void
win_convfiledata(WIN32_FIND_DATAW *fdw, WIN32_FIND_DATAA *fda)
{
	/* first fields are the same */
	memcpy(fdw, fda, (uchar*)fdw->cFileName-(uchar*)fdw);
	win_utf2wstrn(fdw->cFileName, sizeof(fdw->cFileName), fda->cFileName);
	win_utf2wstrn(fdw->cAlternateFileName, sizeof(fdw->cAlternateFileName),
			fda->cAlternateFileName);
}
