#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "fontutils.h"
#include "miscutils.h"
#include "menu.h"

#define max(a,b) ((a)>(b)?(a):(b))

void
vga_popupmenu(vga_menu_t *menu, int x, int y, int fg, int bg, font_t *font, mouse_hs_t hs[], vga_win *win) {
	int i, n, fw, cur_y;
	char *cursave,  c;
	int cur_sel = 0;
	vga_win localwin = { 0, 0, 0, 0, 0 };

	fw = 8;
	for (i=0; (menu+i)->name; i++) {
		if (*((menu+i)->name)) {
			localwin.wid = max(localwin.wid,
					   fw*strlen((menu+i)->name));
			localwin.ht += font->font_height;
		} else
			localwin.ht += 3;
	}

	/* Because scanline start and lengths must be multiples of 8 */
	if (x % 8)
		x = (x >> 3) << 3;

	localwin.x = x;
	localwin.y = y;
	localwin.wid += 16;
	localwin.ht += 4;
	vga_save_win(&localwin);
#if 0
	vga_drawbox(x,y,localwin.wid,localwin.ht,bg,FILLED|RAISED);
#else
	vga_box(x,y,localwin.wid,localwin.ht,fg,bg,FILLED|BOXED);
#endif

	vga_setcolor(fg);

	for (i=0, cur_y = y+2, n = 0; (menu+i)->name; i++)
		if (*((menu+i)->name)) {
			if (hs) {
				hs[n].x1=x;
				hs[n].y1=cur_y;
				hs[n].x2=hs[n].x1+localwin.wid;
				hs[n].y2=hs[n].y1+font->font_height;
				hs[n].func = (menu+i)->func;
				n++;
			}
			vga_write((char *)(menu+i)->name, x + 8, cur_y, font, fg, bg, ALIGN_LEFT);
			cur_y+=font->font_height;
		} else {
			vga_setcolor(fg);
			vga_drawline(x+2, cur_y+1, x+localwin.wid-3, cur_y+1);
			cur_y+=3;
		}

	cur_y = y+2;
	i = 0;

	if (win) {
		win->x = localwin.x;
		win->y = localwin.y;
		win->wid = localwin.wid;
		win->ht = localwin.ht;
		win->data = localwin.data;
		return;
	}

	cursave = malloc (localwin.wid * font->font_height);
	for (n = 0; n <= font->font_height; n++)
		vga_getscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);
	for (n=0; n<localwin.wid * font->font_height; n++)
		cursave[n] = cursave[n] == bg ? fg : cursave[n] == fg ? bg : cursave[n];
	for (n = 0; n <= font->font_height; n++)
		vga_drawscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);

	while (c=getchar() != 'q' && c != 27) {
		for (n=0; n<localwin.wid * font->font_height; n++)
			cursave[n] = cursave[n] == bg ? fg : cursave[n] == fg ? bg : cursave[n];
		for (n = 0; n <= font->font_height; n++)
			vga_drawscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);

		i++;
		if (!(menu+i)->name) {
			cur_y = y+2;
			i = 0;
			for (n = 0; n <= font->font_height; n++)
				vga_getscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);
			for (n=0; n<localwin.wid * font->font_height; n++)
				cursave[n] = cursave[n] == bg ? fg : cursave[n] == fg ? bg : cursave[n];
			for (n = 0; n <= font->font_height; n++)
				vga_drawscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);
			continue;
		}
		if (*((menu+i)->name))
			cur_y+=font->font_height;
		else
			i++, cur_y+=3+font->font_height;

		for (n = 0; n <= font->font_height; n++)
			vga_getscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);
		for (n=0; n<localwin.wid * font->font_height; n++)
			cursave[n] = cursave[n] == bg ? fg : cursave[n] == fg ? bg : cursave[n];
		for (n = 0; n <= font->font_height; n++)
			vga_drawscansegment (cursave + n * localwin.wid, x, cur_y + n, localwin.wid);
	}
	free (cursave);
	vga_restore_win(&localwin);
}
