#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <cursor.h>
#include <keyboard.h>
#include <frame.h>
#include <plumb.h>
#include <complete.h>
#include "term.h"

typedef struct Text	Text;
typedef struct Readbuf	Readbuf;

enum
{
	HiWater	= 640000,	/* max size of history */
	LoWater	= 400000,	/* min size of history after max'ed */
	MinWater	= 20000,
};

/* various geometric paramters */
enum
{
	Scrollwid 	= 12,		/* width of scroll bar */
	Scrollgap 	= 4,		/* gap right of scroll bar */
	Maxtab		= 4,
};

enum
{
	Cut,
	Paste,
	Snarf,
	Send,
	Plumb,
	Scroll,
};

#define	ESC		0x1B
#define	CUT		0x18	/* ctrl-x */		
#define	COPY		0x03	/* crtl-c */
#define	PASTE		0x16	/* crtl-v */

#define	READBUFSIZE 8192
#define TRUE 1
#define FALSE 0


struct Text
{
	Frame		*f;		/* frame ofr terminal */
	Mouse		m;
	uint		nr;		/* num of runes in term */
	uint		maxr;	/* max num of runes in r */
	Rune		*r;		/* runes for term */
	uint		nraw;		/* num of runes in raw buffer */
	Rune		*raw;		/* raw buffer */
	uint		org;		/* first rune on the screen */
	uint		q0;		/* start of selection region */
	uint		q1;		/* end of selection region */
	uint		qh;		/* unix point */
	int		npart;		/* partial runes read from console */
	char		part[UTFmax];	
	int		nsnarf;		/* snarf buffer */
	Rune		*snarf;
};

struct Readbuf
{
	short	n;				/* # bytes in buf */
	uchar	data[READBUFSIZE];		/* data bytes */
};

void	mouse(void);
void	domenu2(int);
void	loop(void);
void	geom(void);
void	fill(void);
void	tcheck(void);
void	updatesel(void);
void	doreshape(void);
void	runewrite(Rune*, int);
void	consread(void);
void	conswrite(char*, int);
int	bswidth(Rune c);
void	cut(void);
void	paste(Rune*, int, int);
void	snarfupdate(void);
void	snarf(void);
void	show(uint);
void	key(Rune);
void	setorigin(uint org, int exact);
uint	line2q(uint);
uint	backnl(uint, uint);
int	cansee(uint);
uint	backnl(uint, uint);
void	addraw(Rune*, int);
void	mselect(void);
void	doubleclick(uint *q0, uint *q1);
int	clickmatch(int cl, int cr, int dir, uint *q);
Rune	*strrune(Rune *s, Rune c);
int	consready(void);
Rectangle scrpos(Rectangle r, ulong p0, ulong p1, ulong tot);
void	scrdraw(void);
void	scroll(int);
void	hostproc(void *arg);
void	hoststart(void);
void	plumbstart(void);
void	plumb(uint, uint);
void	plumbclick(uint*, uint*);
uint	insert(Rune*, int, uint, int);

#define	runemalloc(n)		malloc((n)*sizeof(Rune))
#define	runerealloc(a, n)	realloc(a, (n)*sizeof(Rune))
#define	runemove(a, b, n)	memmove(a, b, (n)*sizeof(Rune))
Rectangle	scrollr;	/* scroll bar rectangle */
Rectangle	lastsr;		/* used for scroll bar */
int		holdon;		/* hold mode */
int		rawon;		/* raw mode */
int		scrolling;	/* window scrolls */
int		clickmsec;	/* time of last click */
uint		clickq0;	/* point of last click */
int		rcfd;
int		rcpid;
int		maxtab;
int		use9wm;
Mousectl*	mc;
Keyboardctl*	kc;
Channel*	hostc;
Readbuf		rcbuf[2];
int		mainpid;
int		acmecolors;
int		plumbfd;
int		button2exec;
int		label(Rune*, int);
char		wdir[1024];
char		childwdir[1024];
void		hangupnote(void*, char*);

char *menu2str[] = {
	"cut",
	"paste",
	"snarf",
	"send",
	"plumb",
	"scroll",
	0
};

Image* cols[NCOL];
Image* hcols[NCOL];
Image* palegrey;
Image* paleblue;
Image* blue;
Image *plumbcolor;
Image *execcolor;

Menu menu2 =
{
	menu2str
};

Text	t;

Cursor whitearrow = {
	{0, 0},
	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC, 
	 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC, 
	 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC, 
	 0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, },
	{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C, 
	 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C, 
	 0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C, 
	 0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }
};

