#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 <plumb.h>
#include "dat.h"
#include "fns.h"

int	winid;

void
wininit(Window *w, Window *clone, Rectangle r)
{
	Rectangle r1, br;
	File *f;
	Reffont *rf;
	Rune *rp;
	int nc;

	w->tag.w = w;
	w->taglines = 1;
	w->tagexpand = TRUE;
	w->body.w = w;
	w->id = ++winid;
	incref(&w->ref);
	if(globalincref)
		incref(&w->ref);
	w->ctlfid = ~0;
	w->utflastqid = -1;
	r1 = r;

	w->tagtop = r;
	w->tagtop.max.y = r.min.y + font->height;
	r1.max.y = r1.min.y + w->taglines*font->height;

	incref(&reffont.ref);
	f = fileaddtext(nil, &w->tag);
	textinit(&w->tag, f, r1, &reffont, tagcols);
	w->tag.what = Tag;
	/* tag is a copy of the contents, not a tracked image */
	if(clone){
		textdelete(&w->tag, 0, w->tag.file->b.nc, TRUE);
		nc = clone->tag.file->b.nc;
		rp = runemalloc(nc);
		bufread(&clone->tag.file->b, 0, rp, nc);
		textinsert(&w->tag, 0, rp, nc, TRUE);
		free(rp);
		filereset(w->tag.file);
		textsetselect(&w->tag, nc, nc);
	}
	r1 = r;
	r1.min.y += w->taglines*font->height + 1;
	if(r1.max.y < r1.min.y)
		r1.max.y = r1.min.y;
	f = nil;
	if(clone){
		f = clone->body.file;
		w->body.org = clone->body.org;
		w->isscratch = clone->isscratch;
		rf = rfget(FALSE, FALSE, FALSE, clone->body.reffont->f->name);
	}else
		rf = rfget(FALSE, FALSE, FALSE, nil);
	f = fileaddtext(f, &w->body);
	w->body.what = Body;
	textinit(&w->body, f, r1, rf, textcols);
	r1.min.y -= 1;
	r1.max.y = r1.min.y+1;
	draw(screen, r1, tagcols[BORD], nil, ZP);
	textscrdraw(&w->body);
	w->r = r;
	br.min = w->tag.scrollr.min;
	br.max.x = br.min.x + Dx(button->r);
	br.max.y = br.min.y + Dy(button->r);
	draw(screen, br, button, nil, button->r.min);
	w->filemenu = TRUE;
	w->maxlines = w->body.fr.maxlines;
	w->autoindent = globalautoindent;
	if(clone){
		w->dirty = clone->dirty;
		w->autoindent = clone->autoindent;
		textsetselect(&w->body, clone->body.q0, clone->body.q1);
		winsettag(w);
	}
}

/*
 * Draw the appropriate button.
 */
void
windrawbutton(Window *w)
{
	Image *b;
	Rectangle br;
	
	b = button;
	if(!w->isdir && !w->isscratch && (w->body.file->mod || w->body.ncache))
		b = modbutton;
	br.min = w->tag.scrollr.min;
	br.max.x = br.min.x + Dx(b->r);
	br.max.y = br.min.y + Dy(b->r);
	draw(screen, br, b, nil, b->r.min);
}

int
delrunepos(Window *w)
{
	int n;
	Rune rune;
	
	for(n=0; n<w->tag.file->b.nc; n++) {
		bufread(&w->tag.file->b, n, &rune, 1);
		if(rune == ' ')
			break;
	}
	n += 2;
	if(n >= w->tag.file->b.nc)
		return -1;
	return n;
}

void
movetodel(Window *w)
{
	int n;
	
	n = delrunepos(w);
	if(n < 0)
		return;
	moveto(mousectl, addpt(frptofchar(&w->tag.fr, n), Pt(4, w->tag.fr.font->height-4)));
}

/*
 * Compute number of tag lines required
 * to display entire tag text.
 */
