#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <cursor.h>
#include <keyboard.h>
#include <frame.h>
#include "flayer.h"
#include "samterm.h"

uchar	**name;	/* first byte is ' ' or '\'': modified state */
Text	**text;	/* pointer to Text associated with file */
ushort	*tag;		/* text[i].tag, even if text[i] not defined */
int	nname;
int	mname;
int	mw;

char	*genmenu3(int);
char	*genmenu2(int);
char	*genmenu2c(int);

enum Menu2
{
	Cut,
	Paste,
	Snarf,
	Plumb,
	Look,
	Exch,
	Search,
	NMENU2 = Search,
	Send = Search,
	NMENU2C
};

enum Menu3
{
	New,
	Zerox,
	Resize,
	Close,
	Write,
	NMENU3
};

char	*menu2str[] = {
	"cut",
	"paste",
	"snarf",
	"plumb",
	"look",
	"<rio>",
	0,		/* storage for last pattern */
};

char	*menu3str[] = {
	"new",
	"zerox",
	"resize",
	"close",
	"write",
};

Menu	menu2 =	{0, genmenu2};
Menu	menu2c ={0, genmenu2c};
Menu	menu3 =	{0, genmenu3};

void
menu2hit(void)
{
	Text *t=(Text *)which->user1;
	int w = which-t->l;
	int m;

	if(hversion==0 || plumbfd<0)
		menu2str[Plumb] = "(plumb)";
	m = menuhit(2, mousectl, t==&cmd? &menu2c : &menu2, nil);
	if(hostlock || t->lock)
		return;

	switch(m){
	case Cut:
		cut(t, w, 1, 1);
		break;

	case Paste:
		paste(t, w);
		break;

	case Snarf:
		snarf(t, w);
		break;

	case Plumb:
		if(hversion > 0)
			outTsll(Tplumb, t->tag, which->p0, which->p1);
		break;

	case Exch:
		snarf(t, w);
		outT0(Tstartsnarf);
		setlock();
		break;

	case Look:
		outTsll(Tlook, t->tag, which->p0, which->p1);
		setlock();
		break;

	case Search:
		outcmd();
		if(t==&cmd)
			outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1);
		else
			outT0(Tsearch);
		setlock();
		break;
	}
}

void
menu3hit(void)
{
	Rectangle r;
	Flayer *l;
	int m, i;
	Text *t;

	mw = -1;
	m = menuhit(3, mousectl, &menu3, nil);
	switch(m){
	case -1:
		break;

	case New:
		if(!hostlock)
			sweeptext(1, 0);
		break;

	case Zerox:
	case Resize:
		if(!hostlock){
			setcursor(mousectl, &bullseye);
			buttons(Down);
			if((mousep->buttons&4) && (l = flwhich(mousep->xy)) && getr(&r))
				duplicate(l, r, l->f.font, m==Resize);
			else
				setcursor(mousectl, cursor);
			buttons(Up);
		}
		break;

	case Close:
		if(!hostlock){
			setcursor(mousectl, &bullseye);
			buttons(Down);
			if((mousep->buttons&4) && (l = flwhich(mousep->xy)) && !hostlock){
				t=(Text *)l->user1;
				if (t->nwin>1)
					closeup(l);
				else if(t!=&cmd) {
					outTs(Tclose, t->tag);
					setlock();
				}
			}
			setcursor(mousectl, cursor);
			buttons(Up);
		}
		break;

	case Write:
		if(!hostlock){
			setcursor(mousectl, &bullseye);
			buttons(Down);
			if((mousep->buttons&4) && (l = flwhich(mousep->xy))){
				outTs(Twrite, ((Text *)l->user1)->tag);
				setlock();
			}else
				setcursor(mousectl, cursor);
			buttons(Up);
		}
		break;

	default:
		if(t = text[m-NMENU3]){
			i = t->front;
			if(t->nwin==0 || t->l[i].textfn==0)
				return;	/* not ready yet; try again later */
			if(t->nwin>1 && which==&t->l[i])
				do
					if(++i==NL)
						i = 0;
				while(i!=t->front && t->l[i].textfn==0);
			current(&t->l[i]);
		}else if(!hostlock)
			sweeptext(0, tag[m-NMENU3]);
		break;
	}
}


Text *
sweeptext(int new, int tag)
{
	Rectangle r;
	Text *t;

	if(getr(&r) && (t = malloc(sizeof(Text)))){
		memset((void*)t, 0, sizeof(Text));
		current((Flayer *)0);
		flnew(&t->l[0], gettext, 0, (char *)t);
		flinit(&t->l[0], r, font, maincols);	/*bnl*/
		t->nwin = 1;
		rinit(&t->rasp);
		if(new)
			startnewfile(Tstartnewfile, t);
		else{
			rinit(&t->rasp);
			t->tag = tag;
			startfile(t);
		}
		return t;
	}
	return 0;
}

