#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

enum
{
	Margin = 4,		/* outside to text */
	Border = 2,		/* outside to selection boxes */
	Blackborder = 2,	/* width of outlining border */
	Vspacing = 2,		/* extra spacing between lines of text */
	Maxunscroll = 25,	/* maximum #entries before scrolling turns on */
	Nscroll = 20,		/* number entries in scrolling part */
	Scrollwid = 14,		/* width of scroll bar */
	Gap = 4,			/* between text and scroll bar */
};

static	Image	*menutxt;
static	Image	*back;
static	Image	*high;
static	Image	*bord;
static	Image	*text;
static	Image	*htext;

static
void
menucolors(void)
{
	/* Main tone is greenish, with negative selection */
	back = allocimagemix(display, DPalegreen, DWhite);
	high = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkgreen);	/* dark green */
	bord = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DMedgreen);	/* not as dark green */
	if(back==nil || high==nil || bord==nil)
		goto Error;
	text = display->black;
	htext = back;
	return;

    Error:
	freeimage(back);
	freeimage(high);
	freeimage(bord);
	back = display->white;
	high = display->black;
	bord = display->black;
	text = display->black;
	htext = display->white;
}

/*
 * r is a rectangle holding the text elements.
 * return the rectangle, including its black edge, holding element i.
 */
static Rectangle
menurect(Rectangle r, int i)
{
	if(i < 0)
		return Rect(0, 0, 0, 0);
	r.min.y += (font->height+Vspacing)*i;
	r.max.y = r.min.y+font->height+Vspacing;
	return insetrect(r, Border-Margin);
}

/*
 * r is a rectangle holding the text elements.
 * return the element number containing p.
 */
static int
menusel(Rectangle r, Point p)
{
	r = insetrect(r, Margin);
	if(!ptinrect(p, r))
		return -1;
	return (p.y-r.min.y)/(font->height+Vspacing);
}

static
void
paintitem(Menu *menu, Rectangle textr, int off, int i, int highlight, Image *save, Image *restore)
{
	char *item;
	Rectangle r;
	Point pt;

	if(i < 0)
		return;
	r = menurect(textr, i);
	if(restore){
		draw(screen, r, restore, nil, restore->r.min);
		return;
	}
	if(save)
		draw(save, save->r, screen, nil, r.min);
	item = menu->item? menu->item[i+off] : (*menu->gen)(i+off);
	pt.x = (textr.min.x+textr.max.x-stringwidth(font, item))/2;
	pt.y = textr.min.y+i*(font->height+Vspacing);
	draw(screen, r, highlight? high : back, nil, pt);
	string(screen, pt, highlight? htext : text, pt, font, item);
}

/*
 * menur is a rectangle holding all the highlightable text elements.
 * track mouse while inside the box, return what's selected when button
 * is raised, -1 as soon as it leaves box.
 * invariant: nothing is highlighted on entry or exit.
 */
static int
menuscan(Menu *menu, int but, Mouse *m, Rectangle textr, int off, int lasti, Image *save)
{
	int i;

	paintitem(menu, textr, off, lasti, 1, save, nil);
	flushimage(display, 1);	/* in case display->locking is set */
	*m = emouse();
	while(m->buttons & (1<<(but-1))){
		flushimage(display, 1);	/* in case display->locking is set */
		*m = emouse();
		i = menusel(textr, m->xy);
		if(i != -1 && i == lasti)
			continue;
		paintitem(menu, textr, off, lasti, 0, nil, save);
		if(i == -1)
			return i;
		lasti = i;
		paintitem(menu, textr, off, lasti, 1, save, nil);
	}
	return lasti;
}

static void
menupaint(Menu *menu, Rectangle textr, int off, int nitemdrawn)
{
	int i;

	draw(screen, insetrect(textr, Border-Margin), back, nil, ZP);
	for(i = 0; i<nitemdrawn; i++)
		paintitem(menu, textr, off, i, 0, nil, nil);
}

static void
menuscrollpaint(Rectangle scrollr, int off, int nitem, int nitemdrawn)
{
	Rectangle r;

	draw(screen, scrollr, back, nil, ZP);
	r.min.x = scrollr.min.x;
	r.max.x = scrollr.max.x;
	r.min.y = scrollr.min.y + (Dy(scrollr)*off)/nitem;
	r.max.y = scrollr.min.y + (Dy(scrollr)*(off+nitemdrawn))/nitem;
	if(r.max.y < r.min.y+2)
		r.max.y = r.min.y+2;
	border(screen, r, 1, bord, ZP);
	if(menutxt == 0)
		menutxt = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, DDarkgreen);
	if(menutxt)
		draw(screen, insetrect(r, 1), menutxt, nil, ZP);
}