void
usage(void)
{
	fprint(2, "usage: 9term [-ars] [cmd ...]\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char *argv[])
{
	char *p;

	rfork(RFNOTEG);
	_wantfocuschanges = 1;
	mainpid = getpid();
	ARGBEGIN{
	default:
		usage();
	case 'a':	/* acme mode */
		button2exec++;
		break;
	case 'r':
		/* not clear this is useful */
		rawon = 1;
		break;
	case 's':
		scrolling++;
		break;
	case 'w':	/* started from "rio" window manager */
		use9wm = 1;
		break;
	}ARGEND

	p = getenv("tabstop");
	if(p == 0)
		p = getenv("TABSTOP");
	if(p != 0 && maxtab <= 0)
		maxtab = strtoul(p, 0, 0);
	if(maxtab <= 0)
		maxtab = 8;

	initdraw(0, nil, "9term");
	notify(hangupnote);

	mc = initmouse(nil, screen);
	kc = initkeyboard(nil);
	rcpid = rcstart(argc, argv, &rcfd);
	hoststart();
	plumbstart();

	t.f = mallocz(sizeof(Frame), 1);

	if(acmecolors){
		cols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
		cols[HIGH] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DDarkyellow);
		cols[BORD] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DYellowgreen);
	}else{
		cols[BACK] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DWhite);
		cols[HIGH] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
		cols[BORD] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x999999FF);
	}
	cols[TEXT] = display->black;
	cols[HTEXT] = display->black;
	palegrey = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x666666FF);

	hcols[BACK] = cols[BACK];
	hcols[HIGH] = cols[HIGH];
	blue = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DMedblue);
	paleblue = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DGreyblue);

	hcols[BORD] = blue;
	hcols[TEXT] = hcols[BORD];
	hcols[HTEXT] = hcols[TEXT];

	plumbcolor = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x006600FF);
	execcolor = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAA0000FF);

	if(!blue || !palegrey || !paleblue || !plumbcolor || !execcolor)
		sysfatal("alloc colors: %r");
	draw(screen, screen->r, cols[BACK], nil, ZP);
	geom();
	loop();
}

void
hangupnote(void *a, char *msg)
{
	if(getpid() != mainpid)
		noted(NDFLT);
	if(strcmp(msg, "hangup") == 0 && rcpid != 0){
		postnote(PNGROUP, rcpid, "hangup");
		noted(NDFLT);
	}
	noted(NDFLT);
}

void
hostproc(void *arg)
{
	Channel *c;
	int i, n, which;

	c = arg;

	i = 0;
	for(;;){
		/* Let typing have a go -- maybe there's a rubout waiting. */
		i = 1-i;	/* toggle */
		n = threadread(rcfd, rcbuf[i].data, sizeof rcbuf[i].data);
		if(n <= 0){
			if(n < 0)
				fprint(2, "9term: host read error: %r\n");
			threadexitsall("host");
		}
		rcbuf[i].n = n;
		which = i;
		send(c, &which);
	}
}

void
hoststart(void)
{
	hostc = chancreate(sizeof(int), 0);
	threadcreate(hostproc, hostc, 32*1024);
}

void
loop(void)
{
	Rune r;
	int i;
	Alt a[5];

	a[0].c = mc->c;
	a[0].v = &mc->m;
	a[0].op = CHANRCV;

	a[1].c = kc->c;
	a[1].v = &r;
	a[1].op = CHANRCV;

	a[2].c = hostc;
	a[2].v = &i;
	a[2].op = CHANRCV;

	a[3].c = mc->resizec;
	a[3].v = nil;
	a[3].op = CHANRCV;

	a[4].c = nil;
	a[4].v = nil;
	a[4].op = CHANEND;

	for(;;) {
		tcheck();

		scrdraw();
		flushimage(display, 1);
		a[2].op = CHANRCV;
		if(!scrolling && t.qh > t.org+t.f->nchars)
			a[2].op = CHANNOP;;
		switch(alt(a)) {
		default:
			sysfatal("impossible");
		case 0:
			t.m = mc->m;
			mouse();
			break;
		case 1:
			key(r);
			break;
		case 2:
			conswrite((char*)rcbuf[i].data, rcbuf[i].n);
			break;
		case 3:
			doreshape();
			break;
		}
	}
}

