#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 <plumb.h>
#include "flayer.h"
#include "samterm.h"

#define	HSIZE	3	/* Type + short count */
Header	h;
uchar	indata[DATASIZE+1];	/* room for NUL */
uchar	outdata[DATASIZE];
short	outcount;
int	hversion;
int	hostfd[2];

void	inmesg(Hmesg, int);
int	inshort(int);
long	inlong(int);
long	invlong(int);
void	hsetdot(int, long, long);
void	hmoveto(int, long);
void	hsetsnarf(int);
void	hplumb(int);
void	clrlock(void);
int	snarfswap(char*, int, char**);

void
rcv(void)
{
	int c;
	static int state = 0;
	static int count = 0;
	static int i = 0;
	static int errs = 0;

	while((c=rcvchar()) != -1)
		switch(state){
		case 0:
			h.type = c;
			state++;
			break;

		case 1:
			h.count0 = c;
			state++;
			break;

		case 2:
			h.count1 = c;
			count = h.count0|(h.count1<<8);
			i = 0;
			if(count > DATASIZE){
				if(++errs < 5){
					dumperrmsg(count, h.type, h.count0, c);
					state = 0;
					continue;
				}
				fprint(2, "type %d count %d\n", h.type, count);
				panic("count>DATASIZE");
			}
			if(count == 0)
				goto zerocount;
			state++;
			break;

		case 3:
			indata[i++] = c;
			if(i == count){
		zerocount:
				indata[i] = 0;
				inmesg(h.type, count);
				state = count = 0;
				continue;
			}
			break;
		}
}

Text *
whichtext(int tg)
{
	int i;

	for(i=0; i<nname; i++)
		if(tag[i] == tg)
			return text[i];
	panic("whichtext");
	return 0;
}

void
inmesg(Hmesg type, int count)
{
	Text *t;
	int i, m;
	long l;
	Flayer *lp;

	m = inshort(0);
	l = inlong(2);
	switch(type){
	case -1:
		panic("rcv error");
	default:
		fprint(2, "type %d\n", type);
		panic("rcv unknown");

	case Hversion:
		hversion = m;
		break;

	case Hbindname:
		l = invlong(2);		/* for 64-bit pointers */
		if((i=whichmenu(m)) < 0)
			break;
		/* in case of a race, a bindname may already have occurred */
		if((t=whichtext(m)) == 0)
			t=(Text *)l;
		else	/* let the old one win; clean up the new one */
			while(((Text *)l)->nwin>0)
				closeup(&((Text *)l)->l[((Text *)l)->front]);
		text[i] = t;
		text[i]->tag = m;
		break;

	case Hcurrent:
		if(whichmenu(m)<0)
			break;
		t = whichtext(m);
		i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
		if(t==0 && (t = sweeptext(0, m))==0)
			break;
		if(t->l[t->front].textfn==0)
			panic("Hcurrent");
		lp = &t->l[t->front];
		if(i){
			flupfront(lp);
			flborder(lp, 0);
			work = lp;
		}else
			current(lp);
		break;

	case Hmovname:
		if((m=whichmenu(m)) < 0)
			break;
		t = text[m];
		l = tag[m];
		i = name[m][0];
		text[m] = 0;	/* suppress panic in menudel */
		menudel(m);
		if(t == &cmd)
			m = 0;
		else{
			if (nname>0 && text[0]==&cmd)
				m = 1;
			else m = 0;
			for(; m<nname; m++)
				if(strcmp((char*)indata+2, (char*)name[m]+1)<0)
					break;
		}
		menuins(m, indata+2, t, i, (int)l);
		break;

	case Hgrow:
		if(whichmenu(m) >= 0)
			hgrow(m, l, inlong(6), 1);
		break;

	case Hnewname:
		menuins(0, (uchar *)"", (Text *)0, ' ', m);
		break;

	case Hcheck0:
		i = whichmenu(m);
		if(i>=0) {
			t = text[i];
			if(t)
				t->lock++;
			outTs(Tcheck, m);
		}
		break;

	case Hcheck:
		i = whichmenu(m);
		if(i>=0) {
			t = text[i];
			if(t && t->lock)
				t->lock--;
			hcheck(m);
		}
		break;

	case Hunlock:
		clrlock();
		break;

	case Hdata:
		if(whichmenu(m) >= 0)
			l += hdata(m, l, indata+6, count-6);
	Checkscroll:
		if(m == cmd.tag){
			for(i=0; i<NL; i++){
				lp = &cmd.l[i];
				if(lp->textfn)
					center(lp, l>=0? l : lp->p1);
			}
		}
		break;

	case Horigin:
		if(whichmenu(m) >= 0)
			horigin(m, l);
		break;

	case Hunlockfile:
		if(whichmenu(m)>=0 && (t = whichtext(m))->lock){
			--t->lock;
			l = -1;
			goto Checkscroll;
		}
		break;

	case Hsetdot:
		if(whichmenu(m) >= 0)
			hsetdot(m, l, inlong(6));
		break;

	case Hgrowdata:
		if(whichmenu(m)<0)
			break;
		hgrow(m, l, inlong(6), 0);
		whichtext(m)->lock++;	/* fake the request */
		l += hdata(m, l, indata+10, count-10);
		goto Checkscroll;

	case Hmoveto:
		if(whichmenu(m)>=0)
			hmoveto(m, l);
		break;

	case Hclean:
		if((m = whichmenu(m)) >= 0)
			name[m][0] = ' ';
		break;

	case Hdirty:
		if((m = whichmenu(m))>=0)
			name[m][0] = '\'';
		break;

	case Hdelname:
		if((m=whichmenu(m)) >= 0)
			menudel(m);
		break;

	case Hcut:
		if(whichmenu(m) >= 0)
			hcut(m, l, inlong(6));
		break;

	case Hclose:
		if(whichmenu(m)<0 || (t = whichtext(m))==0)
			break;
		l = t->nwin;
		for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++)
			if(lp->textfn){
				closeup(lp);
				--l;
			}
		break;

	case Hsetpat:
		setpat((char *)indata);
		break;

	case Hsetsnarf:
		hsetsnarf(m);
		break;

	case Hsnarflen:
		snarflen = inlong(0);
		break;

	case Hack:
		outT0(Tack);
		break;

	case Hexit:
		outT0(Texit);
		threadexitsall(nil);
		break;

	case Hplumb:
		hplumb(m);
		break;
	}
}