int
wintaglines(Window *w, Rectangle r)
{
	int n;
	Rune rune;
	Point p;

	if(!w->tagexpand && !w->showdel)
		return 1;
	w->showdel = FALSE;
	w->tag.fr.noredraw = 1;
	textresize(&w->tag, r, TRUE);
	w->tag.fr.noredraw = 0;
	w->tagsafe = FALSE;
	
	if(!w->tagexpand) {
		/* use just as many lines as needed to show the Del */
		n = delrunepos(w);
		if(n < 0)
			return 1;
		p = subpt(frptofchar(&w->tag.fr, n), w->tag.fr.r.min);
		return 1 + p.y / w->tag.fr.font->height;
	}
		
	/* can't use more than we have */
	if(w->tag.fr.nlines >= w->tag.fr.maxlines)
		return w->tag.fr.maxlines;

	/* if tag ends with \n, include empty line at end for typing */
	n = w->tag.fr.nlines;
	if(w->tag.file->b.nc > 0){
		bufread(&w->tag.file->b, w->tag.file->b.nc-1, &rune, 1);
		if(rune == '\n')
			n++;
	}
	if(n == 0)
		n = 1;
	return n;
}

int
winresize(Window *w, Rectangle r, int safe, int keepextra)
{
	int oy, y, mouseintag, mouseinbody, tagresized;
	Point p;
	Rectangle r1;

	mouseintag = ptinrect(mouse->xy, w->tag.all);
	mouseinbody = ptinrect(mouse->xy, w->body.all);

	/* tagtop is first line of tag */
	w->tagtop = r;
	w->tagtop.max.y = r.min.y+font->height;

	r1 = r;
	r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height);

	/* If needed, recompute number of lines in tag. */
	if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){
		w->taglines = wintaglines(w, r);
		r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height);
	}

	/* If needed, resize & redraw tag. */
	y = r1.max.y;
	tagresized = 0;
	if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){
		tagresized = 1;
		textresize(&w->tag, r1, TRUE);
		y = w->tag.fr.r.max.y;
		windrawbutton(w);
		w->tagsafe = TRUE;

		/* If mouse is in tag, pull up as tag closes. */
		if(mouseintag && !ptinrect(mouse->xy, w->tag.all)){
			p = mouse->xy;
			p.y = w->tag.all.max.y-3;
			moveto(mousectl, p);
		}

		/* If mouse is in body, push down as tag expands. */
		if(mouseinbody && ptinrect(mouse->xy, w->tag.all)){
			p = mouse->xy;
			p.y = w->tag.all.max.y+3;
			moveto(mousectl, p);
		}
	}
	
	/* If needed, resize & redraw body. */
	r1 = r;
	r1.min.y = y;
	if(!safe || !eqrect(w->body.all, r1)){
		oy = y;
		if(y+1+w->body.fr.font->height <= r.max.y){	/* room for one line */
			r1.min.y = y;
			r1.max.y = y+1;
			draw(screen, r1, tagcols[BORD], nil, ZP);
			y++;
			r1.min.y = min(y, r.max.y);
			r1.max.y = r.max.y;
		}else{
			r1.min.y = y;
			r1.max.y = y;
		}
		y = textresize(&w->body, r1, keepextra);
		w->r = r;
		w->r.max.y = y;
		textscrdraw(&w->body);
		w->body.all.min.y = oy;
	}
	w->maxlines = min(w->body.fr.nlines, max(w->maxlines, w->body.fr.maxlines));
	return w->r.max.y;
}

void
winlock1(Window *w, int owner)
{
	incref(&w->ref);
	qlock(&w->lk);
	w->owner = owner;
}

void
winlock(Window *w, int owner)
{
	int i;
	File *f;

	f = w->body.file;
	for(i=0; i<f->ntext; i++)
		winlock1(f->text[i]->w, owner);
}

void
winunlock(Window *w)
{
	int i;
	File *f;

	/*
	 * subtle: loop runs backwards to avoid tripping over
	 * winclose indirectly editing f->text and freeing f
	 * on the last iteration of the loop.
	 */
	f = w->body.file;
	for(i=f->ntext-1; i>=0; i--){
		w = f->text[i]->w;
		w->owner = 0;
		qunlock(&w->lk);
		winclose(w);
	}
}