void
doreshape(void)
{
	if(getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
	draw(screen, screen->r, cols[BACK], nil, ZP);
	geom();
	scrdraw();
}

void
geom(void)
{
	Point p;
	Rectangle r;

	if(!acmecolors){
		if(_windowhasfocus){
			cols[TEXT] = cols[HTEXT] = display->black;
			hcols[TEXT] = hcols[HTEXT] = blue;
		}else{
			cols[TEXT] = cols[HTEXT] = palegrey;
			hcols[TEXT] = hcols[HTEXT] = paleblue;
		}
	}

	r = screen->r;
	r.min.y++;
	r.max.y--;

	scrollr = r;
	scrollr.max.x = r.min.x+Scrollwid;
	lastsr = Rect(0,0,0,0);

	r.min.x += Scrollwid+Scrollgap;

	frclear(t.f, 0);
	frinit(t.f, r, font, screen, holdon ? hcols : cols);
	t.f->maxtab = maxtab*stringwidth(font, "0");
	fill();
	updatesel();

	p = stringsize(font, "0");
	if(p.x == 0 || p.y == 0)
		return;

	updatewinsize(Dy(r)/p.y, Dx(r)/p.x, Dx(r), Dy(r));
}

void
drawhold(int holdon)
{
	if(holdon)
		setcursor(mc, &whitearrow);
	else
		setcursor(mc, nil);

	draw(screen, screen->r, cols[BACK], nil, ZP);
	geom();
	scrdraw();
}

void
wordclick(uint *q0, uint *q1)
{
	while(*q1<t.nr && !isspace(t.r[*q1]))
		(*q1)++;
	while(*q0>0 && !isspace(t.r[*q0-1]))
		(*q0)--;
}

int
aselect(uint *q0, uint *q1, Image *color)
{
	int cancel;
	uint oldq0, oldq1, newq0, newq1;

	/* save old selection */
	oldq0 = t.q0;
	oldq1 = t.q1;

	/* sweep out area and record it */
	t.f->cols[HIGH] = color;
	t.f->cols[HTEXT] = display->white;
	mselect();
	newq0 = t.q0;
	newq1 = t.q1;

	cancel = 0;
	if(t.m.buttons != 0){
		while(t.m.buttons){
			readmouse(mc);
			t.m = mc->m;
		}
		cancel = 1;
	}

	/* restore old selection */
	t.f->cols[HIGH] = cols[HIGH];
	t.f->cols[HTEXT] = cols[HTEXT];
	t.q0 = oldq0;
	t.q1 = oldq1;
	updatesel();

	if(cancel)
		return -1;

	/* selected a region */
	if(newq0 < newq1){
		*q0 = newq0;
		*q1 = newq1;
		return 0;
	}

	/* clicked inside previous selection */
	/* the "<=" in newq0 <= oldq1 allows us to click the right edge */
	if(oldq0 <= newq0 && newq0 <= oldq1){
		*q0 = oldq0;
		*q1 = oldq1;
		return 0;
	}

	/* just a click */
	*q0 = newq0;
	*q1 = newq1;
	return 0;
}

static Rune Lnl[1] = { '\n' };

void
mouse(void)
{
	int but;
	uint q0, q1;

	but = t.m.buttons;

	if(but != 1 && but != 2 && but != 4)
		return;

	if (ptinrect(t.m.xy, scrollr)) {
		scroll(but);
		if(t.qh<=t.org+t.f->nchars)
			consread();
		return;
	}
		
	switch(but) {
	case 1:
		mselect();
		break;
	case 2:
		if(button2exec){
			if(aselect(&q0, &q1, execcolor) >= 0){
				if(q0 == q1)
					wordclick(&q0, &q1);
				if(q0 == q1)
					break;
				t.q0 = t.q1 = t.nr;
				updatesel();
				paste(t.r+q0, q1-q0, 1);
				if(t.r[q1-1] != '\n')
					paste(Lnl, 1, 1);
			}
			break;
		}
		domenu2(2);
		break;
	case 4:
		if(aselect(&q0, &q1, plumbcolor) >= 0)
			plumb(q0, q1);
		break;
	}
}

void
mselect(void)
{
	int b, x, y;
	uint q0;

	b = t.m.buttons;
	q0 = frcharofpt(t.f, t.m.xy) + t.org;
	if(t.m.msec-clickmsec<500 && clickq0==q0 && t.q0==t.q1 && b==1){
		doubleclick(&t.q0, &t.q1);
		updatesel();
/*		t.t.i->flush(); */
		x = t.m.xy.x;
		y = t.m.xy.y;
		/* stay here until something interesting happens */
		do {
			readmouse(mc);
			t.m = mc->m;
		} while(t.m.buttons==b && abs(t.m.xy.x-x)<4 && abs(t.m.xy.y-y)<4);
		t.m.xy.x = x;	/* in case we're calling frselect */
		t.m.xy.y = y;
		clickmsec = 0;
	}

	if(t.m.buttons == b) {
		frselect(t.f, mc);
		t.m = mc->m;
		t.q0 = t.f->p0 + t.org;
		t.q1 = t.f->p1 + t.org;
		clickmsec = t.m.msec;
		clickq0 = t.q0;
	}
	if((t.m.buttons != b) &&(b&1)){
		enum{Cancut = 1, Canpaste = 2} state = Cancut | Canpaste;
		while(t.m.buttons){
			if(t.m.buttons&2){
				if(state&Cancut){
					snarf();
					cut();
					state = Canpaste;
				}
			}else if(t.m.buttons&4){
				if(state&Canpaste){
					snarfupdate();
					if(t.nsnarf){
						paste(t.snarf, t.nsnarf, 0);
					}
					state = Cancut;
				}
			}
			readmouse(mc);
			t.m = mc->m;
		}
	}
}

Rune newline[] = { '\n', 0 };

void
domenu2(int but)
{
	if(scrolling)
		menu2str[Scroll] = "noscroll";
	else
		menu2str[Scroll] = "scroll";

	switch(menuhit(but, mc, &menu2, nil)){
	case -1:
		break;
	case Cut:
		snarf();
		cut();
		if(scrolling)
			show(t.q0);
		break;
	case Paste:
		snarfupdate();
		paste(t.snarf, t.nsnarf, 0);
		if(scrolling)
			show(t.q0);
		break;
	case Snarf:
		snarf();
		if(scrolling)
			show(t.q0);
		break;
	case Send:
		if(t.q0 != t.q1)
			snarf();
		else
			snarfupdate();
		t.q0 = t.q1 = t.nr;
		updatesel();
		paste(t.snarf, t.nsnarf, 1);
		if(t.nsnarf == 0 || t.snarf[t.nsnarf-1] != '\n')
			paste(newline, 1, 1);
		show(t.nr);
		consread();
		break;
	case Scroll:
		scrolling = !scrolling;
		if (scrolling) {
			show(t.nr);
			consread();
		}
		break;
	case Plumb:
		plumb(t.q0, t.q1);
		break;
	default:
		sysfatal("bad menu item");
	}
}

int
windfilewidth(uint q0, int oneelement)
{
	uint q;
	Rune r;

	q = q0;
	while(q > 0){
		r = t.r[q-1];
		if(r<=' ')
			break;
		if(oneelement && r=='/')
			break;
		--q;
	}
	return q0-q;
}

void
showcandidates(Completion *c)
{
	int i;
	Fmt f;
	Rune *rp;
	uint nr, qline, q0;
	char *s;

	runefmtstrinit(&f);
	if (c->nmatch == 0)
		s = "[no matches in ";
	else
		s = "[";
	if(c->nfile > 32)
		fmtprint(&f, "%s%d files]\n", s, c->nfile);
	else{
		fmtprint(&f, "%s", s);
		for(i=0; i<c->nfile; i++){
			if(i > 0)
				fmtprint(&f, " ");
			fmtprint(&f, "%s", c->filename[i]);
		}
		fmtprint(&f, "]\n");
	}
	/* place text at beginning of line before host point */
	qline = t.qh;
	while(qline>0 && t.r[qline-1] != '\n')
		qline--;

	rp = runefmtstrflush(&f);
	nr = runestrlen(rp);

	q0 = t.q0;
	q0 += insert(rp, nr, qline, 0) - qline;
	free(rp);
	t.q0 = q0+nr;
	t.q1 = q0+nr;
	updatesel();
}

Rune*
namecomplete(void)
{
	int nstr, npath;
	Rune *rp, *path, *str;
	Completion *c;
	char *s, *dir, *root;

	/* control-f: filename completion; works back to white space or / */
	if(t.q0<t.nr && t.r[t.q0]>' ')	/* must be at end of word */
		return nil;
	nstr = windfilewidth(t.q0, TRUE);
	str = runemalloc(nstr);
	runemove(str, t.r+(t.q0-nstr), nstr);
	npath = windfilewidth(t.q0-nstr, FALSE);
	path = runemalloc(npath);
	runemove(path, t.r+(t.q0-nstr-npath), npath);
	rp = nil;

	/* is path rooted? if not, we need to make it relative to window path */
	if(npath>0 && path[0]=='/'){
		dir = malloc(UTFmax*npath+1);
		sprint(dir, "%.*S", npath, path);
	}else{
		if(strcmp(wdir, "") == 0)
			root = ".";
		else
			root = wdir;
		dir = malloc(strlen(root)+1+UTFmax*npath+1);
		sprint(dir, "%s/%.*S", root, npath, path);
	}
	dir = cleanname(dir);

	s = smprint("%.*S", nstr, str);
	c = complete(dir, s);
	free(s);
	if(c == nil)
		goto Return;

	if(!c->advance)
		showcandidates(c);

	if(c->advance)
		rp = runesmprint("%s", c->string);

  Return:
	freecompletion(c);
	free(dir);
	free(path);
	free(str);
	return rp;
}

void
key(Rune r)
{
	Rune *rp;
	int nr;

	if(r == 0)
		return;
	switch(r){
	case Kpgup:
		setorigin(backnl(t.org, t.f->maxlines*2/3), 1);
		return;
	case Kpgdown:
		setorigin(line2q(t.f->maxlines*2/3), 1);
		if(t.qh<=t.org+t.f->nchars)
			consread();
		return;
	case Kup:
		setorigin(backnl(t.org, t.f->maxlines/3), 1);
		return;
	case Kdown:
		setorigin(line2q(t.f->maxlines/3), 1);
		if(t.qh<=t.org+t.f->nchars)
			consread();
		return;
	case Kleft:
		if(t.q0 > 0){
			t.q0--;
			t.q1 = t.q0;
			updatesel();
			show(t.q0);
		}
		return;
	case Kright:
		if(t.q1 < t.nr){
			t.q1++;
			t.q0 = t.q1;
			updatesel();
			show(t.q1);
		}
		return;
	case Khome:
		show(0);
		return;
	case Kend:
	case 0x05:
		show(t.nr);
		return;
	case CUT:
		snarf();
		cut();
		if(scrolling)
			show(t.q0);
		return;
	case COPY:
		snarf();
		if(scrolling)
			show(t.q0);
		return;
	case PASTE:
		snarfupdate();
		paste(t.snarf, t.nsnarf, 0);
		if(scrolling)
			show(t.q0);
		return;
	}

	if(rawon && t.q0==t.nr){
		addraw(&r, 1);
		consread();
		return;
	}

	if(r==ESC || (holdon && r==0x7F)){	/* toggle hold */
		holdon = !holdon;
		drawhold(holdon);
		if(!holdon)
			consread();
		if(r==ESC)
			return;
	}

	snarf();

	switch(r) {
	case 0x03:	/* ^C: send interrupt */
	case 0x7F:	/* DEL: send interrupt */
		t.qh = t.q0 = t.q1 = t.nr;
		show(t.q0);
		write(rcfd, "\x7F", 1);
		break;
	case 0x06:	/* ^F: file name completion */
	case Kins:		/* Insert: file name completion */
		rp = namecomplete();
		if(rp == nil)
			return;
		nr = runestrlen(rp);
		paste(rp, nr, 1);
		free(rp);
		return;
	case 0x08:	/* ^H: erase character */
	case 0x15:	/* ^U: erase line */
	case 0x17:	/* ^W: erase word */
		if (t.q0 != 0 && t.q0 != t.qh)
			t.q0 -= bswidth(r);
		cut();
		break;
	default:
		paste(&r, 1, 1);
		break;
	}
	if(scrolling)
		show(t.q0);
}

int
bswidth(Rune c)
{
	uint q, eq, stop;
	Rune r;
	int skipping;

	/* there is known to be at least one character to erase */
	if(c == 0x08)	/* ^H: erase character */
		return 1;
	q = t.q0;
	stop = 0;
	if(q > t.qh)
		stop = t.qh;
	skipping = 1;
	while(q > stop){
		r = t.r[q-1];
		if(r == '\n'){		/* eat at most one more character */
			if(q == t.q0)	/* eat the newline */
				--q;
			break; 
		}
		if(c == 0x17){
			eq = isalnum(r);
			if(eq && skipping)	/* found one; stop skipping */
				skipping = 0;
			else if(!eq && !skipping)
				break;
		}
		--q;
	}
	return t.q0-q;
}

int
consready(void)
{
	int i, c;

	if(holdon)
		return 0;

	if(rawon) 
		return t.nraw != 0;

	/* look to see if there is a complete line */
	for(i=t.qh; i<t.nr; i++){
		c = t.r[i];
		if(c=='\n' || c=='\004' || c=='\x7F')
			return 1;
	}
	return 0;
}


void
consread(void)
{
	char buf[8000], *p;
	int c, width, n;

	for(;;) {
		if(!consready())
			return;

		n = sizeof(buf);
		p = buf;
		c = 0;
		while(n >= UTFmax && (t.qh<t.nr || t.nraw > 0)) {
			if(t.qh == t.nr){
				width = runetochar(p, &t.raw[0]);
				t.nraw--;
				runemove(t.raw, t.raw+1, t.nraw);
			}else
				width = runetochar(p, &t.r[t.qh++]);
			c = *p;
			p += width;
			n -= width;
			if(!rawon && (c == '\n' || c == '\004' || c == '\x7F'))
				break;
		}
		/* take out control-d when not doing a zero length write */
		n = p-buf;
		if(write(rcfd, buf, n) < 0)
			exits(0);
/*		mallocstats(); */
	}
}

void
conswrite(char *p, int n)
{
	int n2, i;
	Rune buf2[1000], *q;

	/* convert to runes */
	i = t.npart;
	if(i > 0){
		/* handle partial runes */
		while(i < UTFmax && n>0) {
			t.part[i] = *p;
			i++;
			p++;
			n--;
			if(fullrune(t.part, i)) {
				t.npart = 0;
				chartorune(buf2, t.part);
				runewrite(buf2, 1);
				break;
			}
		}
		/* there is a little extra room in a message buf */
	}

	while(n >= UTFmax || fullrune(p, n)) {
		n2 = nelem(buf2);
		q = buf2;

		while(n2) {
			if(n < UTFmax && !fullrune(p, n))
				break;
			i = chartorune(q, p);
			p += i;
			n -= i;
			n2--;
			q++;
		}
		runewrite(buf2, q-buf2);
	}

	if(n != 0) {
		assert(n+t.npart < UTFmax);
		memcpy(t.part+t.npart, p, n);
		t.npart += n;
	}

	if(scrolling)
		show(t.qh);
}

void
runewrite(Rune *r, int n)
{
	int i;
	uint initial;
	uint q0, q1;
	uint p0, p1;
	Rune *p, *q;

	n = label(r, n);
	if(n == 0)
		return;

	/* get rid of backspaces */
	initial = 0;
	p = q = r;
	for(i=0; i<n; i++) {
		if(*p == '\b') {
			if(q == r)
				initial++;
			else
				--q;
		} else if(*p)
			*q++ = *p;
		p++;
	}
	n = q-r;

	if(initial){
		/* write turned into a delete */

		if(initial > t.qh)
			initial = t.qh;
		q0 = t.qh-initial;
		q1 = t.qh;

		runemove(t.r+q0, t.r+q1, t.nr-q1);
		t.nr -= initial;
		t.qh -= initial;
		if(t.q0 > q1)
			t.q0 -= initial;
		else if(t.q0 > q0)
			t.q0 = q0;
		if(t.q1 > q1)
			t.q1 -= initial;
		else if(t.q1 > q0)
			t.q1 = q0;
		if(t.org > q1)
			t.org -= initial;
		else if(q0 < t.org+t.f->nchars){
			if(t.org < q0)
				p0 = q0 - t.org;
			else {
				t.org = q0;
				p0 = 0;
			}
			p1 = q1 - t.org;
			if(p1 > t.f->nchars)
				p1 = t.f->nchars;
			frdelete(t.f, p0, p1);
			fill();
		}
		updatesel();
	}

	insert(r, n, t.qh, 1);
}


void
cut(void)
{
	uint n, p0, p1;
	uint q0, q1;

	q0 = t.q0;
	q1 = t.q1;

	if (q0 < t.org && q1 >= t.org)
		show(q0);

	n = q1-q0;
	if(n == 0)
		return;
	runemove(t.r+q0, t.r+q1, t.nr-q1);
	t.nr -= n;
	t.q0 = t.q1 = q0;
	if(q1 < t.qh)
		t.qh -= n;
	else if(q0 < t.qh)
		t.qh = q0;
	if(q1 < t.org)
		t.org -= n;
	else if(q0 < t.org+t.f->nchars){
		assert(q0 >= t.org);
		p0 = q0 - t.org;
		p1 = q1 - t.org;
		if(p1 > t.f->nchars)
			p1 = t.f->nchars;
		frdelete(t.f, p0, p1);
		fill();
	}
	updatesel();
}

void
snarfupdate(void)
{
	char *pp;
	int n, i;
	Rune *p;

	pp = getsnarf();
	if(pp == nil)
		return;
	n = strlen(pp);
	if(n <= 0) {
		 /*t.nsnarf = 0;*/
		return;
	}
	t.snarf = runerealloc(t.snarf, n);
	for(i=0,p=t.snarf; i<n; p++)
		i += chartorune(p, pp+i);
	t.nsnarf = p-t.snarf;

}

char sbuf[SnarfSize];
void
snarf(void)
{
	char *p;
	int i, n;
	Rune *rp;

	if(t.q1 == t.q0)
		return;
	n = t.q1-t.q0;
	t.snarf = runerealloc(t.snarf, n);
	for(i=0,p=sbuf,rp=t.snarf; i<n && p < sbuf+SnarfSize-UTFmax; i++){
		*rp++ = *(t.r+t.q0+i);
		p += runetochar(p, t.r+t.q0+i);
	}
	t.nsnarf = rp-t.snarf;
	*p = '\0';
	putsnarf(sbuf);
}

uint
min(uint x, uint y)
{
	if(x < y)
		return x;
	return y;
}

uint
max(uint x, uint y)
{
	if(x > y)
		return x;
	return y;
}

uint
insert(Rune *r, int n, uint q0, int hostwrite)
{
	uint m;

	if(n == 0)
		return q0;
	if(t.nr+n>HiWater && q0>=t.org && q0>=t.qh){
		m = min(HiWater-LoWater, min(t.org, t.qh));
		t.org -= m;
		t.qh -= m;
		if(t.q0 > m)
			t.q0 -= m;
		else
			t.q0 = 0;
		if(t.q1 > m)
			t.q1 -= m;
		else
			t.q1 = 0;
		t.nr -= m;
		runemove(t.r, t.r+m, t.nr);
		q0 -= m;
	}
	if(t.nr+n > t.maxr){
		/*
		 * Minimize realloc breakage:
		 *	Allocate at least MinWater
		 * 	Double allocation size each time
		 *	But don't go much above HiWater
		 */
		m = max(min(2*(t.nr+n), HiWater), t.nr+n)+MinWater;
		if(m > HiWater)
			m = max(HiWater+MinWater, t.nr+n);
		if(m > t.maxr){
			t.r = runerealloc(t.r, m);
			t.maxr = m;
		}
	}
	runemove(t.r+q0+n, t.r+q0, t.nr-q0);
	runemove(t.r+q0, r, n);
	t.nr += n;
	/* if output touches, advance selection, not qh; works best for keyboard and output */
	if(q0 <= t.q1)
		t.q1 += n;
	if(q0 <= t.q0)
		t.q0 += n;
	if(q0 < t.qh || (q0==t.qh && hostwrite))
		t.qh += n;
	else
		consread();
	if(q0 < t.org)
		t.org += n;
	else if(q0 <= t.org+t.f->nchars)
		frinsert(t.f, r, r+n, q0-t.org);
	return q0;
}

void
paste(Rune *r, int n, int advance)
{
	Rune *rbuf;

	if(rawon && t.q0==t.nr){
		addraw(r, n);
		return;
	}

	cut();
	if(n == 0)
		return;

	/*
	 * if this is a button2 execute then we might have been passed
	 * runes inside the buffer.  must save them before realloc.
	 */
	rbuf = nil;
	if(t.r <= r && r < t.r+n){
		rbuf = runemalloc(n);
		runemove(rbuf, r, n);
		r = rbuf;
	}

	insert(r, n, t.q0, 0);
	updatesel();
	free(rbuf);
}

void
fill(void)
{
	if (t.f->nlines >= t.f->maxlines)
		return;
	frinsert(t.f, t.r + t.org + t.f->nchars, t.r + t.nr, t.f->nchars);
}

void
updatesel(void)
{
	Frame *f;
	uint n;

	f = t.f;
	if(t.org+f->p0 == t.q0 && t.org+f->p1 == t.q1)
		return;

	n = t.f->nchars;

	frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
	if (t.q0 >= t.org)
		f->p0 = t.q0-t.org;
	else
		f->p0 = 0;
	if(f->p0 > n)
		f->p0 = n;
	if (t.q1 >= t.org)
		f->p1 = t.q1-t.org;
	else
		f->p1 = 0;
	if(f->p1 > n)
		f->p1 = n;
	frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 1);

/*
	if(t.qh<=t.org+t.f.nchars && t.cwqueue != 0)
		t.cwqueue->wakeup <-= 0;
*/

	tcheck();
}

