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

static Rune Lcolhdr[] = {
	'N', 'e', 'w', 'c', 'o', 'l', ' ',
	'K', 'i', 'l', 'l', ' ',
	'P', 'u', 't', 'a', 'l', 'l', ' ',
	'D', 'u', 'm', 'p', ' ',
	'E', 'x', 'i', 't', ' ',
	0
};

void
rowinit(Row *row, Rectangle r)
{
	Rectangle r1;
	Text *t;

	draw(screen, r, display->white, nil, ZP);
	row->r = r;
	row->col = nil;
	row->ncol = 0;
	r1 = r;
	r1.max.y = r1.min.y + font->height;
	t = &row->tag;
	textinit(t, fileaddtext(nil, t), r1, rfget(FALSE, FALSE, FALSE, nil), tagcols);
	t->what = Rowtag;
	t->row = row;
	t->w = nil;
	t->col = nil;
	r1.min.y = r1.max.y;
	r1.max.y += Border;
	draw(screen, r1, display->black, nil, ZP);
	textinsert(t, 0, Lcolhdr, 29, TRUE);
	textsetselect(t, t->file->b.nc, t->file->b.nc);
}

Column*
rowadd(Row *row, Column *c, int x)
{
	Rectangle r, r1;
	Column *d;
	int i;

	d = nil;
	r = row->r;
	r.min.y = row->tag.fr.r.max.y+Border;
	if(x<r.min.x && row->ncol>0){	/*steal 40% of last column by default */
		d = row->col[row->ncol-1];
		x = d->r.min.x + 3*Dx(d->r)/5;
	}
	/* look for column we'll land on */
	for(i=0; i<row->ncol; i++){
		d = row->col[i];
		if(x < d->r.max.x)
			break;
	}
	if(row->ncol > 0){
		if(i < row->ncol)
			i++;	/* new column will go after d */
		r = d->r;
		if(Dx(r) < 100)
			return nil;
		draw(screen, r, display->white, nil, ZP);
		r1 = r;
		r1.max.x = min(x-Border, r.max.x-50);
		if(Dx(r1) < 50)
			r1.max.x = r1.min.x+50;
		colresize(d, r1);
		r1.min.x = r1.max.x;
		r1.max.x = r1.min.x+Border;
		draw(screen, r1, display->black, nil, ZP);
		r.min.x = r1.max.x;
	}
	if(c == nil){
		c = emalloc(sizeof(Column));
		colinit(c, r);
		incref(&reffont.ref);
	}else
		colresize(c, r);
	c->row = row;
	c->tag.row = row;
	row->col = realloc(row->col, (row->ncol+1)*sizeof(Column*));
	memmove(row->col+i+1, row->col+i, (row->ncol-i)*sizeof(Column*));
	row->col[i] = c;
	row->ncol++;
	clearmouse();
	return c;
}

void
rowresize(Row *row, Rectangle r)
{
	int i, dx, odx;
	Rectangle r1, r2;
	Column *c;

	dx = Dx(r);
	odx = Dx(row->r);
	row->r = r;
	r1 = r;
	r1.max.y = r1.min.y + font->height;
	textresize(&row->tag, r1);
	r1.min.y = r1.max.y;
	r1.max.y += Border;
	draw(screen, r1, display->black, nil, ZP);
	r.min.y = r1.max.y;
	r1 = r;
	r1.max.x = r1.min.x;
	for(i=0; i<row->ncol; i++){
		c = row->col[i];
		r1.min.x = r1.max.x;
		if(i == row->ncol-1)
			r1.max.x = r.max.x;
		else
			r1.max.x = r1.min.x+Dx(c->r)*dx/odx;
		if(i > 0){
			r2 = r1;
			r2.max.x = r2.min.x+Border;
			draw(screen, r2, display->black, nil, ZP);
			r1.min.x = r2.max.x;
		}
		colresize(c, r1);
	}
}