int
whichmenu(int tg)
{
	int i;

	for(i=0; i<nname; i++)
		if(tag[i] == tg)
			return i;
	return -1;
}

void
menuins(int n, uchar *s, Text *t, int m, int tg)
{
	int i;

	if(nname == mname){
		if(mname == 0)
			mname = 32;
		else
			mname *= 2;
		name = realloc(name, sizeof(name[0])*mname);
		text = realloc(text, sizeof(text[0])*mname);
		tag = realloc(tag, sizeof(tag[0])*mname);
		if(name==nil || text==nil || tag==nil)
			panic("realloc");
	}
	for(i=nname; i>n; --i)
		name[i]=name[i-1], text[i]=text[i-1], tag[i]=tag[i-1];
	text[n] = t;
	tag[n] = tg;
	name[n] = alloc(strlen((char*)s)+2);
	name[n][0] = m;
	strcpy((char*)name[n]+1, (char*)s);
	nname++;
	menu3.lasthit = n+NMENU3;
}

void
menudel(int n)
{
	int i;

	if(nname==0 || n>=nname || text[n])
		panic("menudel");
	free(name[n]);
	--nname;
	for(i = n; i<nname; i++)
		name[i]=name[i+1], text[i]=text[i+1], tag[i]=tag[i+1];
}

void
setpat(char *s)
{
	static char pat[17];

	pat[0] = '/';
	strncpy(pat+1, s, 15);
	menu2str[Search] = pat;
}

#define	NBUF	64
static uchar buf[NBUF*UTFmax]={' ', ' ', ' ', ' '};

char *
paren(char *s)
{
	uchar *t = buf;

	*t++ = '(';
	do; while(*t++ = *s++);
	t[-1] = ')';
	*t = 0;
	return (char *)buf;
}
char*
genmenu2(int n)
{
	Text *t=(Text *)which->user1;
	char *p;
	if(n>=NMENU2+(menu2str[Search]!=0))
		return 0;
	p = menu2str[n];
	if(!hostlock && !t->lock || n==Search || n==Look)
		return p;
	return paren(p);
}
char*
genmenu2c(int n)
{
	Text *t=(Text *)which->user1;
	char *p;
	if(n >= NMENU2C)
		return 0;
	if(n == Send)
		p="send";
	else
		p = menu2str[n];
	if(!hostlock && !t->lock)
		return p;
	return paren(p);
}
char *
genmenu3(int n)
{
	Text *t;
	int c, i, k, l, w;
	Rune r;
	char *p;

	if(n >= NMENU3+nname)
		return 0;
	if(n < NMENU3){
		p = menu3str[n];
		if(hostlock)
			p = paren(p);
		return p;
	}
	n -= NMENU3;
	if(n == 0)	/* unless we've been fooled, this is cmd */
		return (char *)&name[n][1];
	if(mw == -1){
		mw = 7;	/* strlen("~~sam~~"); */
		for(i=1; i<nname; i++){
			w = utflen((char*)name[i]+1)+4;	/* include "'+. " */
			if(w > mw)
				mw = w;
		}
	}
	if(mw > NBUF)
		mw = NBUF;
	t = text[n];
	buf[0] = name[n][0];
	buf[1] = '-';
	buf[2] = ' ';
	buf[3] = ' ';
	if(t){
		if(t->nwin == 1)
			buf[1] = '+';
		else if(t->nwin > 1)
			buf[1] = '*';
		if(work && t==(Text *)work->user1) {
			buf[2]= '.';
			if(modified)
				buf[0] = '\'';
		}
	}
	l = utflen((char*)name[n]+1);
	if(l > NBUF-4-2){
		i = 4;
		k = 1;
		while(i < NBUF/2){
			k += chartorune(&r, (char*)name[n]+k);
			i++;
		}
		c = name[n][k];
		name[n][k] = 0;
		strcpy((char*)buf+4, (char*)name[n]+1);
		name[n][k] = c;
		strcat((char*)buf, "...");
		while((l-i) >= NBUF/2-4){
			k += chartorune(&r, (char*)name[n]+k);
			i++;
		}
		strcat((char*)buf, (char*)name[n]+k);
	}else
		strcpy((char*)buf+4, (char*)name[n]+1);
	i = utflen((char*)buf);
	k = strlen((char*)buf);
	while(i<mw && k<sizeof buf-1){
		buf[k++] = ' ';
		i++;
	}
	buf[k] = 0;
	return (char *)buf;
}