void
winmousebut(Window *w)
{
	moveto(mousectl, addpt(w->tag.scrollr.min, 
		divpt(Pt(Dx(w->tag.scrollr), font->height), 2)));
}

void
windirfree(Window *w)
{
	int i;
	Dirlist *dl;

	if(w->isdir){
		for(i=0; i<w->ndl; i++){
			dl = w->dlp[i];
			free(dl->r);
			free(dl);
		}
		free(w->dlp);
	}
	w->dlp = nil;
	w->ndl = 0;
}

void
winclose(Window *w)
{
	int i;

	if(decref(&w->ref) == 0){
		windirfree(w);
		textclose(&w->tag);
		textclose(&w->body);
		if(activewin == w)
			activewin = nil;
		for(i=0; i<w->nincl; i++)
			free(w->incl[i]);
		free(w->incl);
		free(w->events);
		free(w);
	}
}

void
windelete(Window *w)
{
	Xfid *x;

	x = w->eventx;
	if(x){
		w->nevents = 0;
		free(w->events);
		w->events = nil;
		w->eventx = nil;
		sendp(x->c, nil);	/* wake him up */
	}
}

void
winundo(Window *w, int isundo)
{
	Text *body;
	int i;
	File *f;
	Window *v;

	w->utflastqid = -1;
	body = &w->body;
	fileundo(body->file, isundo, &body->q0, &body->q1);
	textshow(body, body->q0, body->q1, 1);
	f = body->file;
	for(i=0; i<f->ntext; i++){
		v = f->text[i]->w;
		v->dirty = (f->seq != v->putseq);
		if(v != w){
			v->body.q0 = v->body.fr.p0+v->body.org;
			v->body.q1 = v->body.fr.p1+v->body.org;
		}
	}
	winsettag(w);
}

void
winsetname(Window *w, Rune *name, int n)
{
	Text *t;
	Window *v;
	int i;
	static Rune Lslashguide[] = { '/', 'g', 'u', 'i', 'd', 'e', 0 };
	static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 };

	t = &w->body;
	if(runeeq(t->file->name, t->file->nname, name, n) == TRUE)
		return;
	w->isscratch = FALSE;
	if(n>=6 && runeeq(Lslashguide, 6, name+(n-6), 6))
		w->isscratch = TRUE;
	else if(n>=7 && runeeq(Lpluserrors, 7, name+(n-7), 7))
		w->isscratch = TRUE;
	filesetname(t->file, name, n);
	for(i=0; i<t->file->ntext; i++){
		v = t->file->text[i]->w;
		winsettag(v);
		v->isscratch = w->isscratch;
	}
}

void
wintype(Window *w, Text *t, Rune r)
{
	int i;

	texttype(t, r);
	if(t->what == Body)
		for(i=0; i<t->file->ntext; i++)
			textscrdraw(t->file->text[i]);
	winsettag(w);
}

void
wincleartag(Window *w)
{
	int i, n;
	Rune *r;

	/* w must be committed */
	n = w->tag.file->b.nc;
	r = runemalloc(n);
	bufread(&w->tag.file->b, 0, r, n);
	for(i=0; i<n; i++)
		if(r[i]==' ' || r[i]=='\t')
			break;
	for(; i<n; i++)
		if(r[i] == '|')
			break;
	if(i == n)
		return;
	i++;
	textdelete(&w->tag, i, n, TRUE);
	free(r);
	w->tag.file->mod = FALSE;
	if(w->tag.q0 > i)
		w->tag.q0 = i;
	if(w->tag.q1 > i)
		w->tag.q1 = i;
	textsetselect(&w->tag, w->tag.q0, w->tag.q1);
}