void
rowdragcol(Row *row, Column *c, int _0)
{
	Rectangle r;
	int i, b, x;
	Point p, op;
	Column *d;

	USED(_0);

	clearmouse();
	setcursor(mousectl, &boxcursor);
	b = mouse->buttons;
	op = mouse->xy;
	while(mouse->buttons == b)
		readmouse(mousectl);
	setcursor(mousectl, nil);
	if(mouse->buttons){
		while(mouse->buttons)
			readmouse(mousectl);
		return;
	}

	for(i=0; i<row->ncol; i++)
		if(row->col[i] == c)
			goto Found;
	error("can't find column");

  Found:
	if(i == 0)
		return;
	p = mouse->xy;
	if((abs(p.x-op.x)<5 && abs(p.y-op.y)<5))
		return;
	if((i>0 && p.x<row->col[i-1]->r.min.x) || (i<row->ncol-1 && p.x>c->r.max.x)){
		/* shuffle */
		x = c->r.min.x;
		rowclose(row, c, FALSE);
		if(rowadd(row, c, p.x) == nil)	/* whoops! */
		if(rowadd(row, c, x) == nil)		/* WHOOPS! */
		if(rowadd(row, c, -1)==nil){		/* shit! */
			rowclose(row, c, TRUE);
			return;
		}
		colmousebut(c);
		return;
	}
	d = row->col[i-1];
	if(p.x < d->r.min.x+80+Scrollwid)
		p.x = d->r.min.x+80+Scrollwid;
	if(p.x > c->r.max.x-80-Scrollwid)
		p.x = c->r.max.x-80-Scrollwid;
	r = d->r;
	r.max.x = c->r.max.x;
	draw(screen, r, display->white, nil, ZP);
	r.max.x = p.x;
	colresize(d, r);
	r = c->r;
	r.min.x = p.x;
	r.max.x = r.min.x;
	r.max.x += Border;
	draw(screen, r, display->black, nil, ZP);
	r.min.x = r.max.x;
	r.max.x = c->r.max.x;
	colresize(c, r);
	colmousebut(c);
}

void
rowclose(Row *row, Column *c, int dofree)
{
	Rectangle r;
	int i;

	for(i=0; i<row->ncol; i++)
		if(row->col[i] == c)
			goto Found;
	error("can't find column");
  Found:
	r = c->r;
	if(dofree)
		colcloseall(c);
	memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*));
	row->ncol--;
	row->col = realloc(row->col, row->ncol*sizeof(Column*));
	if(row->ncol == 0){
		draw(screen, r, display->white, nil, ZP);
		return;
	}
	if(i == row->ncol){		/* extend last column right */
		c = row->col[i-1];
		r.min.x = c->r.min.x;
		r.max.x = row->r.max.x;
	}else{			/* extend next window left */
		c = row->col[i];
		r.max.x = c->r.max.x;
	}
	draw(screen, r, display->white, nil, ZP);
	colresize(c, r);
}

Column*
rowwhichcol(Row *row, Point p)
{
	int i;
	Column *c;

	for(i=0; i<row->ncol; i++){
		c = row->col[i];
		if(ptinrect(p, c->r))
			return c;
	}
	return nil;
}

Text*
rowwhich(Row *row, Point p)
{
	Column *c;

	if(ptinrect(p, row->tag.all))
		return &row->tag;
	c = rowwhichcol(row, p);
	if(c)
		return colwhich(c, p);
	return nil;
}

Text*
rowtype(Row *row, Rune r, Point p)
{
	Window *w;
	Text *t;

	clearmouse();
	qlock(&row->lk);
	if(bartflag)
		t = barttext;
	else
		t = rowwhich(row, p);
	if(t!=nil && !(t->what==Tag && ptinrect(p, t->scrollr))){
		w = t->w;
		if(w == nil)
			texttype(t, r);
		else{
			winlock(w, 'K');
			wintype(w, t, r);
			winunlock(w);
		}
	}
	qunlock(&row->lk);
	return t;
}

int
rowclean(Row *row)
{
	int clean;
	int i;

	clean = TRUE;
	for(i=0; i<row->ncol; i++)
		clean &= colclean(row->col[i]);
	return clean;
}

