#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <fcall.h>
#include <9pclient.h>
#include <plumb.h>
#include <complete.h>
#include "dat.h"
#include "fns.h"

#define MOVEIT if(0)

enum
{
	HiWater	= 64000000,	/* max size of history */
	LoWater	= 400000,	/* min size of history after max'ed */
	MinWater	= 20000	/* room to leave available when reallocating */
};

static	int		topped;
static	int		id;

static	Image	*cols[NCOL];
static	Image	*grey;
static	Image	*darkgrey;
static	Cursor	*lastcursor;
static	Image	*titlecol;
static	Image	*lighttitlecol;
static	Image	*holdcol;
static	Image	*lightholdcol;
static	Image	*paleholdcol;

static int
wscale(Window *w, int n)
{
	if(w == nil || w->i == nil)
		return n;
	return scalesize(w->i->display, n);
}

Window*
wmk(Image *i, Mousectl *mc, Channel *ck, Channel *cctl, int scrolling)
{
	Window *w;
	Rectangle r;

	if(cols[0] == nil){
		/* greys are multiples of 0x11111100+0xFF, 14* being palest */
		grey = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF);
		darkgrey = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x666666FF);
		cols[BACK] = display->white;
		cols[HIGH] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);
		cols[BORD] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x999999FF);
		cols[TEXT] = display->black;
		cols[HTEXT] = display->black;
		titlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreygreen);
		lighttitlecol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreygreen);
		holdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DMedblue);
		lightholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DGreyblue);
		paleholdcol = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPalegreyblue);
	}
	w = emalloc(sizeof(Window));
	w->screenr = i->r;
	r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1));
	w->i = i;
	w->mc = *mc;
	w->ck = ck;
	w->cctl = cctl;
	w->cursorp = nil;
	w->conswrite = chancreate(sizeof(Conswritemesg), 0);
	w->consread =  chancreate(sizeof(Consreadmesg), 0);
	w->mouseread =  chancreate(sizeof(Mousereadmesg), 0);
	w->wctlread =  chancreate(sizeof(Consreadmesg), 0);
	w->scrollr = r;
	w->scrollr.max.x = r.min.x+wscale(w, Scrollwid);
	w->lastsr = ZR;
	r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap);
	frinit(&w->f, r, font, i, cols);
	w->f.maxtab = maxtab*stringwidth(font, "0");
	w->topped = ++topped;
	w->id = ++id;
	w->notefd = -1;
	w->scrolling = scrolling;
	w->dir = estrdup(startdir);
	w->label = estrdup("<unnamed>");
	r = insetrect(w->i->r, wscale(w, Selborder));
	draw(w->i, r, cols[BACK], nil, w->f.entire.min);
	wborder(w, wscale(w, Selborder));
	wscrdraw(w);
	incref(&w->ref);	/* ref will be removed after mounting; avoids delete before ready to be deleted */
	return w;
}

void
wsetname(Window *w)
{
	int i, n;
	char err[ERRMAX];
	
	n = sprint(w->name, "window.%d.%d", w->id, w->namecount++);
	for(i='A'; i<='Z'; i++){
		if(nameimage(w->i, w->name, 1) > 0)
			return;
		errstr(err, sizeof err);
		if(strcmp(err, "image name in use") != 0)
			break;
		w->name[n] = i;
		w->name[n+1] = 0;
	}
	w->name[0] = 0;
	fprint(2, "rio: setname failed: %s\n", err);
}

void
wresize(Window *w, Image *i, int move)
{
	Rectangle r, or;

	or = w->i->r;
	if(move || (Dx(or)==Dx(i->r) && Dy(or)==Dy(i->r)))
		draw(i, i->r, w->i, nil, w->i->r.min);
	if(w->i != i){
fprint(2, "res %p %p\n", w->i, i);
		freeimage(w->i);
		w->i = i;
	}
/*	wsetname(w); */
/*XXX	w->mc.image = i; */
	r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1));
	w->scrollr = r;
	w->scrollr.max.x = r.min.x+wscale(w, Scrollwid);
	w->lastsr = ZR;
	r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap);
	if(move)
		frsetrects(&w->f, r, w->i);
	else{
		frclear(&w->f, FALSE);
		frinit(&w->f, r, w->f.font, w->i, cols);
		wsetcols(w);
		w->f.maxtab = maxtab*stringwidth(w->f.font, "0");
		r = insetrect(w->i->r, wscale(w, Selborder));
		draw(w->i, r, cols[BACK], nil, w->f.entire.min);
		wfill(w);
		wsetselect(w, w->q0, w->q1);
		wscrdraw(w);
	}
	wborder(w, wscale(w, Selborder));
	w->topped = ++topped;
	w->resized = TRUE;
	w->mouse.counter++;
}

void
wrefresh(Window *w, Rectangle r)
{
	/* USED(r); */

	/* BUG: rectangle is ignored */
	if(w == input)
		wborder(w, wscale(w, Selborder));
	else
		wborder(w, wscale(w, Unselborder));
	if(w->mouseopen)
		return;
	draw(w->i, insetrect(w->i->r, Borderwidth), w->f.cols[BACK], nil, w->i->r.min);
	w->f.ticked = 0;
	if(w->f.p0 > 0)
		frdrawsel(&w->f, frptofchar(&w->f, 0), 0, w->f.p0, 0);
	if(w->f.p1 < w->f.nchars)
		frdrawsel(&w->f, frptofchar(&w->f, w->f.p1), w->f.p1, w->f.nchars, 0);
	frdrawsel(&w->f, frptofchar(&w->f, w->f.p0), w->f.p0, w->f.p1, 1);
	w->lastsr = ZR;
	wscrdraw(w);
}

