#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"

Text	cmd;
Rune	*scratch;
long	nscralloc;
Cursor	*cursor;
Flayer	*which = 0;
Flayer	*work = 0;
long	snarflen;
long	typestart = -1;
long	typeend = -1;
long	typeesc = -1;
long	modified = 0;		/* strange lookahead for menus */
char	hostlock = 1;
char	hasunlocked = 0;
int	maxtab = 8;
int	chord;
int	autoindent;

#define chording 0	/* code here for reference but it causes deadlocks */

void
notifyf(void *a, char *msg)
{
	if(strcmp(msg, "interrupt") == 0)
		noted(NCONT);
	noted(NDFLT);
}

void
threadmain(int argc, char *argv[])
{
	int i, got, scr, w;
	Text *t;
	Rectangle r;
	Flayer *nwhich;

	/*
	 * sam is talking to us on fd 0 and 1.
	 * move these elsewhere so that if we accidentally
	 * use 0 and 1 in other code, nothing bad happens.
	 */
	dup(0, 3);
	dup(1, 4);
	hostfd[0] = 3;
	hostfd[1] = 4;
	close(0);
	close(1);
	open("/dev/null", OREAD);
	if(open("/dev/tty", OWRITE) < 0)
		open("/dev/null", OWRITE);

	notify(notifyf);

	if(protodebug) print("getscreen\n");
	getscreen(argc, argv);
	if(protodebug) print("iconinit\n");
	iconinit();
	if(protodebug) print("initio\n");
	initio();
	if(protodebug) print("scratch\n");
	scratch = alloc(100*RUNESIZE);
	nscralloc = 100;
	r = screen->r;
	r.max.y = r.min.y+Dy(r)/5;
	if(protodebug) print("flstart\n");
	flstart(screen->clipr);
	rinit(&cmd.rasp);
	flnew(&cmd.l[0], gettext, 1, &cmd);
	flinit(&cmd.l[0], r, font, cmdcols);
	cmd.nwin = 1;
	which = &cmd.l[0];
	cmd.tag = Untagged;
	outTs(Tversion, VERSION);
	startnewfile(Tstartcmdfile, &cmd);

	got = 0;
	if(protodebug) print("loop\n");
	for(;;got = waitforio()){
		if(hasunlocked && RESIZED())
			resize();
		if(got&(1<<RHost))
			rcv();
		if(got&(1<<RPlumb)){
			for(i=0; cmd.l[i].textfn==0; i++)
				;
			current(&cmd.l[i]);
			flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
			type(which, RPlumb);
		}
		if(got&(1<<RKeyboard))
			if(which)
				type(which, RKeyboard);
			else
				kbdblock();
		if(got&(1<<RMouse)){
			if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){
				mouseunblock();
				continue;
			}
			nwhich = flwhich(mousep->xy);
			scr = which && ptinrect(mousep->xy, which->scroll);
			if(mousep->buttons)
				flushtyping(1);
			if(chording && chord==1 && !mousep->buttons)
				chord = 0;
			if(chording && chord)
				chord |= mousep->buttons;
			else if(mousep->buttons&1){
				if(nwhich){
					if(nwhich!=which)
						current(nwhich);
					else if(scr)
						scroll(which, 1);
					else{
						t=(Text *)which->user1;
						if(flselect(which)){
							outTsl(Tdclick, t->tag, which->p0);
							t->lock++;
						}else if(t!=&cmd)
							outcmd();
						if(mousep->buttons&1)
							chord = mousep->buttons;
					}
				}
			}else if((mousep->buttons&2) && which){
				if(scr)
					scroll(which, 2);
				else
					menu2hit();
			}else if((mousep->buttons&4)){
				if(scr)
					scroll(which, 3);
				else
					menu3hit();
			}
			mouseunblock();
		}
		if(chording && chord){
			t = (Text*)which->user1;
			if(!t->lock && !hostlock){
				w = which-t->l;
				if(chord&2){
					cut(t, w, 1, 1);
					chord &= ~2;
				}else if(chord&4){
					paste(t, w);
					chord &= ~4;
				}
			}
		}
	}
}

void
resize(void)
{
	int i;

	flresize(screen->clipr);
	for(i = 0; i<nname; i++)
		if(text[i])
			hcheck(text[i]->tag);
}

void
current(Flayer *nw)
{
	Text *t;

	if(which)
		flborder(which, 0);
	if(nw){
		flushtyping(1);
		flupfront(nw);
		flborder(nw, 1);
		buttons(Up);
		t = (Text *)nw->user1;
		t->front = nw-&t->l[0];
		if(t != &cmd)
			work = nw;
	}
	which = nw;
}