void
rowdump(Row *row, char *file)
{
	int i, j, fd, m, n, dumped;
	uint q0, q1;
	Biobuf *b;
	char *buf, *a, *fontname;
	Rune *r;
	Column *c;
	Window *w, *w1;
	Text *t;

	if(row->ncol == 0)
		return;
	buf = fbufalloc();
	if(file == nil){
		if(home == nil){
			warning(nil, "can't find file for dump: $home not defined\n");
			goto Rescue;
		}
		sprint(buf, "%s/acme.dump", home);
		file = buf;
	}
	fd = create(file, OWRITE, 0600);
	if(fd < 0){
		warning(nil, "can't open %s: %r\n", file);
		goto Rescue;
	}
	b = emalloc(sizeof(Biobuf));
	Binit(b, fd, OWRITE);
	r = fbufalloc();
	Bprint(b, "%s\n", wdir);
	Bprint(b, "%s\n", fontnames[0]);
	Bprint(b, "%s\n", fontnames[1]);
	for(i=0; i<row->ncol; i++){
		c = row->col[i];
		Bprint(b, "%11.7f", 100.0*(c->r.min.x-row->r.min.x)/Dx(row->r));
		if(i == row->ncol-1)
			Bputc(b, '\n');
		else
			Bputc(b, ' ');
	}
	for(i=0; i<row->ncol; i++){
		c = row->col[i];
		for(j=0; j<c->nw; j++)
			c->w[j]->body.file->dumpid = 0;
	}
	for(i=0; i<row->ncol; i++){
		c = row->col[i];
		for(j=0; j<c->nw; j++){
			w = c->w[j];
			wincommit(w, &w->tag);
			t = &w->body;
			/* windows owned by others get special treatment */
			if(w->nopen[QWevent] > 0)
				if(w->dumpstr == nil)
					continue;
			/* zeroxes of external windows are tossed */
			if(t->file->ntext > 1)
				for(n=0; n<t->file->ntext; n++){
					w1 = t->file->text[n]->w;
					if(w == w1)
						continue;
					if(w1->nopen[QWevent])
						goto Continue2;
				}
			fontname = "";
			if(t->reffont->f != font)
				fontname = t->reffont->f->name;
			if(t->file->nname)
				a = runetobyte(t->file->name, t->file->nname);
			else
				a = emalloc(1);
			if(t->file->dumpid){
				dumped = FALSE;
				Bprint(b, "x%11d %11d %11d %11d %11.7f %s\n", i, t->file->dumpid,
					w->body.q0, w->body.q1,
					100.0*(w->r.min.y-c->r.min.y)/Dy(c->r),
					fontname);
			}else if(w->dumpstr){
				dumped = FALSE;
				Bprint(b, "e%11d %11d %11d %11d %11.7f %s\n", i, t->file->dumpid,
					0, 0,
					100.0*(w->r.min.y-c->r.min.y)/Dy(c->r),
					fontname);
			}else if((w->dirty==FALSE && access(a, 0)==0) || w->isdir){
				dumped = FALSE;
				t->file->dumpid = w->id;
				Bprint(b, "f%11d %11d %11d %11d %11.7f %s\n", i, w->id,
					w->body.q0, w->body.q1,
					100.0*(w->r.min.y-c->r.min.y)/Dy(c->r),
					fontname);
			}else{
				dumped = TRUE;
				t->file->dumpid = w->id;
				Bprint(b, "F%11d %11d %11d %11d %11.7f %11d %s\n", i, j,
					w->body.q0, w->body.q1,
					100.0*(w->r.min.y-c->r.min.y)/Dy(c->r),
					w->body.file->b.nc, fontname);
			}
			free(a);
			winctlprint(w, buf, 0);
			Bwrite(b, buf, strlen(buf));
			m = min(RBUFSIZE, w->tag.file->b.nc);
			bufread(&w->tag.file->b, 0, r, m);
			n = 0;
			while(n<m && r[n]!='\n')
				n++;
			r[n++] = '\n';
			Bprint(b, "%.*S", n, r);
			if(dumped){
				q0 = 0;
				q1 = t->file->b.nc;
				while(q0 < q1){
					n = q1 - q0;
					if(n > BUFSIZE/UTFmax)
						n = BUFSIZE/UTFmax;
					bufread(&t->file->b, q0, r, n);
					Bprint(b, "%.*S", n, r);
					q0 += n;
				}
			}
			if(w->dumpstr){
				if(w->dumpdir)
					Bprint(b, "%s\n%s\n", w->dumpdir, w->dumpstr);
				else
					Bprint(b, "\n%s\n", w->dumpstr);
			}
    Continue2:;
		}
	}
	Bterm(b);
	close(fd);
	free(b);
	fbuffree(r);

   Rescue:
	fbuffree(buf);
}