void
winsettag1(Window *w)
{
	int i, j, k, n, bar, dirty, resize;
	Rune *new, *old, *r;
	uint q0, q1;
	static Rune Ldelsnarf[] = { ' ', 'D', 'e', 'l', ' ',
		'S', 'n', 'a', 'r', 'f', 0 };
	static Rune Lundo[] = { ' ', 'U', 'n', 'd', 'o', 0 };
	static Rune Lredo[] = { ' ', 'R', 'e', 'd', 'o', 0 };
	static Rune Lget[] = { ' ', 'G', 'e', 't', 0 };
	static Rune Lput[] = { ' ', 'P', 'u', 't', 0 };
	static Rune Llook[] = { ' ', 'L', 'o', 'o', 'k', ' ', 0 };
	static Rune Lpipe[] = { ' ', '|', 0 };

	/* there are races that get us here with stuff in the tag cache, so we take extra care to sync it */
	if(w->tag.ncache!=0 || w->tag.file->mod)
		wincommit(w, &w->tag);	/* check file name; also guarantees we can modify tag contents */
	old = runemalloc(w->tag.file->b.nc+1);
	bufread(&w->tag.file->b, 0, old, w->tag.file->b.nc);
	old[w->tag.file->b.nc] = '\0';
	for(i=0; i<w->tag.file->b.nc; i++)
		if(old[i]==' ' || old[i]=='\t')
			break;
	if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){
		textdelete(&w->tag, 0, i, TRUE);
		textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE);
		free(old);
		old = runemalloc(w->tag.file->b.nc+1);
		bufread(&w->tag.file->b, 0, old, w->tag.file->b.nc);
		old[w->tag.file->b.nc] = '\0';
	}

	/* compute the text for the whole tag, replacing current only if it differs */
	new = runemalloc(w->body.file->nname+100);
	i = 0;
	runemove(new+i, w->body.file->name, w->body.file->nname);
	i += w->body.file->nname;
	runemove(new+i, Ldelsnarf, 10);
	i += 10;
	if(w->filemenu){
		if(w->body.needundo || w->body.file->delta.nc>0 || w->body.ncache){
			runemove(new+i, Lundo, 5);
			i += 5;
		}
		if(w->body.file->epsilon.nc > 0){
			runemove(new+i, Lredo, 5);
			i += 5;
		}
		dirty = w->body.file->nname && (w->body.ncache || w->body.file->seq!=w->putseq);
		if(!w->isdir && dirty){
			runemove(new+i, Lput, 4);
			i += 4;
		}
	}
	if(w->isdir){
		runemove(new+i, Lget, 4);
		i += 4;
	}
	runemove(new+i, Lpipe, 2);
	i += 2;
	r = runestrchr(old, '|');
	if(r)
		k = r-old+1;
	else{
		k = w->tag.file->b.nc;
		if(w->body.file->seq == 0){
			runemove(new+i, Llook, 6);
			i += 6;
		}
	}
	new[i] = 0;

	/* replace tag if the new one is different */
	resize = 0;
	if(runeeq(new, i, old, k) == FALSE){
		resize = 1;
		n = k;
		if(n > i)
			n = i;
		for(j=0; j<n; j++)
			if(old[j] != new[j])
				break;
		q0 = w->tag.q0;
		q1 = w->tag.q1;
		textdelete(&w->tag, j, k, TRUE);
		textinsert(&w->tag, j, new+j, i-j, TRUE);
		/* try to preserve user selection */
		r = runestrchr(old, '|');
		if(r){
			bar = r-old;
			if(q0 > bar){
				bar = (runestrchr(new, '|')-new)-bar;
				w->tag.q0 = q0+bar;
				w->tag.q1 = q1+bar;
			}
		}
	}
	free(old);
	free(new);
	w->tag.file->mod = FALSE;
	n = w->tag.file->b.nc+w->tag.ncache;
	if(w->tag.q0 > n)
		w->tag.q0 = n;
	if(w->tag.q1 > n)
		w->tag.q1 = n;
	textsetselect(&w->tag, w->tag.q0, w->tag.q1);
	windrawbutton(w);
	if(resize){
		w->tagsafe = 0;
		winresize(w, w->r, TRUE, TRUE);
	}
}