void
show(uint q0)
{
	int nl;
	uint q, oq;

	if(cansee(q0))
		return;
	
	if (q0<t.org)
		nl = t.f->maxlines/5;
	else
		nl = 4*t.f->maxlines/5;
	q = backnl(q0, nl);
	/* avoid going in the wrong direction */
	if (q0>t.org && q<t.org)
		q = t.org;
	setorigin(q, 0);
	/* keep trying until q0 is on the screen */
	while(!cansee(q0)) {
		assert(q0 >= t.org);
		oq = q;
		q = line2q(t.f->maxlines-nl);
		assert(q > oq);
		setorigin(q, 1);
	}
}

int
cansee(uint q0)
{
	uint qe;

	qe = t.org+t.f->nchars;

	if(q0>=t.org && q0 < qe)
		return 1;
	if (q0 != qe)
		return 0;
	if (t.f->nlines < t.f->maxlines)
		return 1;
	if (q0 > 0 && t.r[t.nr-1] == '\n')
		return 0;
	return 1;
}


void
setorigin(uint org, int exact)
{
	int i, a;
	uint n;
	
	if(org>0 && !exact){
		/* try and start after a newline */
		/* don't try harder than 256 chars */
		for(i=0; i<256 && org<t.nr; i++){
			if(t.r[org-1] == '\n')
				break;
			org++;
		}
	}
	a = org-t.org;

	if(a>=0 && a<t.f->nchars)
		frdelete(t.f, 0, a);
	else if(a<0 && -a<100*t.f->maxlines){
		n = t.org - org;
		frinsert(t.f, t.r+org, t.r+org+n, 0);
	}else
		frdelete(t.f, 0, t.f->nchars);
	t.org = org;
	fill();
	updatesel();
}