int
wclose(Window *w)
{
	int i;

	i = decref(&w->ref);
	if(i > 0)
		return 0;
	if(i < 0)
		error("negative ref count");
	if(!w->deleted)
		wclosewin(w);
	wsendctlmesg(w, Exited, ZR, nil);
	return 1;
}


void
winctl(void *arg)
{
	Rune *rp, *bp, *up, *kbdr;
	uint qh;
	int nr, nb, c, wid, i, npart, initial, lastb, scrolling;
	char *s, *t, part[UTFmax];
	Window *w;
	Mousestate *mp, m;
	enum { WKey, WMouse, WMouseread, WCtl, WCwrite, WCread, WWread, NWALT };
	Alt alts[NWALT+1];
	Mousereadmesg mrm;
	Conswritemesg cwm;
	Consreadmesg crm;
	Consreadmesg cwrm;
	Stringpair pair;
	Wctlmesg wcm;
	char buf[4*12+1];

	w = arg;
	snprint(buf, sizeof buf, "winctl-id%d", w->id);
	threadsetname(buf);

	mrm.cm = chancreate(sizeof(Mouse), 0);
	cwm.cw = chancreate(sizeof(Stringpair), 0);
	crm.c1 = chancreate(sizeof(Stringpair), 0);
	crm.c2 = chancreate(sizeof(Stringpair), 0);
	cwrm.c1 = chancreate(sizeof(Stringpair), 0);
	cwrm.c2 = chancreate(sizeof(Stringpair), 0);
	

	alts[WKey].c = w->ck;
	alts[WKey].v = &kbdr;
	alts[WKey].op = CHANRCV;
	alts[WMouse].c = w->mc.c;
	alts[WMouse].v = &w->mc.m;
	alts[WMouse].op = CHANRCV;
	alts[WMouseread].c = w->mouseread;
	alts[WMouseread].v = &mrm;
	alts[WMouseread].op = CHANSND;
	alts[WCtl].c = w->cctl;
	alts[WCtl].v = &wcm;
	alts[WCtl].op = CHANRCV;
	alts[WCwrite].c = w->conswrite;
	alts[WCwrite].v = &cwm;
	alts[WCwrite].op = CHANSND;
	alts[WCread].c = w->consread;
	alts[WCread].v = &crm;
	alts[WCread].op = CHANSND;
	alts[WWread].c = w->wctlread;
	alts[WWread].v = &cwrm;
	alts[WWread].op = CHANSND;
	alts[NWALT].op = CHANEND;

	npart = 0;
	lastb = -1;
	for(;;){
		if(w->mouseopen && w->mouse.counter != w->mouse.lastcounter)
			alts[WMouseread].op = CHANSND;
		else
			alts[WMouseread].op = CHANNOP;
		//	if(!w->scrolling && !w->mouseopen && w->qh>w->org+w->f.nchars)
		//		alts[WCwrite].op = CHANNOP;
		//	else
		alts[WCwrite].op = CHANSND;
		if(w->deleted || !w->wctlready)
			alts[WWread].op = CHANNOP;
		else
			alts[WWread].op = CHANSND;
		/* this code depends on NL and EOT fitting in a single byte */
		/* kind of expensive for each loop; worth precomputing? */
		if(w->holding)
			alts[WCread].op = CHANNOP;
		else if(npart || (w->rawing && w->nraw>0))
			alts[WCread].op = CHANSND;
		else{
			alts[WCread].op = CHANNOP;
			for(i=w->qh; i<w->nr; i++){
				c = w->r[i];
				if(c=='\n' || c=='\004'){
					alts[WCread].op = CHANSND;
					break;
				}
			}
		}
		switch(alt(alts)){
		case WKey:
			for(i=0; kbdr[i]!=L'\0'; i++)
				wkeyctl(w, kbdr[i]);
/*			wkeyctl(w, r); */
/*			while(nbrecv(w->ck, &r)) */
/*				wkeyctl(w, r); */
			break;
		case WMouse:
			if(w->mouseopen) {
				w->mouse.counter++;

				/* queue click events */
				if(!w->mouse.qfull && lastb != w->mc.m.buttons) {	/* add to ring */
					mp = &w->mouse.queue[w->mouse.wi];
					if(++w->mouse.wi == nelem(w->mouse.queue))
						w->mouse.wi = 0;
					if(w->mouse.wi == w->mouse.ri)
						w->mouse.qfull = TRUE;
					mp->m = w->mc.m;
					mp->counter = w->mouse.counter;
					lastb = w->mc.m.buttons;
				}
			} else
				wmousectl(w);
			break;
		case WMouseread:
			/* send a queued event or, if the queue is empty, the current state */
			/* if the queue has filled, we discard all the events it contained. */
			/* the intent is to discard frantic clicking by the user during long latencies. */
			w->mouse.qfull = FALSE;
			if(w->mouse.wi != w->mouse.ri) {
				m = w->mouse.queue[w->mouse.ri];
				if(++w->mouse.ri == nelem(w->mouse.queue))
					w->mouse.ri = 0;
			} else {
				m.m = w->mc.m;
				m.counter = w->mouse.counter;
			}
			w->mouse.lastcounter = m.counter;
			send(mrm.cm, &m.m);
			continue;
		case WCtl:
			if(wctlmesg(w, wcm.type, wcm.r, wcm.image) == Exited){
				chanfree(crm.c1);
				chanfree(crm.c2);
				chanfree(mrm.cm);
				chanfree(cwm.cw);
				chanfree(cwrm.c1);
				chanfree(cwrm.c2);
				threadexits(nil);
			}
			continue;
		case WCwrite:
			recv(cwm.cw, &pair);
			rp = pair.s;
			nr = pair.ns;
			bp = rp;
			up = rp;
			initial = 0;
			for(i=0; i<nr; i++){
				switch(*bp){
				case 0:
					break;
				case '\b':
					if(up == rp)
						initial++;
					else
						--up;
					break;
				case '\r':
					while(i<nr-1 && *(bp+1) == '\r'){
						bp++;
						i++;
					}
					if(i<nr-1 && *(bp+1) != '\n'){
						while(up > rp && *(up-1) != '\n')
							up--;
						if(up == rp)
							initial = wbswidth(w, '\r');
					}else if(i == nr-1)
						*up = '\n';
					break;
				default:
					*up++ = *bp;
					break;
				}
				bp++;
			}
			if(initial){
				if(initial > w->qh)
					initial = w->qh;
				qh = w->qh - initial;
				wdelete(w, qh, qh+initial);
				w->qh = qh;
			}
			nr = up - rp;
			scrolling = w->scrolling && w->org <= w->qh && w->qh <= w->org + w->f.nchars;
			w->qh = winsert(w, rp, nr, w->qh)+nr;
			if(scrolling)
				wshow(w, w->qh);
			wsetselect(w, w->q0, w->q1);
			wscrdraw(w);
			free(rp);
			break;
		case WCread:
			recv(crm.c1, &pair);
			t = pair.s;
			nb = pair.ns;
			i = npart;
			npart = 0;
			if(i)
				memmove(t, part, i);
			while(i<nb && (w->qh<w->nr || w->nraw>0)){
				if(w->qh == w->nr){
					wid = runetochar(t+i, &w->raw[0]);
					w->nraw--;
					runemove(w->raw, w->raw+1, w->nraw);
				}else
					wid = runetochar(t+i, &w->r[w->qh++]);
				c = t[i];	/* knows break characters fit in a byte */
				i += wid;
				if(!w->rawing && (c == '\n' || c=='\004')){
				/*	if(c == '\004') */
				/*		i--; */
					break;
				}
			}
		/*	if(i==nb && w->qh<w->nr && w->r[w->qh]=='\004') */
		/*		w->qh++; */
			if(i > nb){
				npart = i-nb;
				memmove(part, t+nb, npart);
				i = nb;
			}
			pair.s = t;
			pair.ns = i;
			send(crm.c2, &pair);
			continue;
		case WWread:
			w->wctlready = 0;
			recv(cwrm.c1, &pair);
			if(w->deleted || w->i==nil)
				pair.ns = sprint(pair.s, "");
			else{
				s = "visible";
				for(i=0; i<nhidden; i++)
					if(hidden[i] == w){
						s = "hidden";
						break;
					}
				t = "notcurrent";
				if(w == input)
					t = "current";
				pair.ns = snprint(pair.s, pair.ns, "%11d %11d %11d %11d %s %s ",
					w->i->r.min.x, w->i->r.min.y, w->i->r.max.x, w->i->r.max.y, t, s);
			}
			send(cwrm.c2, &pair);
			continue;
		}
		if(!w->deleted)
			flushimage(display, 1);
	}
}