int
emenuhit(int but, Mouse *m, Menu *menu)
{
	int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem;
	int scrolling;
	Rectangle r, menur, sc, textr, scrollr;
	Image *b, *save;
	Point pt;
	char *item;

	if(back == nil)
		menucolors();
	sc = screen->clipr;
	replclipr(screen, 0, screen->r);
	maxwid = 0;
	for(nitem = 0;
	    item = menu->item? menu->item[nitem] : (*menu->gen)(nitem);
	    nitem++){
		i = stringwidth(font, item);
		if(i > maxwid)
			maxwid = i;
	}
	if(menu->lasthit<0 || menu->lasthit>=nitem)
		menu->lasthit = 0;
	screenitem = (Dy(screen->r)-10)/(font->height+Vspacing);
	if(nitem>Maxunscroll || nitem>screenitem){
		scrolling = 1;
		nitemdrawn = Nscroll;
		if(nitemdrawn > screenitem)
			nitemdrawn = screenitem;
		wid = maxwid + Gap + Scrollwid;
		off = menu->lasthit - nitemdrawn/2;
		if(off < 0)
			off = 0;
		if(off > nitem-nitemdrawn)
			off = nitem-nitemdrawn;
		lasti = menu->lasthit-off;
	}else{
		scrolling = 0;
		nitemdrawn = nitem;
		wid = maxwid;
		off = 0;
		lasti = menu->lasthit;
	}
	r = insetrect(Rect(0, 0, wid, nitemdrawn*(font->height+Vspacing)), -Margin);
	r = rectsubpt(r, Pt(wid/2, lasti*(font->height+Vspacing)+font->height/2));
	r = rectaddpt(r, m->xy);
	pt = ZP;
	if(r.max.x>screen->r.max.x)
		pt.x = screen->r.max.x-r.max.x;
	if(r.max.y>screen->r.max.y)
		pt.y = screen->r.max.y-r.max.y;
	if(r.min.x<screen->r.min.x)
		pt.x = screen->r.min.x-r.min.x;
	if(r.min.y<screen->r.min.y)
		pt.y = screen->r.min.y-r.min.y;
	menur = rectaddpt(r, pt);
	textr.max.x = menur.max.x-Margin;
	textr.min.x = textr.max.x-maxwid;
	textr.min.y = menur.min.y+Margin;
	textr.max.y = textr.min.y + nitemdrawn*(font->height+Vspacing);
	if(scrolling){
		scrollr = insetrect(menur, Border);
		scrollr.max.x = scrollr.min.x+Scrollwid;
	}else
		scrollr = Rect(0, 0, 0, 0);

	b = allocimage(display, menur, screen->chan, 0, 0);
	if(b == 0)
		b = screen;
	draw(b, menur, screen, nil, menur.min);
	draw(screen, menur, back, nil, ZP);
	border(screen, menur, Blackborder, bord, ZP);
	save = allocimage(display, menurect(textr, 0), screen->chan, 0, -1);
	r = menurect(textr, lasti);
	emoveto(divpt(addpt(r.min, r.max), 2));
	menupaint(menu, textr, off, nitemdrawn);
	if(scrolling)
		menuscrollpaint(scrollr, off, nitem, nitemdrawn);
	while(m->buttons & (1<<(but-1))){
		lasti = menuscan(menu, but, m, textr, off, lasti, save);
		if(lasti >= 0)
			break;
		while(!ptinrect(m->xy, textr) && (m->buttons & (1<<(but-1)))){
			if(scrolling && ptinrect(m->xy, scrollr)){
				noff = ((m->xy.y-scrollr.min.y)*nitem)/Dy(scrollr);
				noff -= nitemdrawn/2;
				if(noff < 0)
					noff = 0;
				if(noff > nitem-nitemdrawn)
					noff = nitem-nitemdrawn;
				if(noff != off){
					off = noff;
					menupaint(menu, textr, off, nitemdrawn);
					menuscrollpaint(scrollr, off, nitem, nitemdrawn);
				}
			}
			flushimage(display, 1);	/* in case display->locking is set */
			*m = emouse();
		}
	}
	draw(screen, menur, b, nil, menur.min);
	if(b != screen)
		freeimage(b);
	freeimage(save);
	replclipr(screen, 0, sc);
	flushimage(display, 1);
	if(lasti >= 0){
		menu->lasthit = lasti+off;
		return menu->lasthit;
	}
	return -1;
}