uint
line2q(uint n)
{
	Frame *f;

	f = t.f;
	return frcharofpt(f, Pt(f->r.min.x, f->r.min.y + n*font->height))+t.org;
}

uint
backnl(uint p, uint n)
{
	int i, j;

	for (i = n;; i--) {
		/* at 256 chars, call it a line anyway */
		for(j=256; --j>0 && p>0; p--)
			if(t.r[p-1]=='\n')
				break;
		if (p == 0 || i == 0)
			return p;
		p--;
	}
	return 0; /* alef bug */
}

void
addraw(Rune *r, int nr)
{
	t.raw = runerealloc(t.raw, t.nraw+nr);
	runemove(t.raw+t.nraw, r, nr);
	t.nraw += nr;
/*
	if(t.crqueue != nil)
		t.crqueue->wakeup <-= 0;
*/	
}


Rune left1[] =  { '{', '[', '(', '<', 0xab, 0 };
Rune right1[] = { '}', ']', ')', '>', 0xbb, 0 };
Rune left2[] =  { '\n', 0 };
Rune left3[] =  { '\'', '"', '`', 0 };

Rune *left[] = {
	left1,
	left2,
	left3,
	0
};

Rune *right[] = {
	right1,
	left2,
	left3,
	0
};

void
doubleclick(uint *q0, uint *q1)
{
	int c, i;
	Rune *r, *l, *p;
	uint q;

	for(i=0; left[i]!=0; i++){
		q = *q0;
		l = left[i];
		r = right[i];
		/* try matching character to left, looking right */
		if(q == 0)
			c = '\n';
		else
			c = t.r[q-1];
		p = strrune(l, c);
		if(p != 0){
			if(clickmatch(c, r[p-l], 1, &q))
				*q1 = q-(c!='\n');
			return;
		}
		/* try matching character to right, looking left */
		if(q == t.nr)
			c = '\n';
		else
			c = t.r[q];
		p = strrune(r, c);
		if(p != 0){
			if(clickmatch(c, l[p-r], -1, &q)){
				*q1 = *q0+(*q0<t.nr && c=='\n');
				*q0 = q;
				if(c!='\n' || q!=0 || t.r[0]=='\n')
					(*q0)++;
			}
			return;
		}
	}
	/* try filling out word to right */
	while(*q1<t.nr && isalnum(t.r[*q1]))
		(*q1)++;
	/* try filling out word to left */
	while(*q0>0 && isalnum(t.r[*q0-1]))
		(*q0)--;
}