void
waddraw(Window *w, Rune *r, int nr)
{
	w->raw = runerealloc(w->raw, w->nraw+nr);
	runemove(w->raw+w->nraw, r, nr);
	w->nraw += nr;
}

/*
 * Need to do this in a separate proc because if process we're interrupting
 * is dying and trying to print tombstone, kernel is blocked holding p->debug lock.
 */
void
interruptproc(void *v)
{
	int *notefd;

	notefd = v;
	write(*notefd, "interrupt", 9);
	free(notefd);
}

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

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

void
showcandidates(Window *w, 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 = w->qh;
	while(qline>0 && w->r[qline-1] != '\n')
		qline--;

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

	q0 = w->q0;
	q0 += winsert(w, rp, runestrlen(rp), qline) - qline;
	free(rp);
	wsetselect(w, q0+nr, q0+nr);
}

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

	/* control-f: filename completion; works back to white space or / */
	if(w->q0<w->nr && w->r[w->q0]>' ')	/* must be at end of word */
		return nil;
	nstr = windfilewidth(w, w->q0, TRUE);
	str = runemalloc(nstr);
	runemove(str, w->r+(w->q0-nstr), nstr);
	npath = windfilewidth(w, w->q0-nstr, FALSE);
	path = runemalloc(npath);
	runemove(path, w->r+(w->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(w->dir, "") == 0)
			root = ".";
		else
			root = w->dir;
		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(w, c);

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

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

void
wkeyctl(Window *w, Rune r)
{
	uint q0 ,q1;
	int n, nb, nr;
	Rune *rp;

	if(r == 0)
		return;
	if(w->deleted)
		return;
	w->rawing = rawon();
	/* navigation keys work only when mouse is not open */
	if(!w->mouseopen)
		switch(r){
		case Kdown:
			n = w->f.maxlines/3;
			goto case_Down;
		case Kscrollonedown:
			n = mousescrollsize(w->f.maxlines);
			if(n <= 0)
				n = 1;
			goto case_Down;
		case Kpgdown:
			n = 2*w->f.maxlines/3;
		case_Down:
			q0 = w->org+frcharofpt(&w->f, Pt(w->f.r.min.x, w->f.r.min.y+n*w->f.font->height));
			wsetorigin(w, q0, TRUE);
			return;
		case Kup:
			n = w->f.maxlines/3;
			goto case_Up;
		case Kscrolloneup:
			n = mousescrollsize(w->f.maxlines);
			if(n <= 0)
				n = 1;
			goto case_Up;
		case Kpgup:
			n = 2*w->f.maxlines/3;
		case_Up:
			q0 = wbacknl(w, w->org, n);
			wsetorigin(w, q0, TRUE);
			return;
		case Kleft:
			if(w->q0 > 0){
				q0 = w->q0-1;
				wsetselect(w, q0, q0);
				wshow(w, q0);
			}
			return;
		case Kright:
			if(w->q1 < w->nr){
				q1 = w->q1+1;
				wsetselect(w, q1, q1);
				wshow(w, q1);
			}
			return;
		case Khome:
			if(w->org > w->iq1) {
				q0 = wbacknl(w, w->iq1, 1);
				wsetorigin(w, q0, TRUE);
			} else
				wshow(w, 0);
			return;
		case Kend:
			if(w->iq1 > w->org+w->f.nchars) {
				q0 = wbacknl(w, w->iq1, 1);
				wsetorigin(w, q0, TRUE);
			} else
				wshow(w, w->nr);
			return;
		case 0x01:	/* ^A: beginning of line */
			if(w->q0==0 || w->q0==w->qh || w->r[w->q0-1]=='\n')
				return;
			nb = wbswidth(w, 0x15 /* ^U */);
			wsetselect(w, w->q0-nb, w->q0-nb);
			wshow(w, w->q0);
			return;
		case 0x05:	/* ^E: end of line */
			q0 = w->q0;
			while(q0 < w->nr && w->r[q0]!='\n')
				q0++;
			wsetselect(w, q0, q0);
			wshow(w, w->q0);
			return;
		}
	/*
	 * This if used to be below the if(w->rawing ...),
	 * but let's try putting it here.  This will allow ESC-processing
	 * to toggle hold mode even in remote SSH connections.
	 * The drawback is that vi-style processing gets harder.
	 * If you find yourself in some weird readline mode, good
	 * luck getting out without ESC.  Let's see who complains.
	 */
	if(r==0x1B || (w->holding && r==0x7F)){	/* toggle hold */
		if(w->holding)
			--w->holding;
		else
			w->holding++;
		wrepaint(w);
		if(r == 0x1B)
			return;
	}
	if(!w->holding && w->rawing && (w->q0==w->nr || w->mouseopen)){
		waddraw(w, &r, 1);
		return;
	}
	if(r == Kcmd+'x'){
		wsnarf(w);
		wcut(w);
		wscrdraw(w);
		return;
	}
	if(r == Kcmd+'c'){
		wsnarf(w);
		return;
	}
	if(r == Kcmd+'v'){
		riogetsnarf();
		wpaste(w);
		wscrdraw(w);
		return;
	}
	if(r != 0x7F){
		wsnarf(w);
		wcut(w);
	}
	switch(r){
	case 0x7F:		/* send interrupt */
		w->qh = w->nr;
		wshow(w, w->qh);
		winterrupt(w);
		w->iq1 = w->q0;
		return;
	case 0x06:	/* ^F: file name completion */
	case Kins:		/* Insert: file name completion */
		rp = namecomplete(w);
		if(rp == nil)
			return;
		nr = runestrlen(rp);
		q0 = w->q0;
		q0 = winsert(w, rp, nr, q0);
		wshow(w, q0+nr);
		w->iq1 = w->q0;
		free(rp);
		return;
	case 0x08:	/* ^H: erase character */
	case 0x15:	/* ^U: erase line */
	case 0x17:	/* ^W: erase word */
		if(w->q0==0 || w->q0==w->qh)
			return;
		nb = wbswidth(w, r);
		q1 = w->q0;
		q0 = q1-nb;
		if(q0 < w->org){
			q0 = w->org;
			nb = q1-q0;
		}
		if(nb > 0){
			wdelete(w, q0, q0+nb);
			wsetselect(w, q0, q0);
		}
		w->iq1 = w->q0;
		return;
	}
	/* otherwise ordinary character; just insert */
	q0 = w->q0;
	q0 = winsert(w, &r, 1, q0);
	wshow(w, q0+1);
	w->iq1 = w->q0;
}

void
wsetcols(Window *w)
{
	if(w->holding)
		if(w == input)
			w->f.cols[TEXT] = w->f.cols[HTEXT] = holdcol;
		else
			w->f.cols[TEXT] = w->f.cols[HTEXT] = lightholdcol;
	else
		if(w == input)
			w->f.cols[TEXT] = w->f.cols[HTEXT] = display->black;
		else
			w->f.cols[TEXT] = w->f.cols[HTEXT] = darkgrey;
}

void
wrepaint(Window *w)
{
	wsetcols(w);
	if(!w->mouseopen){
		frredraw(&w->f);
	}
	if(w == input){
		wborder(w, wscale(w, Selborder));
		wsetcursor(w, 0);
	}else
		wborder(w, wscale(w, Unselborder));
}

int
wbswidth(Window *w, 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 = w->q0;
	stop = 0;
	if(q > w->qh)
		stop = w->qh;
	skipping = TRUE;
	while(q > stop){
		r = w->r[q-1];
		if(r == '\n'){		/* eat at most one more character */
			if(q == w->q0 && c != '\r')	/* eat the newline */
				--q;
			break; 
		}
		if(c == 0x17){
			eq = isalnum(r);
			if(eq && skipping)	/* found one; stop skipping */
				skipping = FALSE;
			else if(!eq && !skipping)
				break;
		}
		--q;
	}
	return w->q0-q;
}

void
wsnarf(Window *w)
{
	if(w->q1 == w->q0)
		return;
	nsnarf = w->q1-w->q0;
	snarf = runerealloc(snarf, nsnarf);
	snarfversion++;	/* maybe modified by parent */
	runemove(snarf, w->r+w->q0, nsnarf);
	rioputsnarf();
}

void
wcut(Window *w)
{
	if(w->q1 == w->q0)
		return;
	wdelete(w, w->q0, w->q1);
	wsetselect(w, w->q0, w->q0);
}

void
wpaste(Window *w)
{
	uint q0;

	if(nsnarf == 0)
		return;
	wcut(w);
	q0 = w->q0;
	if(w->rawing && !w->holding && q0==w->nr){
		waddraw(w, snarf, nsnarf);
		wsetselect(w, q0, q0);
	}else{
		q0 = winsert(w, snarf, nsnarf, w->q0);
		wsetselect(w, q0, q0+nsnarf);
	}
}

void
wplumb(Window *w)
{
	Plumbmsg *m;
	static CFid *fd;
	char buf[32];
	uint p0, p1;
	Cursor *c;

	if(fd == nil)
		fd = plumbopenfid("send", OWRITE);
	if(fd == nil)
		return;
	m = emalloc(sizeof(Plumbmsg));
	m->src = estrdup("rio");
	m->dst = nil;
	m->wdir = estrdup(w->dir);
	m->type = estrdup("text");
	p0 = w->q0;
	p1 = w->q1;
	if(w->q1 > w->q0)
		m->attr = nil;
	else{
		while(p0>0 && w->r[p0-1]!=' ' && w->r[p0-1]!='\t' && w->r[p0-1]!='\n')
			p0--;
		while(p1<w->nr && w->r[p1]!=' ' && w->r[p1]!='\t' && w->r[p1]!='\n')
			p1++;
		sprint(buf, "click=%d", w->q0-p0);
		m->attr = plumbunpackattr(buf);
	}
	if(p1-p0 > messagesize-1024){
		plumbfree(m);
		return;	/* too large for 9P */
	}
	m->data = runetobyte(w->r+p0, p1-p0, &m->ndata);
	if(plumbsendtofid(fd, m) < 0){
		c = lastcursor;
		riosetcursor(&query, 1);
		sleep(300);
		riosetcursor(c, 1);
	}
	plumbfree(m);
}

int
winborder(Window *w, Point xy)
{
	return ptinrect(xy, w->screenr) && !ptinrect(xy, insetrect(w->screenr, wscale(w, Selborder)));
}

void
wmousectl(Window *w)
{
	int but;

	if(w->mc.m.buttons == 1)
		but = 1;
	else if(w->mc.m.buttons == 2)
		but = 2;
	else if(w->mc.m.buttons == 4)
		but = 3;
	else{
		if(w->mc.m.buttons == 8)
			wkeyctl(w, Kscrolloneup);
		if(w->mc.m.buttons == 16)
			wkeyctl(w, Kscrollonedown);
		return;
	}

	incref(&w->ref);		/* hold up window while we track */
	if(w->deleted)
		goto Return;
	if(ptinrect(w->mc.m.xy, w->scrollr)){
		if(but)
			wscroll(w, but);
		goto Return;
	}
	if(but == 1)
		wselect(w);
	/* else all is handled by main process */
   Return:
	wclose(w);
}

void
wdelete(Window *w, uint q0, uint q1)
{
	uint n, p0, p1;

	n = q1-q0;
	if(n == 0)
		return;
	runemove(w->r+q0, w->r+q1, w->nr-q1);
	w->nr -= n;
	if(q0 < w->iq1)
		w->iq1 -= min(n, w->iq1-q0);
	if(q0 < w->q0)
		w->q0 -= min(n, w->q0-q0);
	if(q0 < w->q1)
		w->q1 -= min(n, w->q1-q0);
	if(q1 < w->qh)
		w->qh -= n;
	else if(q0 < w->qh)
		w->qh = q0;
	if(q1 <= w->org)
		w->org -= n;
	else if(q0 < w->org+w->f.nchars){
		p1 = q1 - w->org;
		if(p1 > w->f.nchars)
			p1 = w->f.nchars;
		if(q0 < w->org){
			w->org = q0;
			p0 = 0;
		}else
			p0 = q0 - w->org;
		frdelete(&w->f, p0, p1);
		wfill(w);
	}
}


static Window	*clickwin;
static uint	clickmsec;
static Window	*selectwin;
static uint	selectq;

/*
 * called from frame library
 */
void
framescroll(Frame *f, int dl)
{
	if(f != &selectwin->f)
		error("frameselect not right frame");
	wframescroll(selectwin, dl);
}

void
wframescroll(Window *w, int dl)
{
	uint q0;

	if(dl == 0){
		wscrsleep(w, 100);
		return;
	}
	if(dl < 0){
		q0 = wbacknl(w, w->org, -dl);
		if(selectq > w->org+w->f.p0)
			wsetselect(w, w->org+w->f.p0, selectq);
		else
			wsetselect(w, selectq, w->org+w->f.p0);
	}else{
		if(w->org+w->f.nchars == w->nr)
			return;
		q0 = w->org+frcharofpt(&w->f, Pt(w->f.r.min.x, w->f.r.min.y+dl*w->f.font->height));
		if(selectq >= w->org+w->f.p1)
			wsetselect(w, w->org+w->f.p1, selectq);
		else
			wsetselect(w, selectq, w->org+w->f.p1);
	}
	wsetorigin(w, q0, TRUE);
}

void
wselect(Window *w)
{
	uint q0, q1;
	int b, x, y, first;

	first = 1;
	selectwin = w;
	/*
	 * Double-click immediately if it might make sense.
	 */
	b = w->mc.m.buttons;
	q0 = w->q0;
	q1 = w->q1;
	selectq = w->org+frcharofpt(&w->f, w->mc.m.xy);
	if(clickwin==w && w->mc.m.msec-clickmsec<500)
	if(q0==q1 && selectq==w->q0){
		wdoubleclick(w, &q0, &q1);
		wsetselect(w, q0, q1);
		flushimage(display, 1);
		x = w->mc.m.xy.x;
		y = w->mc.m.xy.y;
		/* stay here until something interesting happens */
		do
			readmouse(&w->mc);
		while(w->mc.m.buttons==b && abs(w->mc.m.xy.x-x)<3 && abs(w->mc.m.xy.y-y)<3);
		w->mc.m.xy.x = x;	/* in case we're calling frselect */
		w->mc.m.xy.y = y;
		q0 = w->q0;	/* may have changed */
		q1 = w->q1;
		selectq = q0;
	}
	if(w->mc.m.buttons == b){
		w->f.scroll = framescroll;
		frselect(&w->f, &w->mc);
		/* horrible botch: while asleep, may have lost selection altogether */
		if(selectq > w->nr)
			selectq = w->org + w->f.p0;
		w->f.scroll = nil;
		if(selectq < w->org)
			q0 = selectq;
		else
			q0 = w->org + w->f.p0;
		if(selectq > w->org+w->f.nchars)
			q1 = selectq;
		else
			q1 = w->org+w->f.p1;
	}
	if(q0 == q1){
		if(q0==w->q0 && clickwin==w && w->mc.m.msec-clickmsec<500){
			wdoubleclick(w, &q0, &q1);
			clickwin = nil;
		}else{
			clickwin = w;
			clickmsec = w->mc.m.msec;
		}
	}else
		clickwin = nil;
	wsetselect(w, q0, q1);
	flushimage(display, 1);
	while(w->mc.m.buttons){
		w->mc.m.msec = 0;
		b = w->mc.m.buttons;
		if(b & 6){
			if(b & 2){
				wsnarf(w);
				wcut(w);
			}else{
				if(first){
					first = 0;
					riogetsnarf();
				}
				wpaste(w);
			}
		}
		wscrdraw(w);
		flushimage(display, 1);
		while(w->mc.m.buttons == b)
			readmouse(&w->mc);
		clickwin = nil;
	}
}

void
wsendctlmesg(Window *w, int type, Rectangle r, Image *image)
{
	Wctlmesg wcm;

	wcm.type = type;
	wcm.r = r;
	wcm.image = image;
	send(w->cctl, &wcm);
}

int
wctlmesg(Window *w, int m, Rectangle r, Image *i)
{
	char buf[64];

	switch(m){
	default:
		error("unknown control message");
		break;
	case Wakeup:
		break;
	case Moved:
	case Reshaped:
		if(w->deleted){
			freeimage(i);
			break;
		}
		w->screenr = r;
		strcpy(buf, w->name);
		wresize(w, i, m==Moved);
		w->wctlready = 1;
		if(Dx(r) > 0){
			if(w != input)
				wcurrent(w);
		}else if(w == input)
			wcurrent(nil);
		flushimage(display, 1);
		break;
	case Refresh:
		if(w->deleted || Dx(w->screenr)<=0 || !rectclip(&r, w->i->r))
			break;
		if(!w->mouseopen)
			wrefresh(w, r);
		flushimage(display, 1);
		break;
	case Movemouse:
		if(sweeping || !ptinrect(r.min, w->i->r))
			break;
		wmovemouse(w, r.min);
	case Rawon:
		break;
	case Rawoff:
		if(w->deleted)
			break;
		while(w->nraw > 0){
			wkeyctl(w, w->raw[0]);
			--w->nraw;
			runemove(w->raw, w->raw+1, w->nraw);
		}
		break;
	case Holdon:
	case Holdoff:
		if(w->deleted)
			break;
		wrepaint(w);
		flushimage(display, 1);
		break;
	case Deleted:
		if(w->deleted)
			break;
		write(w->notefd, "hangup", 6);
		wclosewin(w);
		break;
	case Exited:
		frclear(&w->f, TRUE);
		close(w->notefd);
		chanfree(w->mc.c);
		chanfree(w->ck);
		chanfree(w->cctl);
		chanfree(w->conswrite);
		chanfree(w->consread);
		chanfree(w->mouseread);
		chanfree(w->wctlread);
		free(w->raw);
		free(w->r);
		free(w->dir);
		free(w->label);
		free(w);
		break;
	}
	return m;
}

/*
 * Convert back to physical coordinates
 */
void
wmovemouse(Window *w, Point p)
{
	p.x += w->screenr.min.x-w->i->r.min.x;
	p.y += w->screenr.min.y-w->i->r.min.y;
	moveto(mousectl, p);
}

void
wcurrent(Window *w)
{
	Window *oi;

	if(wkeyboard!=nil && w==wkeyboard)
		return;
	oi = input;
	input = w;
	if(oi!=w && oi!=nil)
		wrepaint(oi);
	if(w !=nil){
		wrepaint(w);
		wsetcursor(w, 0);
	}
	if(w != oi){
		if(oi){
			oi->wctlready = 1;
			wsendctlmesg(oi, Wakeup, ZR, nil);
		}
		if(w){
			w->wctlready = 1;
			wsendctlmesg(w, Wakeup, ZR, nil);
		}
	}
}

void
wsetcursor(Window *w, int force)
{
	Cursor *p;

	if(w==nil || /*w!=input || */ w->i==nil || Dx(w->screenr)<=0)
		p = nil;
	else if(wpointto(mouse->xy) == w){
		p = w->cursorp;
		if(p==nil && w->holding)
			p = &whitearrow;
	}else
		p = nil;
	if(!menuing)
		riosetcursor(p, force && !menuing);
}

void
riosetcursor(Cursor *p, int force)
{
	if(!force && p==lastcursor)
		return;
	setcursor(mousectl, p);
	lastcursor = p;
}

Window*
wtop(Point pt)
{
	Window *w;

	w = wpointto(pt);
	if(w){
		if(w->topped == topped)
			return nil;
		topwindow(w->i);
		wcurrent(w);
		flushimage(display, 1);
		w->topped = ++topped;
	}
	return w;
}

void
wtopme(Window *w)
{
	if(w!=nil && w->i!=nil && !w->deleted && w->topped!=topped){
		topwindow(w->i);
		flushimage(display, 1);
		w->topped = ++ topped;
	}
}

void
wbottomme(Window *w)
{
	if(w!=nil && w->i!=nil && !w->deleted){
		bottomwindow(w->i);
		flushimage(display, 1);
		w->topped = 0;
	}
}

Window*
wlookid(int id)
{
	int i;

	for(i=0; i<nwindow; i++)
		if(window[i]->id == id)
			return window[i];
	return nil;
}

void
wclosewin(Window *w)
{
	Rectangle r;
	int i;

	w->deleted = TRUE;
	if(w == input){
		input = nil;
		wsetcursor(w, 0);
	}
	if(w == wkeyboard)
		wkeyboard = nil;
	for(i=0; i<nhidden; i++)
		if(hidden[i] == w){
			--nhidden;
			memmove(hidden+i, hidden+i+1, (nhidden-i)*sizeof(hidden[0]));
			break;
		}
	for(i=0; i<nwindow; i++)
		if(window[i] == w){
			--nwindow;
			memmove(window+i, window+i+1, (nwindow-i)*sizeof(Window*));
			w->deleted = TRUE;
			r = w->i->r;
			/* move it off-screen to hide it, in case client is slow in letting it go */
			MOVEIT originwindow(w->i, r.min, view->r.max);
			freeimage(w->i);
			w->i = nil;
			return;
		}
	error("unknown window in closewin");
}

void
wsetpid(Window *w, int pid, int dolabel)
{
	char buf[128];

	w->pid = pid;
	if(dolabel){
		sprint(buf, "rc %d", pid);
		free(w->label);
		w->label = estrdup(buf);
		drawsetlabel(w->label);
	}
}

static Rune left1[] =  { 
	'{', '[', '(', '<', 0xAB,
	0x207d, 0x2329, 0x27e6, 0x27e8, 0x27ea, 
	0xfe59, 0xfe5b, 0xfe5d, 0xff08, 0xff3b, 0xff5b, 
	0
};
static Rune right1[] = {
	'}', ']', ')', '>', 0xBB,
	0x207e, 0x232a, 0x27e7, 0x27e9, 0x27eb, 
	0xfe5a, 0xfe5c, 0xfe5e, 0xff09, 0xff3d, 0xff5d,
	0
};
static Rune left2[] =  { '\n', 0 };
static Rune left3[] =  { '\'', '"', '`', 0 };

Rune *left[] = {
	left1,
	left2,
	left3,
	nil
};
Rune *right[] = {
	right1,
	left2,
	left3,
	nil
};

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

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

int
wclickmatch(Window *w, int cl, int cr, int dir, uint *q)
{
	Rune c;
	int nest;

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


uint
wbacknl(Window *w, uint p, uint n)
{
	int i, j;

	/* look for start of this line if n==0 */
	if(n==0 && p>0 && w->r[p-1]!='\n')
		n = 1;
	i = n;
	while(i-->0 && p>0){
		--p;	/* it's at a newline now; back over it */
		if(p == 0)
			break;
		/* at 128 chars, call it a line anyway */
		for(j=128; --j>0 && p>0; p--)
			if(w->r[p-1]=='\n')
				break;
	}
	return p;
}

void
wshow(Window *w, uint q0)
{
	int qe;
	int nl;
	uint q;

	qe = w->org+w->f.nchars;
	if(w->org<=q0 && (q0<qe || (q0==qe && qe==w->nr)))
		wscrdraw(w);
	else{
		nl = 4*w->f.maxlines/5;
		q = wbacknl(w, q0, nl);
		/* avoid going backwards if trying to go forwards - long lines! */
		if(!(q0>w->org && q<w->org))
			wsetorigin(w, q, TRUE);
		while(q0 > w->org+w->f.nchars)
			wsetorigin(w, w->org+1, FALSE);
	}
}

void
wsetorigin(Window *w, uint org, int exact)
{
	int i, a, fixup;
	Rune *r;
	uint n;

	if(org>0 && !exact){
		/* org is an estimate of the char posn; find a newline */
		/* don't try harder than 256 chars */
		for(i=0; i<256 && org<w->nr; i++){
			if(w->r[org] == '\n'){
				org++;
				break;
			}
			org++;
		}
	}
	a = org-w->org;
	fixup = 0;
	if(a>=0 && a<w->f.nchars){
		frdelete(&w->f, 0, a);
		fixup = 1;	/* frdelete can leave end of last line in wrong selection mode; it doesn't know what follows */
	}else if(a<0 && -a<w->f.nchars){
		n = w->org - org;
		r = runemalloc(n);
		runemove(r, w->r+org, n);
		frinsert(&w->f, r, r+n, 0);
		free(r);
	}else
		frdelete(&w->f, 0, w->f.nchars);
	w->org = org;
	wfill(w);
	wscrdraw(w);
	wsetselect(w, w->q0, w->q1);
	if(fixup && w->f.p1 > w->f.p0)
		frdrawsel(&w->f, frptofchar(&w->f, w->f.p1-1), w->f.p1-1, w->f.p1, 1);
}

void
wsetselect(Window *w, uint q0, uint q1)
{
	int p0, p1;

	/* w->f.p0 and w->f.p1 are always right; w->q0 and w->q1 may be off */
	w->q0 = q0;
	w->q1 = q1;
	/* compute desired p0,p1 from q0,q1 */
	p0 = q0-w->org;
	p1 = q1-w->org;
	if(p0 < 0)
		p0 = 0;
	if(p1 < 0)
		p1 = 0;
	if(p0 > w->f.nchars)
		p0 = w->f.nchars;
	if(p1 > w->f.nchars)
		p1 = w->f.nchars;
	if(p0==w->f.p0 && p1==w->f.p1)
		return;
	/* screen disagrees with desired selection */
	if(w->f.p1<=p0 || p1<=w->f.p0 || p0==p1 || w->f.p1==w->f.p0){
		/* no overlap or too easy to bother trying */
		frdrawsel(&w->f, frptofchar(&w->f, w->f.p0), w->f.p0, w->f.p1, 0);
		frdrawsel(&w->f, frptofchar(&w->f, p0), p0, p1, 1);
		goto Return;
	}
	/* overlap; avoid unnecessary painting */
	if(p0 < w->f.p0){
		/* extend selection backwards */
		frdrawsel(&w->f, frptofchar(&w->f, p0), p0, w->f.p0, 1);
	}else if(p0 > w->f.p0){
		/* trim first part of selection */
		frdrawsel(&w->f, frptofchar(&w->f, w->f.p0), w->f.p0, p0, 0);
	}
	if(p1 > w->f.p1){
		/* extend selection forwards */
		frdrawsel(&w->f, frptofchar(&w->f, w->f.p1), w->f.p1, p1, 1);
	}else if(p1 < w->f.p1){
		/* trim last part of selection */
		frdrawsel(&w->f, frptofchar(&w->f, p1), p1, w->f.p1, 0);
	}

    Return:
	w->f.p0 = p0;
	w->f.p1 = p1;
}

uint
winsert(Window *w, Rune *r, int n, uint q0)
{
	uint m;

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

void
wfill(Window *w)
{
	Rune *rp;
	int i, n, m, nl;

	if(w->f.lastlinefull)
		return;
	rp = malloc(messagesize);
	do{
		n = w->nr-(w->org+w->f.nchars);
		if(n == 0)
			break;
		if(n > 2000)	/* educated guess at reasonable amount */
			n = 2000;
		runemove(rp, w->r+(w->org+w->f.nchars), n);
		/*
		 * it's expensive to frinsert more than we need, so
		 * count newlines.
		 */
		nl = w->f.maxlines-w->f.nlines;
		m = 0;
		for(i=0; i<n; ){
			if(rp[i++] == '\n'){
				m++;
				if(m >= nl)
					break;
			}
		}
		frinsert(&w->f, rp, rp+i, w->f.nchars);
	}while(w->f.lastlinefull == FALSE);
	free(rp);
}

char*
wcontents(Window *w, int *ip)
{
	return runetobyte(w->r, w->nr, ip);
}