void
winsettag(Window *w)
{
	int i;
	File *f;
	Window *v;

	f = w->body.file;
	for(i=0; i<f->ntext; i++){
		v = f->text[i]->w;
		if(v->col->safe || v->body.fr.maxlines>0)
			winsettag1(v);
	}
}

void
wincommit(Window *w, Text *t)
{
	Rune *r;
	int i;
	File *f;

	textcommit(t, TRUE);
	f = t->file;
	if(f->ntext > 1)
		for(i=0; i<f->ntext; i++)
			textcommit(f->text[i], FALSE);	/* no-op for t */
	if(t->what == Body)
		return;
	r = runemalloc(w->tag.file->b.nc);
	bufread(&w->tag.file->b, 0, r, w->tag.file->b.nc);
	for(i=0; i<w->tag.file->b.nc; i++)
		if(r[i]==' ' || r[i]=='\t')
			break;
	if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){
		seq++;
		filemark(w->body.file);
		w->body.file->mod = TRUE;
		w->dirty = TRUE;
		winsetname(w, r, i);
		winsettag(w);
	}
	free(r);
}

void
winaddincl(Window *w, Rune *r, int n)
{
	char *a;
	Dir *d;
	Runestr rs;

	a = runetobyte(r, n);
	d = dirstat(a);
	if(d == nil){
		if(a[0] == '/')
			goto Rescue;
		rs = dirname(&w->body, r, n);
		r = rs.r;
		n = rs.nr;
		free(a);
		a = runetobyte(r, n);
		d = dirstat(a);
		if(d == nil)
			goto Rescue;
		r = runerealloc(r, n+1);
		r[n] = 0;
	}
	free(a);
	if((d->qid.type&QTDIR) == 0){
		free(d);
		warning(nil, "%s: not a directory\n", a);
		free(r);
		return;
	}
	free(d);
	w->nincl++;
	w->incl = realloc(w->incl, w->nincl*sizeof(Rune*));
	memmove(w->incl+1, w->incl, (w->nincl-1)*sizeof(Rune*));
	w->incl[0] = runemalloc(n+1);
	runemove(w->incl[0], r, n);
	free(r);
	return;

Rescue:
	warning(nil, "%s: %r\n", a);
	free(r);
	free(a);
	return;
}

int
winclean(Window *w, int conservative)	/* as it stands, conservative is always TRUE */
{
	if(w->isscratch || w->isdir)	/* don't whine if it's a guide file, error window, etc. */
		return TRUE;
	if(!conservative && w->nopen[QWevent]>0)
		return TRUE;
	if(w->dirty){
		if(w->body.file->nname)
			warning(nil, "%.*S modified\n", w->body.file->nname, w->body.file->name);
		else{
			if(w->body.file->b.nc < 100)	/* don't whine if it's too small */
				return TRUE;
			warning(nil, "unnamed file modified\n");
		}
		w->dirty = FALSE;
		return FALSE;
	}
	return TRUE;
}

char*
winctlprint(Window *w, char *buf, int fonts)
{
	sprint(buf, "%11d %11d %11d %11d %11d ", w->id, w->tag.file->b.nc,
		w->body.file->b.nc, w->isdir, w->dirty);
	if(fonts)
		return smprint("%s%11d %q %11d ", buf, Dx(w->body.fr.r), 
			w->body.reffont->f->name, w->body.fr.maxtab);
	return buf;
}

void
winevent(Window *w, char *fmt, ...)
{
	int n;
	char *b;
	Xfid *x;
	va_list arg;

	if(w->nopen[QWevent] == 0)
		return;
	if(w->owner == 0)
		error("no window owner");
	va_start(arg, fmt);
	b = vsmprint(fmt, arg);
	va_end(arg);
	if(b == nil)
		error("vsmprint failed");
	n = strlen(b);
	w->events = erealloc(w->events, w->nevents+1+n);
	w->events[w->nevents++] = w->owner;
	memmove(w->events+w->nevents, b, n);
	free(b);
	w->nevents += n;
	x = w->eventx;
	if(x){
		w->eventx = nil;
		sendp(x->c, nil);
	}
}