int
clickmatch(int cl, int cr, int dir, uint *q)
{
	Rune c;
	int nest;

	nest = 1;
	for(;;){
		if(dir > 0){
			if(*q == t.nr)
				break;
			c = t.r[*q];
			(*q)++;
		}else{
			if(*q == 0)
				break;
			(*q)--;
			c = t.r[*q];
		}
		if(c == cr){
			if(--nest==0)
				return 1;
		}else if(c == cl)
			nest++;
	}
	return cl=='\n' && nest==1;
}

void
tcheck(void)
{
	Frame *f;
		
	f = t.f;

	assert(t.q0 <= t.q1 && t.q1 <= t.nr);
	assert(t.org <= t.nr && t.qh <= t.nr);
	assert(f->p0 <= f->p1 && f->p1 <= f->nchars);
	assert(t.org + f->nchars <= t.nr);
	assert(t.org+f->nchars==t.nr || (f->nlines >= f->maxlines));
}

Rune*
strrune(Rune *s, Rune c)
{
	Rune c1;

	if(c == 0) {
		while(*s++)
			;
		return s-1;
	}

	while(c1 = *s++)
		if(c1 == c)
			return s-1;
	return 0;
}

void
scrdraw(void)
{
	Rectangle r, r1, r2;
	static Image *scrx;

	r = scrollr;
	r.min.x += 1;	/* border between margin and bar */
	r1 = r;
	if(scrx==0 || scrx->r.max.y < r.max.y){
		if(scrx)
			freeimage(scrx);
		scrx = allocimage(display, Rect(0, 0, 32, r.max.y), screen->chan, 1, DPaleyellow);
		if(scrx == 0)
			sysfatal("scroll balloc");
	}
	r1.min.x = 0;
	r1.max.x = Dx(r);
	r2 = scrpos(r1, t.org, t.org+t.f->nchars, t.nr);
	if(!eqrect(r2, lastsr)){
		lastsr = r2;
		draw(scrx, r1, cols[BORD], nil, ZP);
		draw(scrx, r2, cols[BACK], nil, r2.min);
//		r2 = r1;
//		r2.min.x = r2.max.x-1;
//		draw(scrx, r2, cols[BORD], nil, ZP);
		draw(screen, r, scrx, nil, r1.min);
	}
}