void
closeup(Flayer *l)
{
	Text *t=(Text *)l->user1;
	int m;

	m = whichmenu(t->tag);
	if(m < 0)
		return;
	flclose(l);
	if(l == which){
		which = 0;
		current(flwhich(Pt(0, 0)));
	}
	if(l == work)
		work = 0;
	if(--t->nwin == 0){
		rclear(&t->rasp);
		free((uchar *)t);
		text[m] = 0;
	}else if(l == &t->l[t->front]){
		for(m=0; m<NL; m++)	/* find one; any one will do */
			if(t->l[m].textfn){
				t->front = m;
				return;
			}
		panic("close");
	}
}

Flayer *
findl(Text *t)
{
	int i;
	for(i = 0; i<NL; i++)
		if(t->l[i].textfn==0)
			return &t->l[i];
	return 0;
}

void
duplicate(Flayer *l, Rectangle r, Font *f, int close)
{
	Text *t=(Text *)l->user1;
	Flayer *nl = findl(t);
	Rune *rp;
	ulong n;

	if(nl){
		flnew(nl, gettext, l->user0, (char *)t);
		flinit(nl, r, f, l->f.cols);
		nl->origin = l->origin;
		rp = (*l->textfn)(l, l->f.nchars, &n);
		flinsert(nl, rp, rp+n, l->origin);
		flsetselect(nl, l->p0, l->p1);
		if(close){
			flclose(l);
			if(l==which)
				which = 0;
		}else
			t->nwin++;
		current(nl);
		hcheck(t->tag);
	}
	setcursor(mousectl, cursor);
}

void
buttons(int updown)
{
	while(((mousep->buttons&7)!=0) != updown)
		getmouse();
}

int
getr(Rectangle *rp)
{
	Point p;
	Rectangle r;

	*rp = getrect(3, mousectl);
	if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){
		p = rp->min;
		r = cmd.l[cmd.front].entire;
		*rp = screen->r;
		if(cmd.nwin==1){
			if (p.y <= r.min.y)
				rp->max.y = r.min.y;
			else if (p.y >= r.max.y)
				rp->min.y = r.max.y;
			if (p.x <= r.min.x)
				rp->max.x = r.min.x;
			else if (p.x >= r.max.x)
				rp->min.x = r.max.x;
		}
	}
	return rectclip(rp, screen->r) &&
	   rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;
}

void
snarf(Text *t, int w)
{
	Flayer *l = &t->l[w];

	if(l->p1>l->p0){
		snarflen = l->p1-l->p0;
		outTsll(Tsnarf, t->tag, l->p0, l->p1);
	}
}

void
cut(Text *t, int w, int save, int check)
{
	long p0, p1;
	Flayer *l;

	l = &t->l[w];
	p0 = l->p0;
	p1 = l->p1;
	if(p0 == p1)
		return;
	if(p0 < 0)
		panic("cut");
	if(save)
		snarf(t, w);
	outTsll(Tcut, t->tag, p0, p1);
	flsetselect(l, p0, p0);
	t->lock++;
	hcut(t->tag, p0, p1-p0);
	if(check)
		hcheck(t->tag);
}

void
paste(Text *t, int w)
{
	if(snarflen){
		cut(t, w, 0, 0);
		t->lock++;
		outTsl(Tpaste, t->tag, t->l[w].p0);
	}
}

void
scrorigin(Flayer *l, int but, long p0)
{
	Text *t=(Text *)l->user1;

	switch(but){
	case 1:
		outTsll(Torigin, t->tag, l->origin, p0);
		break;
	case 2:
		outTsll(Torigin, t->tag, p0, 1L);
		break;
	case 3:
		horigin(t->tag,p0);
	}
}

int
alnum(int c)
{
	/*
	 * Hard to get absolutely right.  Use what we know about ASCII
	 * and assume anything above the Latin control characters is
	 * potentially an alphanumeric.
	 */
	if(c<=' ')
		return 0;
	if(0x7F<=c && c<=0xA0)
		return 0;
	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
		return 0;
	return 1;
}

int
raspc(Rasp *r, long p)
{
	ulong n;
	rload(r, p, p+1, &n);
	if(n)
		return scratch[0];
	return 0;
}

