#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];
int	exiting;

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;

	if(protodebug) print("rcv in\n");
	while((c=rcvchar()) != -1){
		if(protodebug) print(".");
		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;
		}
		if(protodebug) print(":");
	}

	if(protodebug) print("rcv out\n");
}

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:
		exiting = 1;
		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);
}