Rectangle
scrpos(Rectangle r, ulong p0, ulong p1, ulong tot)
{
	long h;
	Rectangle q;

	q = insetrect(r, 1);
	h = q.max.y-q.min.y;
	if(tot == 0)
		return q;
	if(tot > 1024L*1024L)
		tot >>= 10, p0 >>= 10, p1 >>= 10;
	if(p0 > 0)
		q.min.y += h*p0/tot;
	if(p1 < tot)
		q.max.y -= h*(tot-p1)/tot;
	if(q.max.y < q.min.y+2){
		if(q.min.y+2 <= r.max.y)
			q.max.y = q.min.y+2;
		else
			q.min.y = q.max.y-2;
	}
	return q;
}

void
scroll(int but)
{
	uint p0, oldp0;
	Rectangle s;
	int x, y, my, h, first, exact;

	s = insetrect(scrollr, 1);
	h = s.max.y-s.min.y;
	x = (s.min.x+s.max.x)/2;
	oldp0 = ~0;
	first = 1;
	do{
		if(t.m.xy.x<s.min.x || s.max.x<=t.m.xy.x){
			readmouse(mc);
			t.m = mc->m;
		}else{
			my = t.m.xy.y;
			if(my < s.min.y)
				my = s.min.y;
			if(my >= s.max.y)
				my = s.max.y;
//			if(!eqpt(t.m.xy, Pt(x, my)))
//				cursorset(Pt(x, my));
			exact = 1;
			if(but == 2){
				y = my;
				if(y > s.max.y-2)
					y = s.max.y-2;
				if(t.nr > 1024*1024)
					p0 = ((t.nr>>10)*(y-s.min.y)/h)<<10;
				else
					p0 = t.nr*(y-s.min.y)/h;
				exact = 0;
			} else if(but == 1)
				p0 = backnl(t.org, (my-s.min.y)/font->height);
			else 
				p0 = t.org+frcharofpt(t.f, Pt(s.max.x, my));

			if(oldp0 != p0)
				setorigin(p0, exact);
			oldp0 = p0;
			scrdraw();
			readmouse(mc);
			t.m = mc->m;
		}
	}while(t.m.buttons & (1<<(but-1)));
}

