// 20 april 2015
#include "uipriv_windows.h"

static void appendSeparator(HMENU menu)
{
	if (AppendMenuW(menu, MF_SEPARATOR, 0, NULL) == 0)
		logLastError("error appending separator in appendSeparator()");
}

static void appendTextItem(HMENU menu, const char *text, UINT_PTR *id)
{
	WCHAR *wtext;

	wtext = toUTF16(text);
	if (AppendMenuW(menu, MF_STRING, *id, wtext) == 0)
		logLastError("error appending menu item in appendTextItem()");
	uiFree(wtext);
	(*id)++;
}

static void appendMenuItem(HMENU menu, const uiMenuItem *item, UINT_PTR *id)
{
	switch (item->Type) {
	case uiMenuItemTypeCommand:
	case uiMenuItemTypeCheckbox:
		appendTextItem(menu, item->Name, id);
		return;
	// TODO see if there are stock items for these three
	case uiMenuItemTypeQuit:
		// TODO verify name
		appendSeparator(menu);
		appendTextItem(menu, "Quit", id);
		return;
	case uiMenuItemTypePreferences:
		// TODO verify name
		appendSeparator(menu);
		appendTextItem(menu, "Preferences", id);
		return;
	case uiMenuItemTypeAbout:
		// TODO verify name
		appendSeparator(menu);
		appendTextItem(menu, "About", id);
		return;
	case uiMenuItemTypeSeparator:
		// TODO verify name
		appendSeparator(menu);
		return;
	}
	// TODO complain
}


static HMENU makeMenu(uiMenuItem *items, UINT_PTR *id)
{
	HMENU menu;
	const uiMenuItem *i;

	menu = CreatePopupMenu();
	if (menu == NULL)
		logLastError("error creating menu in makeMenu()");
	for (i = items; i->Type != 0; i++)
		appendMenuItem(menu, i, id);
	return menu;
}

HMENU makeMenubar(void)
{
	HMENU menubar;
	const uiMenu *m;
	WCHAR *wname;
	HMENU menu;
	UINT_PTR id;

	if (options.Menu == NULL)
		complain("asked to give uiWindow a menubar but didn't specify a menu in uiInitOptions");

	menubar = CreateMenu();
	if (menubar == NULL)
		logLastError("error creating menubar in makeMenubar()");

	id = 100;		// start at a safe number
	for (m = options.Menu; m->Name != NULL; m++) {
		wname = toUTF16(m->Name);
		menu = makeMenu(m->Items, &id);
		if (AppendMenuW(menubar, MF_POPUP | MF_STRING, (UINT_PTR) menu, wname) == 0)
			logLastError("error appending menu to menubar in makeMenubar()");
		uiFree(wname);
	}

	return menubar;
}

// this is slow, but it will do for now
// TODO investigate faster options

static const uiMenuItem *lookupID(const uiMenuItem *items, UINT_PTR *cur, UINT_PTR id)
{
	const uiMenuItem *i;

	for (i = items; i->Type != 0; i++) {
		if (i->Type == uiMenuItemTypeSeparator)
			continue;
		if (*cur == id)
			return i;
		(*cur)++;
	}
	return NULL;
}

const uiMenuItem *menuIDToItem(UINT_PTR id)
{
	UINT_PTR cur;
	const uiMenu *m;
	const uiMenuItem *item;

	cur = 100;
	for (m = options.Menu; m->Name != NULL; m++) {
		item = lookupID(m->Items, &cur, id);
		if (item != NULL)
			return item;
	}
	// TODO complain
	return NULL;
}