#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.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), screen->chan, 1, DDarkgreen);	/* dark green */
	bord = allocimage(display, Rect(0,0,1,1), screen->chan, 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(Image *m, 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(m, r, restore, nil, restore->r.min);
		return;
	}
	if(save)
		draw(save, save->r, m, 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(m, r, highlight? high : back, nil, pt);
	string(m, 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(Image *m, Menu *menu, int but, Mousectl *mc, Rectangle textr, int off, int lasti, Image *save)
{
	int i;

	paintitem(m, menu, textr, off, lasti, 1, save, nil);
	for(readmouse(mc); mc->m.buttons & (1<<(but-1)); readmouse(mc)){
		i = menusel(textr, mc->m.xy);
		if(i != -1 && i == lasti)
			continue;
		paintitem(m, menu, textr, off, lasti, 0, nil, save);
		if(i == -1)
			return i;
		lasti = i;
		paintitem(m, menu, textr, off, lasti, 1, save, nil);
	}
	return lasti;
}

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

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

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

	draw(m, 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(m, r, 1, bord, ZP);
	if(menutxt == 0)
		menutxt = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DDarkgreen);	/* border color; BUG? */
	if(menutxt)
		draw(m, insetrect(r, 1), menutxt, nil, ZP);
}

int
menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr)
{
	int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem;
	int scrolling;
	Rectangle r, menur, sc, textr, scrollr;
	Image *b, *save, *backup;
	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, mc->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);

	if(scr){
		b = allocwindow(scr, menur, Refbackup, DWhite);
		if(b == nil)
			b = screen;
		backup = nil;
	}else{
		b = screen;
		backup = allocimage(display, menur, screen->chan, 0, -1);
		if(backup)
			draw(backup, menur, screen, nil, menur.min);
	}
	draw(b, menur, back, nil, ZP);
	border(b, menur, Blackborder, bord, ZP);
	save = allocimage(display, menurect(textr, 0), screen->chan, 0, -1);
	r = menurect(textr, lasti);
	moveto(mc, divpt(addpt(r.min, r.max), 2));
	menupaint(b, menu, textr, off, nitemdrawn);
	if(scrolling)
		menuscrollpaint(b, scrollr, off, nitem, nitemdrawn);
	while(mc->m.buttons & (1<<(but-1))){
		lasti = menuscan(b, menu, but, mc, textr, off, lasti, save);
		if(lasti >= 0)
			break;
		while(!ptinrect(mc->m.xy, textr) && (mc->m.buttons & (1<<(but-1)))){
			if(scrolling && ptinrect(mc->m.xy, scrollr)){
				noff = ((mc->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(b, menu, textr, off, nitemdrawn);
					menuscrollpaint(b, scrollr, off, nitem, nitemdrawn);
				}
			}
			readmouse(mc);
		}
	}
	if(b != screen)
		freeimage(b);
	if(backup){
		draw(screen, menur, backup, nil, menur.min);
		freeimage(backup);
	}
	freeimage(save);
	replclipr(screen, 0, sc);
	flushimage(display, 1);
	if(lasti >= 0){
		menu->lasthit = lasti+off;
		return menu->lasthit;
	}
	return -1;
}