void
plumbstart(void)
{
	if((plumbfd = plumbopen("send", OWRITE)) < 0)
		fprint(2, "9term: plumbopen: %r\n");
}

void
plumb(uint q0, uint q1)
{
	Plumbmsg *pm;
	char *p;
	int i, p0, n;
	char cbuf[100];

	pm = malloc(sizeof(Plumbmsg));
	pm->src = strdup("9term");
	pm->dst = 0;
	pm->wdir = strdup(wdir);
	pm->type = strdup("text");
	pm->data = nil;
	if(q1 > q0)
		pm->attr = nil;
	else{
		p0 = q0;
		wordclick(&q0, &q1);
		sprint(cbuf, "click=%d", p0-q0);
		pm->attr = plumbunpackattr(cbuf);
	}
	if(q0==q1){
		plumbfree(pm);
		return;
	}
	pm->data = malloc(SnarfSize);
	n = q1 - q0;
	for(i=0,p=pm->data; i<n && p < pm->data + SnarfSize-UTFmax; i++)
		p += runetochar(p, t.r+q0+i);
	*p = '\0';
	pm->ndata = strlen(pm->data);
	plumbsend(plumbfd, pm);
	plumbfree(pm);
}

/*
 * Process in-band messages about window title changes.
 * The messages are of the form:
 *
 *	\033];xxx\007
 *
 * where xxx is the new directory.  This format was chosen
 * because it changes the label on xterm windows.
 */
int
label(Rune *sr, int n)
{
	Rune *sl, *el, *er, *r;

	er = sr+n;
	for(r=er-1; r>=sr; r--)
		if(*r == '\007')
			break;
	if(r < sr)
		return n;

	el = r+1;
	if(el-sr > sizeof wdir)
		sr = el - sizeof wdir;
	for(sl=el-3; sl>=sr; sl--)
		if(sl[0]=='\033' && sl[1]==']' && sl[2]==';')
			break;
	if(sl < sr)
		return n;

	snprint(wdir, sizeof wdir, "%.*S", (el-1)-(sl+3), sl+3);
	drawsetlabel(display, wdir);

	runemove(sl, el, er-el);
	n -= (el-sl);
	return n;
}