void
setlock(void)
{
	hostlock++;
	setcursor(mousectl, cursor = &lockarrow);
}

void
clrlock(void)
{
	hasunlocked = 1;
	if(hostlock > 0)
		hostlock--;
	if(hostlock == 0)
		setcursor(mousectl, cursor=(Cursor *)0);
}

void
startfile(Text *t)
{
	outTsv(Tstartfile, t->tag, t);		/* for 64-bit pointers */
	setlock();
}

void
startnewfile(int type, Text *t)
{
	t->tag = Untagged;
	outTv(type, t);				/* for 64-bit pointers */
}

int
inshort(int n)
{
	return indata[n]|(indata[n+1]<<8);
}

long
inlong(int n)
{
	return indata[n]|(indata[n+1]<<8)|
		((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
}

long
invlong(int n)
{
	long l;

	l = (indata[n+7]<<24) | (indata[n+6]<<16) | (indata[n+5]<<8) | indata[n+4];
	l = (l<<16) | (indata[n+3]<<8) | indata[n+2];
	l = (l<<16) | (indata[n+1]<<8) | indata[n];
	return l;
}

void
outT0(Tmesg type)
{
	outstart(type);
	outsend();
}

void
outTl(Tmesg type, long l)
{
	outstart(type);
	outlong(l);
	outsend();
}

void
outTs(Tmesg type, int s)
{
	outstart(type);
	outshort(s);
	outsend();
}

void
outTss(Tmesg type, int s1, int s2)
{
	outstart(type);
	outshort(s1);
	outshort(s2);
	outsend();
}

void
outTsll(Tmesg type, int s1, long l1, long l2)
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outlong(l2);
	outsend();
}

void
outTsl(Tmesg type, int s1, long l1)
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outsend();
}

void
outTsv(Tmesg type, int s1, void *l1)
{
	outstart(type);
	outshort(s1);
	outvlong(l1);
	outsend();
}

void
outTv(Tmesg type, void *l1)
{
	outstart(type);
	outvlong(l1);
	outsend();
}

void
outTslS(Tmesg type, int s1, long l1, Rune *s)
{
	char buf[DATASIZE*3+1];
	char *c;

	outstart(type);
	outshort(s1);
	outlong(l1);
	c = buf;
	while(*s)
		c += runetochar(c, s++);
	*c++ = 0;
	outcopy(c-buf, (uchar *)buf);
	outsend();
}