long
ctlw(Rasp *r, long o, long p)
{
	int c;

	if(--p < o)
		return o;
	if(raspc(r, p)=='\n')
		return p;
	for(; p>=o && !alnum(c=raspc(r, p)); --p)
		if(c=='\n')
			return p+1;
	for(; p>o && alnum(raspc(r, p-1)); --p)
		;
	return p>=o? p : o;
}

long
ctlu(Rasp *r, long o, long p)
{
	if(--p < o)
		return o;
	if(raspc(r, p)=='\n')
		return p;
	for(; p-1>=o && raspc(r, p-1)!='\n'; --p)
		;
	return p>=o? p : o;
}

int
center(Flayer *l, long a)
{
	Text *t;

	t = l->user1;
	if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
		if(a > t->rasp.nrunes)
			a = t->rasp.nrunes;
		outTsll(Torigin, t->tag, a, 2L);
		return 1;
	}
	return 0;
}

int
thirds(Flayer *l, long a, int n)
{
	Text *t;
	Rectangle s;
	long lines;

	t = l->user1;
	if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
		if(a > t->rasp.nrunes)
			a = t->rasp.nrunes;
		s = insetrect(l->scroll, 1);
		lines = (n*(s.max.y-s.min.y)/l->f.font->height+1)/3;
		if (lines < 2)
			lines = 2;
		outTsll(Torigin, t->tag, a, lines);
		return 1;
	}
	return 0;
}

int
onethird(Flayer *l, long a)
{
	return thirds(l, a, 1);
}

int
twothirds(Flayer *l, long a)
{
	return thirds(l, a, 2);
}

void
flushtyping(int clearesc)
{
	Text *t;
	ulong n;

	if(clearesc)
		typeesc = -1;	
	if(typestart == typeend) {
		modified = 0;
		return;
	}
	t = which->user1;
	if(t != &cmd)
		modified = 1;
	rload(&t->rasp, typestart, typeend, &n);
	scratch[n] = 0;
	if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){
		setlock();
		outcmd();
	}
	outTslS(Ttype, t->tag, typestart, scratch);
	typestart = -1;
	typeend = -1;
}

#define	BACKSCROLLKEY	Kup
#define	ENDKEY	Kend
#define	ESC		0x1B
#define	HOMEKEY	Khome
#define	LEFTARROW	Kleft
#define	LINEEND	0x05
#define	LINESTART	0x01
#define	PAGEDOWN	Kpgdown
#define	PAGEUP	Kpgup
#define	RIGHTARROW	Kright
#define	SCROLLKEY	Kdown
#define	CUT	(Kcmd+'x')
#define	COPY	(Kcmd+'c')
#define	PASTE	(Kcmd+'v')

int
nontypingkey(int c)
{
	switch(c){
	case BACKSCROLLKEY:
	case ENDKEY:
	case HOMEKEY:
	case LEFTARROW:
	case LINEEND:
	case LINESTART:
	case PAGEDOWN:
	case PAGEUP:
	case RIGHTARROW:
	case SCROLLKEY:
		return 1;
	}
	if(c >= Kcmd)
		return 1;
	return 0;
}