static
char*
rdline(Biobuf *b, int *linep)
{
	char *l;

	l = Brdline(b, '\n');
	if(l)
		(*linep)++;
	return l;
}

/*
 * Get font names from load file so we don't load fonts we won't use
 */
void
rowloadfonts(char *file)
{
	int i;
	Biobuf *b;
	char *l;

	b = Bopen(file, OREAD);
	if(b == nil)
		return;
	/* current directory */
	l = Brdline(b, '\n');
	if(l == nil)
		goto Return;
	/* global fonts */
	for(i=0; i<2; i++){
		l = Brdline(b, '\n');
		if(l == nil)
			goto Return;
		l[Blinelen(b)-1] = 0;
		if(*l && strcmp(l, fontnames[i])!=0){
			free(fontnames[i]);
			fontnames[i] = estrdup(l);
		}
	}
    Return:
	Bterm(b);
}

int
rowload(Row *row, char *file, int initing)
{
	int i, j, line, y, nr, nfontr, n, ns, ndumped, dumpid, x, fd;
	double percent;
	Biobuf *b, *bout;
	char *buf, *l, *t, *fontname;
	Rune *r, rune, *fontr;
	Column *c, *c1, *c2;
	uint q0, q1;
	Rectangle r1, r2;
	Window *w;

	buf = fbufalloc();
	if(file == nil){
		if(home == nil){
			warning(nil, "can't find file for load: $home not defined\n");
			goto Rescue1;
		}
		sprint(buf, "%s/acme.dump", home);
		file = buf;
	}
	b = Bopen(file, OREAD);
	if(b == nil){
		warning(nil, "can't open load file %s: %r\n", file);
		goto Rescue1;
	}
	/* current directory */
	line = 0;
	l = rdline(b, &line);
	if(l == nil)
		goto Rescue2;
	l[Blinelen(b)-1] = 0;
	if(chdir(l) < 0){
		warning(nil, "can't chdir %s\n", l);
		goto Rescue2;
	}
	/* global fonts */
	for(i=0; i<2; i++){
		l = rdline(b, &line);
		if(l == nil)
			goto Rescue2;
		l[Blinelen(b)-1] = 0;
		if(*l && strcmp(l, fontnames[i])!=0)
			rfget(i, TRUE, i==0 && initing, l);
	}
	if(initing && row->ncol==0)
		rowinit(row, screen->clipr);
	l = rdline(b, &line);
	if(l == nil)
		goto Rescue2;
	j = Blinelen(b)/12;
	if(j<=0 || j>10)
		goto Rescue2;
	for(i=0; i<j; i++){
		percent = atof(l+i*12);
		if(percent<0 || percent>=100)
			goto Rescue2;
		x = row->r.min.x+percent*Dx(row->r)/100+0.5;
		if(i < row->ncol){
			if(i == 0)
				continue;
			c1 = row->col[i-1];
			c2 = row->col[i];
			r1 = c1->r;
			r2 = c2->r;
			if(x<Border)
				x = Border;
			r1.max.x = x-Border;
			r2.min.x = x;
			if(Dx(r1) < 50 || Dx(r2) < 50)
				continue;
			draw(screen, Rpt(r1.min, r2.max), display->white, nil, ZP);
			colresize(c1, r1);
			colresize(c2, r2);
			r2.min.x = x-Border;
			r2.max.x = x;
			draw(screen, r2, display->black, nil, ZP);
		}
		if(i >= row->ncol)
			rowadd(row, nil, x);
	}
	for(;;){
		l = rdline(b, &line);
		if(l == nil)
			break;
		dumpid = 0;
		switch(l[0]){
		case 'e':
			if(Blinelen(b) < 1+5*12+1)
				goto Rescue2;
			l = rdline(b, &line);	/* ctl line; ignored */
			if(l == nil)
				goto Rescue2;
			l = rdline(b, &line);	/* directory */
			if(l == nil)
				goto Rescue2;
			l[Blinelen(b)-1] = 0;
			if(*l == '\0'){
				if(home == nil)
					r = bytetorune("./", &nr);
				else{
					t = emalloc(strlen(home)+1+1);
					sprint(t, "%s/", home);
					r = bytetorune(t, &nr);
					free(t);
				}
			}else
				r = bytetorune(l, &nr);
			l = rdline(b, &line);	/* command */
			if(l == nil)
				goto Rescue2;
			t = emalloc(Blinelen(b)+1);
			memmove(t, l, Blinelen(b));
			run(nil, t, r, nr, TRUE, nil, nil, FALSE);
			/* r is freed in run() */
			continue;
		case 'f':
			if(Blinelen(b) < 1+5*12+1)
				goto Rescue2;
			fontname = l+1+5*12;
			ndumped = -1;
			break;
		case 'F':
			if(Blinelen(b) < 1+6*12+1)
				goto Rescue2;
			fontname = l+1+6*12;
			ndumped = atoi(l+1+5*12+1);
			break;
		case 'x':
			if(Blinelen(b) < 1+5*12+1)
				goto Rescue2;
			fontname = l+1+5*12;
			ndumped = -1;
			dumpid = atoi(l+1+1*12);
			break;
		default:
			goto Rescue2;
		}
		l[Blinelen(b)-1] = 0;
		fontr = nil;
		nfontr = 0;
		if(*fontname)
			fontr = bytetorune(fontname, &nfontr);
		i = atoi(l+1+0*12);
		j = atoi(l+1+1*12);
		q0 = atoi(l+1+2*12);
		q1 = atoi(l+1+3*12);
		percent = atof(l+1+4*12);
		if(i<0 || i>10)
			goto Rescue2;
		if(i > row->ncol)
			i = row->ncol;
		c = row->col[i];
		y = c->r.min.y+(percent*Dy(c->r))/100+0.5;
		if(y<c->r.min.y || y>=c->r.max.y)
			y = -1;
		if(dumpid == 0)
			w = coladd(c, nil, nil, y);
		else
			w = coladd(c, nil, lookid(dumpid, TRUE), y);
		if(w == nil)
			continue;
		w->dumpid = j;
		l = rdline(b, &line);
		if(l == nil)
			goto Rescue2;
		l[Blinelen(b)-1] = 0;
		r = bytetorune(l+5*12, &nr);
		ns = -1;
		for(n=0; n<nr; n++){
			if(r[n] == '/')
				ns = n;
			if(r[n] == ' ')
				break;
		}
		if(dumpid == 0)
			winsetname(w, r, n);
		for(; n<nr; n++)
			if(r[n] == '|')
				break;
		wincleartag(w);
		textinsert(&w->tag, w->tag.file->b.nc, r+n+1, nr-(n+1), TRUE);
		if(ndumped >= 0){
			/* simplest thing is to put it in a file and load that */
			sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
			fd = create(buf, OWRITE, 0600);
			if(fd < 0){
				free(r);
				warning(nil, "can't create temp file: %r\n");
				goto Rescue2;
			}
			bout = emalloc(sizeof(Biobuf));
			Binit(bout, fd, OWRITE);
			for(n=0; n<ndumped; n++){
				rune = Bgetrune(b);
				if(rune == '\n')
					line++;
				if(rune == (Rune)Beof){
					free(r);
					Bterm(bout);
					free(bout);
					close(fd);
					goto Rescue2;
				}
				Bputrune(bout, rune);
			}
			Bterm(bout);
			free(bout);
			textload(&w->body, 0, buf, 1);
			remove(buf);
			close(fd);
			w->body.file->mod = TRUE;
			for(n=0; n<w->body.file->ntext; n++)
				w->body.file->text[n]->w->dirty = TRUE;
			winsettag(w);
		}else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
			get(&w->body, nil, nil, FALSE, XXX, nil, 0);
		if(fontr){
			fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
			free(fontr);
		}
		free(r);
		if(q0>w->body.file->b.nc || q1>w->body.file->b.nc || q0>q1)
			q0 = q1 = 0;
		textshow(&w->body, q0, q1, 1);
		w->maxlines = min(w->body.fr.nlines, max(w->maxlines, w->body.fr.maxlines));
	}
	Bterm(b);

	fbuffree(buf);
	return TRUE;

Rescue2:
	warning(nil, "bad load file %s:%d\n", file, line);
	Bterm(b);
Rescue1:
	fbuffree(buf);
	return FALSE;
}

void
allwindows(void (*f)(Window*, void*), void *arg)
{
	int i, j;
	Column *c;

	for(i=0; i<row.ncol; i++){
		c = row.col[i];
		for(j=0; j<c->nw; j++)
			(*f)(c->w[j], arg);
	}
}