void
outTsls(Tmesg type, int s1, long l1, int s2)
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outshort(s2);
	outsend();
}

void
outstart(Tmesg type)
{
	outdata[0] = type;
	outcount = 0;
}

void
outcopy(int count, uchar *data)
{
	while(count--)
		outdata[HSIZE+outcount++] = *data++;	
}

void
outshort(int s)
{
	uchar buf[2];

	buf[0]=s;
	buf[1]=s>>8;
	outcopy(2, buf);
}

void
outlong(long l)
{
	uchar buf[4];

	buf[0]=l;
	buf[1]=l>>8;
	buf[2]=l>>16;
	buf[3]=l>>24;
	outcopy(4, buf);
}

void
outvlong(void *v)
{
	int i;
	ulong l;
	uchar buf[8];

	l = (ulong) v;
	for(i = 0; i < sizeof(buf); i++, l >>= 8)
		buf[i] = l;

	outcopy(8, buf);
}

void
outsend(void)
{
	if(outcount>DATASIZE-HSIZE)
		panic("outcount>sizeof outdata");
	outdata[1]=outcount;
	outdata[2]=outcount>>8;
	if(write(hostfd[1], (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
		panic("write error");
}


void
hsetdot(int m, long p0, long p1)
{
	Text *t = whichtext(m);
	Flayer *l = &t->l[t->front];

	flushtyping(1);
	flsetselect(l, p0, p1);
}

void
horigin(int m, long p0)
{
	Text *t = whichtext(m);
	Flayer *l = &t->l[t->front];
	long a;
	ulong n;
	Rune *r;

	if(!flprepare(l)){
		l->origin = p0;
		return;
	}
	a = p0-l->origin;
	if(a>=0 && a<l->f.nchars)
		frdelete(&l->f, 0, a);
	else if(a<0 && -a<l->f.nchars){
		r = rload(&t->rasp, p0, l->origin, &n);
		frinsert(&l->f, r, r+n, 0);
	}else
		frdelete(&l->f, 0, l->f.nchars);
	l->origin = p0;
	scrdraw(l, t->rasp.nrunes);
	if(l->visible==Some)
		flrefresh(l, l->entire, 0);
	hcheck(m);
}

void
hmoveto(int m, long p0)
{
	Text *t = whichtext(m);
	Flayer *l = &t->l[t->front];

	if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
		outTsll(Torigin, m, p0, 2L);
}

void
hcheck(int m)
{
	Flayer *l;
	Text *t;
	int reqd = 0, i;
	long n, nl, a;
	Rune *r;

	if(m == Untagged)
		return;
	t = whichtext(m);
	if(t == 0)		/* possible in a half-built window */
		return;
	for(l = &t->l[0], i = 0; i<NL; i++, l++){
		if(l->textfn==0 || !flprepare(l))	/* BUG: don't
							   need this if BUG below
							   is fixed */
			continue;
		a = t->l[i].origin;
		n = rcontig(&t->rasp, a, a+l->f.nchars, 1);
		if(n<l->f.nchars)	/* text missing in middle of screen */
			a+=n;
		else{			/* text missing at end of screen? */
        Again:
		 	if(l->f.lastlinefull)
				goto Checksel;	/* all's well */
			a = t->l[i].origin+l->f.nchars;
			n = t->rasp.nrunes-a;
			if(n==0)
				goto Checksel;
			if(n>TBLOCKSIZE)
				n = TBLOCKSIZE;
			n = rcontig(&t->rasp, a, a+n, 1);
			if(n>0){
				rload(&t->rasp, a, a+n, 0);
				nl = l->f.nchars;
				r = scratch;
				flinsert(l, r, r+n, l->origin+nl);
				if(nl == l->f.nchars)	/* made no progress */
					goto Checksel;
				goto Again;
			}
		}
		if(!reqd){
			n = rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);
			if(n <= 0)
				panic("hcheck request==0");
			outTsls(Trequest, m, a, (int)n);
			outTs(Tcheck, m);
			t->lock++;	/* for the Trequest */
			t->lock++;	/* for the Tcheck */
			reqd++;
		}
	    Checksel:
		flsetselect(l, l->p0, l->p1);
	}
}

void
flnewlyvisible(Flayer *l)
{
	hcheck(((Text *)l->user1)->tag);
}

void
hsetsnarf(int nc)
{
	char *s2;
	char *s1;
	int i;
	int n;

	setcursor(mousectl, &deadmouse);
	s2 = alloc(nc+1);
	for(i=0; i<nc; i++)
		s2[i] = getch();
	s2[nc] = 0;
	n = snarfswap(s2, nc, &s1);
	if(n >= 0){
		if(!s1)
			n = 0;
		if(n > 65535){
			s1 = strdup("<snarf too long>");
			if (!s1)
				panic("strdup");
			n = strlen(s1);
		}else{
			s1 = realloc(s1, n+1);
			if (!s1)
				panic("realloc");
			s1[n] = 0;
		}
		snarflen = n;
		outTs(Tsetsnarf, n);
		if(n>0 && write(hostfd[1], s1, n)!=n)
			panic("snarf write error");
		free(s1);
	}else
		outTs(Tsetsnarf, 0);
	free(s2);
	setcursor(mousectl, cursor);
}

void
hplumb(int nc)
{
	int i;
	char *s;
	Plumbmsg *m;

	s = alloc(nc);
	for(i=0; i<nc; i++)
		s[i] = getch();
	if(plumbfd > 0){
		m = plumbunpack(s, nc);
		if(m != 0)
			plumbsend(plumbfd, m);
		plumbfree(m);
	}
	free(s);
}

void
hgrow(int m, long a, long new, int req)
{
	int i;
	Flayer *l;
	Text *t = whichtext(m);
	long o, b;

	if(new <= 0)
		panic("hgrow");
	rresize(&t->rasp, a, 0L, new);
	for(l = &t->l[0], i = 0; i<NL; i++, l++){
		if(l->textfn == 0)
			continue;
		o = l->origin;
		b = a-o-rmissing(&t->rasp, o, a);
		if(a < o)
			l->origin+=new;
		if(a < l->p0)
			l->p0+=new;
		if(a < l->p1)
			l->p1+=new;
		/* must prevent b temporarily becoming unsigned */
		if(!req || a<o || (b>0 && b>l->f.nchars) ||
		    (l->f.nchars==0 && a-o>0))
			continue;
		if(new>TBLOCKSIZE)
			new = TBLOCKSIZE;
		outTsls(Trequest, m, a, (int)new);
		t->lock++;
		req = 0;
	}
}

int
hdata1(Text *t, long a, Rune *r, int len)
{
	int i;
	Flayer *l;
	long o, b;

	for(l = &t->l[0], i=0; i<NL; i++, l++){
		if(l->textfn==0)
			continue;
		o = l->origin;
		b = a-o-rmissing(&t->rasp, o, a);
		/* must prevent b temporarily becoming unsigned */
		if(a<o || (b>0 && b>l->f.nchars))
			continue;
		flinsert(l, r, r+len, o+b);
	}
	rdata(&t->rasp, a, a+len, r);
	rclean(&t->rasp);
	return len;
}

int
hdata(int m, long a, uchar *s, int len)
{
	int i, w;
	Text *t = whichtext(m);
	Rune buf[DATASIZE], *r;

	if(t->lock)
		--t->lock;
	if(len == 0)
		return 0;
	r = buf;
	for(i=0; i<len; i+=w,s+=w)
		w = chartorune(r++, (char*)s);
	return hdata1(t, a, buf, r-buf);
}

int
hdatarune(int m, long a, Rune *r, int len)
{
	Text *t = whichtext(m);

	if(t->lock)
		--t->lock;
	if(len == 0)
		return 0;
	return hdata1(t, a, r, len);
}

void
hcut(int m, long a, long old)
{
	Flayer *l;
	Text *t = whichtext(m);
	int i;
	long o, b;

	if(t->lock)
		--t->lock;
	for(l = &t->l[0], i = 0; i<NL; i++, l++){
		if(l->textfn == 0)
			continue;
		o = l->origin;
		b = a-o-rmissing(&t->rasp, o, a);
		/* must prevent b temporarily becoming unsigned */
		if((b<0 || b<l->f.nchars) && a+old>=o){
			fldelete(l, b<0? o : o+b,
			    a+old-rmissing(&t->rasp, o, a+old));
		}
		if(a+old<o)
			l->origin-=old;
		else if(a<=o)
			l->origin = a;
		if(a+old<l->p0)
			l->p0-=old;
		else if(a<=l->p0)
			l->p0 = a;
		if(a+old<l->p1)
			l->p1-=old;
		else if(a<=l->p1)
			l->p1 = a;
	}
	rresize(&t->rasp, a, old, 0L);
	rclean(&t->rasp);
}