void
type(Flayer *l, int res)	/* what a bloody mess this is */
{
	Text *t = (Text *)l->user1;
	Rune buf[100];
	Rune *p = buf;
	int c, backspacing;
	long a, a0;
	int scrollkey;

	scrollkey = 0;
	if(res == RKeyboard)
		scrollkey = nontypingkey(qpeekc());	/* ICK */

	if(hostlock || t->lock){
		kbdblock();
		return;
	}
	a = l->p0;
	if(a!=l->p1 && !scrollkey){
		flushtyping(1);
		cut(t, t->front, 1, 1);
		return;	/* it may now be locked */
	}
	backspacing = 0;
	while((c = kbdchar())>0){
		if(res == RKeyboard){
			if(nontypingkey(c) || c==ESC)
				break;
			/* backspace, ctrl-u, ctrl-w, del */
			if(c=='\b' || c==0x15 || c==0x17 || c==0x7F){
				backspacing = 1;
				break;
			}
		}
		*p++ = c;
		if(autoindent)
		if(c == '\n'){
			/* autoindent */
			int cursor, ch;
			cursor = ctlu(&t->rasp, 0, a+(p-buf)-1);
			while(p < buf+nelem(buf)){
				ch = raspc(&t->rasp, cursor++);
				if(ch == ' ' || ch == '\t')
					*p++ = ch;
				else
					break;
			}
		}
		if(c == '\n' || p >= buf+nelem(buf))
			break;
	}
	if(p > buf){
		if(typestart < 0)
			typestart = a;
		if(typeesc < 0)
			typeesc = a;
		hgrow(t->tag, a, p-buf, 0);
		t->lock++;	/* pretend we Trequest'ed for hdatarune*/
		hdatarune(t->tag, a, buf, p-buf);
		a += p-buf;
		l->p0 = a;
		l->p1 = a;
		typeend = a;
		if(c=='\n' || typeend-typestart>100)
			flushtyping(0);
		onethird(l, a);
	}
	if(c==SCROLLKEY || c==PAGEDOWN){
		flushtyping(0);
		center(l, l->origin+l->f.nchars+1);
	}else if(c==BACKSCROLLKEY || c==PAGEUP){
		flushtyping(0);
		a0 = l->origin-l->f.nchars;
		if(a0 < 0)
			a0 = 0;
		center(l, a0);
	}else if(c == RIGHTARROW){
		flushtyping(0);
		a0 = l->p0;
		if(a0 < t->rasp.nrunes)
			a0++;
		flsetselect(l, a0, a0);
		center(l, a0);
	}else if(c == LEFTARROW){
		flushtyping(0);
		a0 = l->p0;
		if(a0 > 0)
			a0--;
		flsetselect(l, a0, a0);
		center(l, a0);
	}else if(c == HOMEKEY){
		flushtyping(0);
		center(l, 0);
	}else if(c == ENDKEY){
		flushtyping(0);
		center(l, t->rasp.nrunes);
	}else if(c == LINESTART || c == LINEEND){
		flushtyping(1);
		if(c == LINESTART)
			while(a > 0 && raspc(&t->rasp, a-1)!='\n')
				a--;
		else
			while(a < t->rasp.nrunes && raspc(&t->rasp, a)!='\n')
				a++;
		l->p0 = l->p1 = a;
		for(l=t->l; l<&t->l[NL]; l++)
			if(l->textfn)
				flsetselect(l, l->p0, l->p1);
	}else if(backspacing && !hostlock){
		/* backspacing immediately after outcmd(): sorry */
		if(l->f.p0>0 && a>0){
			switch(c){
			case '\b':
			case 0x7F:	/* del */
				l->p0 = a-1;
				break;
			case 0x15:	/* ctrl-u */
				l->p0 = ctlu(&t->rasp, l->origin, a);
				break;
			case 0x17:	/* ctrl-w */
				l->p0 = ctlw(&t->rasp, l->origin, a);
				break;
			}
			l->p1 = a;
			if(l->p1 != l->p0){
				/* cut locally if possible */
				if(typestart<=l->p0 && l->p1<=typeend){
					t->lock++;	/* to call hcut */
					hcut(t->tag, l->p0, l->p1-l->p0);
					/* hcheck is local because we know rasp is contiguous */
					hcheck(t->tag);
				}else{
					flushtyping(0);
					cut(t, t->front, 0, 1);
				}
			}
			if(typeesc >= l->p0)
				typeesc = l->p0;
			if(typestart >= 0){
				if(typestart >= l->p0)
					typestart = l->p0;
				typeend = l->p0;
				if(typestart == typeend){
					typestart = -1;
					typeend = -1;
					modified = 0;
				}
			}
		}
	}else{
		if(c==ESC && typeesc>=0){
			l->p0 = typeesc;
			l->p1 = a;
			flushtyping(1);
		}
		for(l=t->l; l<&t->l[NL]; l++)
			if(l->textfn)
				flsetselect(l, l->p0, l->p1);
		switch(c) {
		case CUT:
			flushtyping(0);
			cut(t, t->front, 1, 1);
			break;
		case COPY:
			flushtyping(0);
			snarf(t, t->front);
			break;
		case PASTE:
			flushtyping(0);
			paste(t, t->front);
			break;
		}
	}
}


void
outcmd(void){
	if(work)
		outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
}

void
panic(char *s)
{
	panic1(display, s);
}

void
panic1(Display *d, char *s)
{
	fprint(2, "samterm:panic: ");
	perror(s);
	abort();
}

Rune*
gettext(Flayer *l, long n, ulong *np)
{
	Text *t;

	t = l->user1;
	rload(&t->rasp, l->origin, l->origin+n, np);
	return scratch;
}

long
scrtotal(Flayer *l)
{
	return ((Text *)l->user1)->rasp.nrunes;
}

void*
alloc(ulong n)
{
	void *p;

	p = malloc(n);
	if(p == 0)
		panic("alloc");
	memset(p, 0, n);
	return p;
}
