#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <event.h>
#include <bio.h>

typedef struct	Thing	Thing;

struct Thing
{
	Image	*b;
	Subfont 	*s;
	char		*name;	/* file name */
	int		face;		/* is 48x48 face file or cursor file*/
	Rectangle r;		/* drawing region */
	Rectangle tr;		/* text region */
	Rectangle er;		/* entire region */
	long		c;		/* character number in subfont */
	int		mod;	/* modified */
	int		mag;		/* magnification */
	Rune		off;		/* offset for subfont indices */
	Thing	*parent;	/* thing of which i'm an edit */
	Thing	*next;
};

enum
{
	Border	= 1,
	Up		= 1,
	Down	= 0,
	Mag		= 4,
	Maxmag	= 10,
};

enum
{
	NORMAL	=0,
	FACE	=1,
	CURSOR	=2
};

enum
{
	Mopen,
	Mread,
	Mwrite,
	Mcopy,
	Mchar,
	Mpixels,
	Mclose,
	Mexit,
};

enum
{
	Blue	= 54,
};

char	*menu3str[] = {
	[Mopen]	"open",
	[Mread]	"read",
	[Mwrite]	"write",
	[Mcopy]	"copy",
	[Mchar]	"char",
	[Mpixels]	"pixels",
	[Mclose]	"close",
	[Mexit]	"exit",
	0,
};

Menu	menu3 = {
	menu3str
};

Cursor sweep0 = {
	{-7, -7},
	{0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
	 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
	 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0},
	{0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
	 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
	 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00}
};

Cursor box = {
	{-7, -7},
	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
	 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
	{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
	 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}
};

Cursor sight = {
	{-7, -7},
	{0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
	 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
	 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
	 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,},
	{0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
	 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
	 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
	 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,}
};

Cursor pixel = {
	{-7, -7},
	{0x1f, 0xf8, 0x3f, 0xfc,  0x7f, 0xfe,  0xf8, 0x1f,
	0xf0, 0x0f,  0xe0, 0x07, 0xe0, 0x07, 0xfe, 0x7f, 
	0xfe, 0x7f, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f, 
	0x78, 0x1f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, },
	{0x00, 0x00, 0x0f, 0xf0, 0x31, 0x8c, 0x21, 0x84, 
	0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x40, 0x02, 
	0x40, 0x02, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 
	0x21, 0x84, 0x31, 0x8c, 0x0f, 0xf0, 0x00, 0x00, }
};

Cursor busy = {
	{-7, -7},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	 0x00, 0x00, 0x00, 0x0c, 0x00, 0x8e, 0x1d, 0xc7,
	 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xff, 0x7f, 0xfe, 
	 0x3f, 0xf8, 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00,},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x82,
	 0x04, 0x41, 0xff, 0xe1, 0x5f, 0xf1, 0x3f, 0xfe, 
	 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,}
};

Cursor skull = {
	{-7,-7},
	{0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe7, 0xe7, 
	 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x1f, 0xf8, 
	 0x0f, 0xf0, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 
	 0xef, 0xf7, 0xc7, 0xe3, 0x00, 0x00, 0x00, 0x00,},
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
	 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
	 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
	 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
};

Rectangle	cntlr;		/* control region */
Rectangle	editr;		/* editing region */
Rectangle	textr;		/* text region */
Thing		*thing;
Mouse		mouse;
char		hex[] = "0123456789abcdefABCDEF";
jmp_buf		err;
char		*file;
int		mag;
int		but1val = 0;
int		but2val = 255;
int		invert = 0;
Image		*values[256];
Image		*greyvalues[256];
uchar		data[8192];

Thing*	tget(char*);
void	mesg(char*, ...);
void	drawthing(Thing*, int);
void	xselect(void);
void	menu(void);
void	error(Display*, char*);
void	buttons(int);
void	drawall(void);
void	tclose1(Thing*);

void
main(int argc, char *argv[])
{
	int i;
	Event e;
	Thing *t;

	mag = Mag;
	if(initdraw(error, 0, "tweak") < 0){
		fprint(2, "tweak: initdraw failed: %r\n");
		exits("initdraw");
	}
	for(i=0; i<256; i++){
		values[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, cmap2rgba(i));
		greyvalues[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (i<<24)|(i<<16)|(i<<8)|0xFF);
		if(values[i] == 0 || greyvalues[i] == 0)
			drawerror(display, "can't allocate image");
	}
	einit(Emouse|Ekeyboard);
	eresized(0);
	i = 1;
	setjmp(err);
	for(; i<argc; i++){
		file = argv[i];
		t = tget(argv[i]);
		if(t)
			drawthing(t, 1);
		flushimage(display, 1);
	}
	file = 0;
	setjmp(err);
	for(;;)
		switch(event(&e)){
		case Ekeyboard:
			break;
		case Emouse:
			mouse = e.mouse;
			if(mouse.buttons & 3){
				xselect();
				break;
			}
			if(mouse.buttons & 4)
				menu();
		}
}

int
xlog2(int n)
{
	int i;

	for(i=0; (1<<i) <= n; i++)
		if((1<<i) == n)
			return i;
	fprint(2, "log2 %d = 0\n", n);
	return 0;
}

void
error(Display *d, char *s)
{
	USED(d);

	if(file)
		mesg("can't read %s: %s: %r", file, s);
	else
		mesg("/dev/bitblt error: %s", s);
	if(err[0])
		longjmp(err, 1);
	exits(s);
}

void
redraw(Thing *t)
{
	Thing *nt;
	Point p;

	if(thing==0 || thing==t)
		draw(screen, editr, display->white, nil, ZP);
	if(thing == 0)
		return;
	if(thing != t){
		for(nt=thing; nt->next!=t; nt=nt->next)
			;
		draw(screen, Rect(screen->r.min.x, nt->er.max.y, editr.max.x, editr.max.y),
			display->white, nil, ZP);
	}
	for(nt=t; nt; nt=nt->next){
		drawthing(nt, 0);
		if(nt->next == 0){
			p = Pt(editr.min.x, nt->er.max.y);
			draw(screen, Rpt(p, editr.max), display->white, nil, ZP);
		}
	}
	mesg("");
}

void
eresized(int new)
{
	if(new && getwindow(display, Refnone) < 0)
		error(display, "can't reattach to window");
	cntlr = insetrect(screen->clipr, 1);
	editr = cntlr;
	textr = editr;
	textr.min.y = textr.max.y - font->height;
	cntlr.max.y = cntlr.min.y + font->height;
	editr.min.y = cntlr.max.y+1;
	editr.max.y = textr.min.y-1;
	draw(screen, screen->clipr, display->white, nil, ZP);
	draw(screen, Rect(editr.min.x, editr.max.y, editr.max.x+1, editr.max.y+1), display->black, nil, ZP);
	replclipr(screen, 0, editr);
	drawall();
}

void
mesgstr(Point p, int line, char *s)
{
	Rectangle c, r;

	r.min = p;
	r.min.y += line*font->height;
	r.max.y = r.min.y+font->height;
	r.max.x = editr.max.x;
	c = screen->clipr;
	replclipr(screen, 0, r);
	draw(screen, r, values[0xDD], nil, ZP);
	r.min.x++;
	string(screen, r.min, display->black, ZP, font, s);
	replclipr(screen, 0, c);
	flushimage(display, 1);
}

void
mesg(char *fmt, ...)
{
	char buf[1024];
	va_list arg;

	va_start(arg, fmt);
	vseprint(buf, buf+sizeof(buf), fmt, arg);
	va_end(arg);
	mesgstr(textr.min, 0, buf);
}

void
tmesg(Thing *t, int line, char *fmt, ...)
{
	char buf[1024];
	va_list arg;

	va_start(arg, fmt);
	vseprint(buf, buf+sizeof(buf), fmt, arg);
	va_end(arg);
	mesgstr(t->tr.min, line, buf);
}


void
scntl(char *l)
{
	sprint(l, "mag: %d  but1: %d  but2: %d  invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);
}

void
cntl(void)
{
	char buf[256];

	scntl(buf);
	mesgstr(cntlr.min, 0, buf);
}

void
stext(Thing *t, char *l0, char *l1)
{
	Fontchar *fc;
	char buf[256];

	l1[0] = 0;
	sprint(buf, "depth:%d r:%d %d  %d %d ", 
		t->b->depth, t->b->r.min.x, t->b->r.min.y,
		t->b->r.max.x, t->b->r.max.y);
	if(t->parent)
		sprint(buf+strlen(buf), "mag: %d ", t->mag);
	sprint(l0, "%s file: %s", buf, t->name);
	if(t->c >= 0){
		fc = &t->parent->s->info[t->c];
		sprint(l1, "c(hex): %x c(char): %C x: %d "
			   "top: %d bottom: %d left: %d width: %d iwidth: %d",
			(int)(t->c+t->parent->off), (int)(t->c+t->parent->off),
			fc->x, fc->top, fc->bottom, fc->left,
			fc->width, Dx(t->b->r));
	}else if(t->s)
		sprint(l1, "offset(hex): %ux n:%d  height:%d  ascent:%d",
			t->off, t->s->n, t->s->height, t->s->ascent);
}

void
text(Thing *t)
{
	char l0[256], l1[256];

	stext(t, l0, l1);
	tmesg(t, 0, l0);
	if(l1[0])
		tmesg(t, 1, l1);
}

void
drawall(void)
{
	Thing *t;

	cntl();
	for(t=thing; t; t=t->next)
		drawthing(t, 0);
}

int
value(Image *b, int x)
{
	int v, l, w;
	uchar mask;

	w = b->depth;
	if(w > 8){
		mesg("ldepth too large");
		return 0;
	}
	l = xlog2(w);
	mask = (1<<w)-1;		/* ones at right end of word */
	x -= b->r.min.x&~(7>>l);	/* adjust x relative to first pixel */
	v = data[x>>(3-l)];
	v >>= ((7>>l)<<l) - ((x&(7>>l))<<l);	/* pixel at right end of word */
	v &= mask;			/* pixel at right end of word */
	return v;
}

int
bvalue(int v, int d)
{
	v &= (1<<d)-1;
	if(d > screen->depth)
		v >>= d - screen->depth;
	else
		while(d < screen->depth && d < 8){
			v |= v << d;
			d <<= 1;
		}
	if(v<0 || v>255){
		mesg("internal error: bad color");
		return Blue;
	}
	return v;
}

void
drawthing(Thing *nt, int link)
{
	int n, nl, nf, i, x, y, sx, sy, fdx, dx, dy, v;
	Thing *t;
	Subfont *s;
	Image *b, *col;
	Point p, p1, p2;

	if(link){
		nt->next = 0;
		if(thing == 0){
			thing = nt;
			y = editr.min.y;
		}else{
			for(t=thing; t->next; t=t->next)
				;
			t->next = nt;
			y = t->er.max.y;
		}
	}else{
		if(thing == nt)
			y = editr.min.y;
		else{
			for(t=thing; t->next!=nt; t=t->next)
				;
			y = t->er.max.y;
		}
	}
	s = nt->s;
	b = nt->b;
	nl = font->height;
	if(s || nt->c>=0)
		nl += font->height;
	fdx = Dx(editr) - 2*Border;
	dx = Dx(b->r);
	dy = Dy(b->r);
	if(nt->mag > 1){
		dx *= nt->mag;
		dy *= nt->mag;
		fdx -= fdx%nt->mag;
	}
	nf = 1 + dx/fdx;
	nt->er.min.y = y;
	nt->er.min.x = editr.min.x;
	nt->er.max.x = nt->er.min.x + Border + dx + Border;
	if(nt->er.max.x > editr.max.x)
		nt->er.max.x = editr.max.x;
	nt->er.max.y = nt->er.min.y + Border + nf*(dy+Border);
	nt->r = insetrect(nt->er, Border);
	nt->er.max.x = editr.max.x;
	draw(screen, nt->er, display->white, nil, ZP);
	for(i=0; i<nf; i++){
		p1 = Pt(nt->r.min.x-1, nt->r.min.y+i*(Border+dy));
		/* draw portion of bitmap */
		p = Pt(p1.x+1, p1.y);
		if(nt->mag == 1)
			draw(screen, Rect(p.x, p.y, p.x+fdx+Dx(b->r), p.y+Dy(b->r)),
				b, nil, Pt(b->r.min.x+i*fdx, b->r.min.y));
		else{
			for(y=b->r.min.y; y<b->r.max.y; y++){
				sy = p.y+(y-b->r.min.y)*nt->mag;
				if((n=unloadimage(b, Rect(b->r.min.x, y, b->r.max.x, y+1), data, sizeof data)) < 0)
					fprint(2, "unloadimage: %r\n");
				for(x=b->r.min.x+i*(fdx/nt->mag); x<b->r.max.x; x++){
					sx = p.x+(x-i*(fdx/nt->mag)-b->r.min.x)*nt->mag;
					if(sx >= nt->r.max.x)
						break;
					v = bvalue(value(b, x), b->depth);
					if(v == 255)
						continue;
					if(b->chan == GREY8)
						draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
							greyvalues[v], nil, ZP);
					else
						draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
							values[v], nil, ZP);
				}

			}
		}
		/* line down left */
		if(i == 0)
			col = display->black;
		else
			col = display->white;
		draw(screen, Rect(p1.x, p1.y, p1.x+1, p1.y+dy+Border), col, nil, ZP);
		/* line across top */
		draw(screen, Rect(p1.x, p1.y-1, nt->r.max.x+Border, p1.y), display->black, nil, ZP);
		p2 = p1;
		if(i == nf-1){
			p2.x += 1 + dx%fdx;
			col = display->black;
		}else{
			p2.x = nt->r.max.x;
			col = display->white;
		}
		/* line down right */
		draw(screen, Rect(p2.x, p2.y, p2.x+1, p2.y+dy+Border), col, nil, ZP);
		/* line across bottom */
		if(i == nf-1){
			p1.y += Border+dy;
			draw(screen, Rect(p1.x, p1.y-1, p2.x,p1.y), display->black, nil, ZP);
		}
	}
	nt->tr.min.x = editr.min.x;
	nt->tr.max.x = editr.max.x;
	nt->tr.min.y = nt->er.max.y + Border;
	nt->tr.max.y = nt->tr.min.y + nl;
	nt->er.max.y = nt->tr.max.y + Border;
	text(nt);
}

int
tohex(int c)
{
	if('0'<=c && c<='9')
		return c - '0';
	if('a'<=c && c<='f')
		return 10 + (c - 'a');
	if('A'<=c && c<='F')
		return 10 + (c - 'A');
	return 0;
}

Thing*
tget(char *file)
{
	int i, j, fd, face, x, y, c, chan;
	Image *b;
	Subfont *s;
	Thing *t;
	Dir *d;
	jmp_buf oerr;
	uchar buf[256];
	char *data;

	buf[0] = '\0';
	errstr((char*)buf, sizeof buf);	/* flush pending error message */
	memmove(oerr, err, sizeof err);
	d = nil;
	if(setjmp(err)){
   Err:
		free(d);
		memmove(err, oerr, sizeof err);
		return 0;
	}
	fd = open(file, OREAD);
	if(fd < 0){
		mesg("can't open %s: %r", file);
		goto Err;
	}
	d = dirfstat(fd);
	if(d == nil){
		mesg("can't stat bitmap file %s: %r", file);
		close(fd);
		goto Err;
	}
	if(read(fd, buf, 11) != 11){
		mesg("can't read %s: %r", file);
		close(fd);
		goto Err;
	}
	seek(fd, 0, 0);
	data = (char*)buf;
	if(*data == '{')
		data++;
	if(memcmp(data, "0x", 2)==0 && data[4]==','){
		/*
		 * cursor file
		 */
		face = CURSOR;
		s = 0;
		data = malloc(d->length+1);
		if(data == 0){
			mesg("can't malloc buffer: %r");
			close(fd);
			goto Err;
		}
		data[d->length] = 0;
		if(read(fd, data, d->length) != d->length){
			mesg("can't read cursor file %s: %r", file);
			close(fd);
			goto Err;
		}
		b = allocimage(display, Rect(0, 0, 16, 32), GREY1, 0, DNofill);
		if(b == 0){
			mesg("image alloc failed file %s: %r", file);
			free(data);
			close(fd);
			goto Err;
		}
		i = 0;
		for(x=0;x<64; ){
			if((c=data[i]) == '\0')
				goto ill;
			if(c=='0' && data[i+1] == 'x'){
				i += 2;
				continue;
			}
			if(strchr(hex, c)){
				buf[x++] = (tohex(c)<<4) | tohex(data[i+1]);
				i += 2;
				continue;
			}
			i++;
		}
		loadimage(b, Rect(0, 0, 16, 32), buf, sizeof buf);
		free(data);
	}else if(memcmp(buf, "0x", 2)==0){
		/*
		 * face file
		 */
		face = FACE;
		s = 0;
		data = malloc(d->length+1);
		if(data == 0){
			mesg("can't malloc buffer: %r");
			close(fd);
			goto Err;
		}
		data[d->length] = 0;
		if(read(fd, data, d->length) != d->length){
			mesg("can't read bitmap file %s: %r", file);
			close(fd);
			goto Err;
		}
		for(y=0,i=0; i<d->length; i++)
			if(data[i] == '\n')
				y++;
		if(y == 0){
	ill:
			mesg("ill-formed face file %s", file);
			close(fd);
			free(data);
			goto Err;
		}
		for(x=0,i=0; (c=data[i])!='\n'; ){
			if(c==',' || c==' ' || c=='\t'){
				i++;
				continue;
			}
			if(c=='0' && data[i+1] == 'x'){
				i += 2;
				continue;
			}
			if(strchr(hex, c)){
				x += 4;
				i++;
				continue;
			}
			goto ill;
		}
		if(x % y)
			goto ill;
		switch(x / y){
		default:
			goto ill;
		case 1:
			chan = GREY1;
			break;
		case 2:
			chan = GREY2;
			break;
		case 4:
			chan = GREY4;
			break;
		case 8:
			chan = CMAP8;
			break;
		}
		b = allocimage(display, Rect(0, 0, y, y), chan, 0, -1);
		if(b == 0){
			mesg("image alloc failed file %s: %r", file);
			free(data);
			close(fd);
			goto Err;
		}
		i = 0;
		for(j=0; j<y; j++){
			for(x=0; (c=data[i])!='\n'; ){
				if(c=='0' && data[i+1] == 'x'){
					i += 2;
					continue;
				}
				if(strchr(hex, c)){
					buf[x++] = ~((tohex(c)<<4) | tohex(data[i+1]));
					i += 2;
					continue;
				}
				i++;
			}
			i++;
			loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf);
		}
		free(data);
	}else{
		face = NORMAL;
		s = 0;
		b = readimage(display, fd, 0);
		if(b == 0){
			mesg("can't read bitmap file %s: %r", file);
			close(fd);
			goto Err;
		}
		if(seek(fd, 0, 1) < d->length)
			s = readsubfonti(display, file, fd, b, 0);
	}
	close(fd);
	t = malloc(sizeof(Thing));
	if(t == 0){
   nomem:
		mesg("malloc failed: %r");
		if(s)
			freesubfont(s);
		else
			freeimage(b);
		goto Err;
	}
	t->name = strdup(file);
	if(t->name == 0){
		free(t);
		goto nomem;
	}
	t->b = b;
	t->s = s;
	t->face = face;
	t->mod = 0;
	t->parent = 0;
	t->c = -1;
	t->mag = 1;
	t->off = 0;
	memmove(err, oerr, sizeof err);
	return t;
}

int
atline(int x, Point p, char *line, char *buf)
{
	char *s, *c, *word, *hit;
	int w, wasblank;
	Rune r;

	wasblank = 1;
	hit = 0;
	word = 0;
	for(s=line; *s; s+=w){
		w = chartorune(&r, s);
		x += runestringnwidth(font, &r, 1);
		if(wasblank && r!=' ')
			word = s;
		wasblank = 0;
		if(r == ' '){
			if(x >= p.x)
				break;
			wasblank = 1;
		}
		if(r == ':')
			hit = word;
	}
	if(x < p.x)
		return 0;
	c = utfrune(hit, ':');
	strncpy(buf, hit, c-hit);
	buf[c-hit] = 0;
	return 1;
}

int
attext(Thing *t, Point p, char *buf)
{
	char l0[256], l1[256];

	if(!ptinrect(p, t->tr))
		return 0;
	stext(t, l0, l1);
	if(p.y < t->tr.min.y+font->height)
		return atline(t->r.min.x, p, l0, buf);
	else
		return atline(t->r.min.x, p, l1, buf);
}

int
type(char *buf, char *tag)
{
	Rune r;
	char *p;

	esetcursor(&busy);
	p = buf;
	for(;;){
		*p = 0;
		mesg("%s: %s", tag, buf);
		r = ekbd();
		switch(r){
		case '\n':
			mesg("");
			esetcursor(0);
			return p-buf;
		case 0x15:	/* control-U */
			p = buf;
			break;
		case '\b':
			if(p > buf)
				--p;
			break;
		default:
			p += runetochar(p, &r);
		}
	}
	return 0;	/* shut up compiler */
}

void
textedit(Thing *t, char *tag)
{
	char buf[256];
	char *s;
	Image *b;
	Subfont *f;
	Fontchar *fc, *nfc;
	Rectangle r;
	ulong chan;
	int i, ld, d, w, c, doredraw, fdx, x;
	Thing *nt;

	buttons(Up);
	if(type(buf, tag) == 0)
		return;
	if(strcmp(tag, "file") == 0){
		for(s=buf; *s; s++)
			if(*s <= ' '){
				mesg("illegal file name");
				return;
			}
		if(strcmp(t->name, buf) != 0){
			if(t->parent)
				t->parent->mod = 1;
			else
				t->mod = 1;
		}
		for(nt=thing; nt; nt=nt->next)
			if(t==nt || t->parent==nt || nt->parent==t){
				free(nt->name);
				nt->name = strdup(buf);
				if(nt->name == 0){
					mesg("malloc failed: %r");
					return;
				}
				text(nt);
			}
		return;
	}
	if(strcmp(tag, "depth") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (d=atoi(buf))<0 || d>8 || xlog2(d)<0){
			mesg("illegal ldepth");
			return;
		}
		if(d == t->b->depth)
			return;
		if(t->parent)
			t->parent->mod = 1;
		else
			t->mod = 1;
		if(d == 8)
			chan = CMAP8;
		else
			chan = CHAN1(CGrey, d);
		for(nt=thing; nt; nt=nt->next){
			if(nt!=t && nt!=t->parent && nt->parent!=t)
				continue;
			b = allocimage(display, nt->b->r, chan, 0, 0);
			if(b == 0){
	nobmem:
				mesg("image alloc failed: %r");
				return;
			}
			draw(b, b->r, nt->b, nil, nt->b->r.min);
			freeimage(nt->b);
			nt->b = b;
			if(nt->s){
				b = allocimage(display, nt->b->r, chan, 0, -1);
				if(b == 0)
					goto nobmem;
				draw(b, b->r, nt->b, nil, nt->b->r.min);
				f = allocsubfont(t->name, nt->s->n, nt->s->height, nt->s->ascent, nt->s->info, b);
				if(f == 0){
	nofmem:
					freeimage(b);
					mesg("can't make subfont: %r");
					return;
				}
				nt->s->info = 0;	/* prevent it being freed */
				nt->s->bits = 0;
				freesubfont(nt->s);
				nt->s = f;
			}
			drawthing(nt, 0);
		}
		return;
	}
	if(strcmp(tag, "mag") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<=0 || ld>Maxmag){
			mesg("illegal magnification");
			return;
		}
		if(t->mag == ld)
			return;
		t->mag = ld;
		redraw(t);
		return;
	}
	if(strcmp(tag, "r") == 0){
		if(t->s){
			mesg("can't change rectangle of subfont\n");
			return;
		}
		s = buf;
		r.min.x = strtoul(s, &s, 0);
		r.min.y = strtoul(s, &s, 0);
		r.max.x = strtoul(s, &s, 0);
		r.max.y = strtoul(s, &s, 0);
		if(Dx(r)<=0 || Dy(r)<=0){
			mesg("illegal rectangle");
			return;
		}
		if(t->parent)
			t = t->parent;
		for(nt=thing; nt; nt=nt->next){
			if(nt->parent==t && !rectinrect(nt->b->r, r))
				tclose1(nt);
		}
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, r, t->b, nil, r.min);
		freeimage(t->b);
		t->b = b;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		redraw(t);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "ascent") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0 || ld>t->s->height){
			mesg("illegal ascent");
			return;
		}
		if(t->s->ascent == ld)
			return;
		t->s->ascent = ld;
		text(t);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "height") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
			mesg("illegal height");
			return;
		}
		if(t->s->height == ld)
			return;
		t->s->height = ld;
		text(t);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "left")==0 || strcmp(tag, "width") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
			mesg("illegal value");
			return;
		}
		fc = &t->parent->s->info[t->c];
		if(strcmp(tag, "left")==0){
			if(fc->left == ld)
				return;
			fc->left = ld;
		}else{
			if(fc->width == ld)
				return;
			fc->width = ld;
		}
		text(t);
		t->parent->mod = 1;
		return;
	}
	if(strcmp(tag, "offset(hex)") == 0){
		if(!strchr(hex, buf[0])){
	illoff:
			mesg("illegal offset");
			return;
		}
		s = 0;
		ld = strtoul(buf, &s, 16);
		if(*s)
			goto illoff;
		t->off = ld;
		text(t);
		for(nt=thing; nt; nt=nt->next)
			if(nt->parent == t)
				text(nt);
		return;
	}
	if(strcmp(tag, "n") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<=0){
			mesg("illegal n");
			return;
		}
		f = t->s;
		if(w == f->n)
			return;
		doredraw = 0;
	again:
		for(nt=thing; nt; nt=nt->next)
			if(nt->parent == t){
				doredraw = 1;
				tclose1(nt);
				goto again;
			}
		r = t->b->r;
		if(w < f->n)
			r.max.x = f->info[w].x;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, b->r, t->b, nil, r.min);
		fdx = Dx(editr) - 2*Border;
		if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
			doredraw = 1;
		freeimage(t->b);
		t->b = b;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, b->r, t->b, nil, r.min);
		nfc = malloc((w+1)*sizeof(Fontchar));
		if(nfc == 0){
			mesg("malloc failed");
			freeimage(b);
			return;
		}
		fc = f->info;
		for(i=0; i<=w && i<=f->n; i++)
			nfc[i] = fc[i];
		if(w+1 < i)
			memset(nfc+i, 0, ((w+1)-i)*sizeof(Fontchar));
		x = fc[f->n].x;
		for(; i<=w; i++)
			nfc[i].x = x;
		f = allocsubfont(t->name, w, f->height, f->ascent, nfc, b);
		if(f == 0)
			goto nofmem;
		t->s->bits = nil;	/* don't free it */
		freesubfont(t->s);
		f->info = nfc;
		t->s = f;
		if(doredraw)
			redraw(thing);
		else
			drawthing(t, 0);
		t->mod = 1;
		return;
	}
	if(strcmp(tag, "iwidth") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<0){
			mesg("illegal iwidth");
			return;
		}
		w -= Dx(t->b->r);
		if(w == 0)
			return;
		r = t->parent->b->r;
		r.max.x += w;
		c = t->c;
		t = t->parent;
		f = t->s;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		fc = &f->info[c];
		draw(b, Rect(b->r.min.x, b->r.min.y,
				b->r.min.x+(fc[1].x-t->b->r.min.x), b->r.min.y+Dy(t->b->r)),
				t->b, nil, t->b->r.min);
		draw(b, Rect(fc[1].x+w, b->r.min.y, w+t->b->r.max.x, b->r.min.y+Dy(t->b->r)),
			t->b, nil, Pt(fc[1].x, t->b->r.min.y));
		fdx = Dx(editr) - 2*Border;
		doredraw = 0;
		if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
			doredraw = 1;
		freeimage(t->b);
		t->b = b;
		b = allocimage(display, r, t->b->chan, 0, 0);
		if(b == 0)
			goto nobmem;
		draw(b, b->r, t->b, nil, t->b->r.min);
		fc = &f->info[c+1];
		for(i=c+1; i<=f->n; i++, fc++)
			fc->x += w;
		f = allocsubfont(t->name, f->n, f->height, f->ascent,
			f->info, b);
		if(f == 0)
			goto nofmem;
		/* t->s and f share info; free carefully */
		fc = f->info;
		t->s->bits = nil;
		t->s->info = 0;
		freesubfont(t->s);
		f->info = fc;
		t->s = f;
		if(doredraw)
			redraw(t);
		else
			drawthing(t, 0);
		/* redraw all affected chars */
		for(nt=thing; nt; nt=nt->next){
			if(nt->parent!=t || nt->c<c)
				continue;
			fc = &f->info[nt->c];
			r.min.x = fc[0].x;
			r.min.y = nt->b->r.min.y;
			r.max.x = fc[1].x;
			r.max.y = nt->b->r.max.y;
			b = allocimage(display, r, nt->b->chan, 0, 0);
			if(b == 0)
				goto nobmem;
			draw(b, r, t->b, nil, r.min);
			doredraw = 0;
			if(Dx(nt->b->r)/fdx != Dx(b->r)/fdx)
				doredraw = 1;
			freeimage(nt->b);
			nt->b = b;
			if(c != nt->c)
				text(nt);
			else{
				if(doredraw)
					redraw(nt);
				else
					drawthing(nt, 0);
			}
		}
		t->mod = 1;
		return;
	}
	mesg("cannot edit %s in file %s", tag, t->name);
}

void
cntledit(char *tag)
{
	char buf[256];
	ulong l;

	buttons(Up);
	if(type(buf, tag) == 0)
		return;
	if(strcmp(tag, "mag") == 0){
		if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<=0 || l>Maxmag){
			mesg("illegal magnification");
			return;
		}
		mag = l;
		cntl();
		return;
	}
	if(strcmp(tag, "but1")==0
	|| strcmp(tag, "but2")==0){
		if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<0 || l>255){
			mesg("illegal value");
			return;
		}
		if(strcmp(tag, "but1") == 0)
			but1val = l;
		else if(strcmp(tag, "but2") == 0)
			but2val = l;
		cntl();
		return;
	}
	if(strcmp(tag, "invert-on-copy")==0){
		if(buf[0]=='y' || buf[0]=='1')
			invert = 1;
		else if(buf[0]=='n' || buf[0]=='0')
			invert = 0;
		else{
			mesg("illegal value");
			return;
		}
		cntl();
		return;
	}
	mesg("cannot edit %s", tag);
}

void
buttons(int ud)
{
	while((mouse.buttons==0) != ud)
		mouse = emouse();
}

Point
screenpt(Thing *t, Point realp)
{
	int fdx, n;
	Point p;

	fdx = Dx(editr)-2*Border;
	if(t->mag > 1)
		fdx -= fdx%t->mag;
	p = mulpt(subpt(realp, t->b->r.min), t->mag);
	if(fdx < Dx(t->b->r)*t->mag){
		n = p.x/fdx;
		p.y += n * (Dy(t->b->r)*t->mag+Border);
		p.x -= n * fdx;
	}
	p = addpt(p, t->r.min);
	return p;
}

Point
realpt(Thing *t, Point screenp)
{
	int fdx, n, dy;
	Point p;

	fdx = (Dx(editr)-2*Border);
	if(t->mag > 1)
		fdx -= fdx%t->mag;
	p.y = screenp.y-t->r.min.y;
	p.x = 0;
	if(fdx < Dx(t->b->r)*t->mag){
		dy = Dy(t->b->r)*t->mag+Border;
		n = (p.y/dy);
		p.x = n * fdx;
		p.y -= n * dy;
	}
	p.x += screenp.x-t->r.min.x;
	p = addpt(divpt(p, t->mag), t->b->r.min);
	return p;
}

int
sweep(int but, Rectangle *r)
{
	Thing *t;
	Point p, q, lastq;

	esetcursor(&sweep0);
	buttons(Down);
	if(mouse.buttons != (1<<(but-1))){
		buttons(Up);
		esetcursor(0);
		return 0;
	}
	p = mouse.xy;
	for(t=thing; t; t=t->next)
		if(ptinrect(p, t->r))
			break;
	if(t)
		p = screenpt(t, realpt(t, p));
	r->min = p;
	r->max = p;
	esetcursor(&box);
	lastq = ZP;
	while(mouse.buttons == (1<<(but-1))){
		edrawgetrect(insetrect(*r, -Borderwidth), 1);
		mouse = emouse();
		edrawgetrect(insetrect(*r, -Borderwidth), 0);
		q = mouse.xy;
		if(t)
			q = screenpt(t, realpt(t, q));
		if(eqpt(q, lastq))
			continue;
		*r = canonrect(Rpt(p, q));
		lastq = q;
	}
	esetcursor(0);
	if(mouse.buttons){
		buttons(Up);
		return 0;
	}
	return 1;
}

void
openedit(Thing *t, Point pt, int c)
{
	int x, y;
	Point p;
	Rectangle r;
	Rectangle br;
	Fontchar *fc;
	Thing *nt;

	if(t->b->depth > 8){
		mesg("image has depth %d; can't handle >8", t->b->depth);
		return;
	}
	br = t->b->r;
	if(t->s == 0){
		c = -1; 
		/* if big enough to bother, sweep box */
		if(Dx(br)<=16 && Dy(br)<=16)
			r = br;
		else{
			if(!sweep(1, &r))
				return;
			r = rectaddpt(r, subpt(br.min, t->r.min));
			if(!rectclip(&r, br))
				return;
			if(Dx(br) <= 8){
				r.min.x = br.min.x;
				r.max.x = br.max.x;
			}else if(Dx(r) < 4){
	    toosmall:
				mesg("rectangle too small");
				return;
			}
			if(Dy(br) <= 8){
				r.min.y = br.min.y;
				r.max.y = br.max.y;
			}else if(Dy(r) < 4)
				goto toosmall;
		}
	}else if(c >= 0){
		fc = &t->s->info[c];
		r.min.x = fc[0].x;
		r.min.y = br.min.y;
		r.max.x = fc[1].x;
		r.max.y = br.min.y + Dy(br);
	}else{
		/* just point at character */
		fc = t->s->info;
		p = addpt(pt, subpt(br.min, t->r.min));
		x = br.min.x;
		y = br.min.y;
		for(c=0; c<t->s->n; c++,fc++){
	    again:
			r.min.x = x;
			r.min.y = y;
			r.max.x = x + fc[1].x - fc[0].x;
			r.max.y = y + Dy(br);
			if(ptinrect(p, r))
				goto found;
			if(r.max.x >= br.min.x+Dx(t->r)){
				x -= Dx(t->r);
				y += t->s->height;
				if(fc[1].x > fc[0].x)
					goto again;
			}
			x += fc[1].x - fc[0].x;
		}
		return;
	   found:
		r = br;
		r.min.x = fc[0].x;
		r.max.x = fc[1].x;
	}
	nt = malloc(sizeof(Thing));
	if(nt == 0){
   nomem:
		mesg("can't allocate: %r");
		return;
	}
	memset(nt, 0, sizeof(Thing));
	nt->c = c;
	nt->b = allocimage(display, r, t->b->chan, 0, DNofill);
	if(nt->b == 0){
		free(nt);
		goto nomem;
	}
	draw(nt->b, r, t->b, nil, r.min);
	nt->name = strdup(t->name);
	if(nt->name == 0){
		freeimage(nt->b);
		free(nt);
		goto nomem;
	}
	nt->parent = t;
	nt->mag = mag;
	drawthing(nt, 1);
}

void
ckinfo(Thing *t, Rectangle mod)
{
	int i, j, k, top, bot, n, zero;
	Fontchar *fc;
	Rectangle r;
	Image *b;
	Thing *nt;

	if(t->parent)
		t = t->parent;
	if(t->s==0 || Dy(t->b->r)==0)
		return;
	b = 0;
	/* check bounding boxes */
	fc = &t->s->info[0];
	r.min.y = t->b->r.min.y;
	r.max.y = t->b->r.max.y;
	for(i=0; i<t->s->n; i++, fc++){
		r.min.x = fc[0].x;
		r.max.x = fc[1].x;
		if(!rectXrect(mod, r))
			continue;
		if(b==0 || Dx(b->r)<Dx(r)){
			if(b)
				freeimage(b);
			b = allocimage(display, rectsubpt(r, r.min), t->b->chan, 0, 0);
			if(b == 0){
				mesg("can't alloc image");
				break;
			}
		}
		draw(b, b->r, display->white, nil, ZP);
		draw(b, b->r, t->b, nil, r.min);
		top = 100000;
		bot = 0;
		n = 2+((Dx(r)/8)*t->b->depth);
		for(j=0; j<b->r.max.y; j++){
			memset(data, 0, n);
			unloadimage(b, Rect(b->r.min.x, j, b->r.max.x, j+1), data, sizeof data);
			zero = 1;
			for(k=0; k<n; k++)
				if(data[k]){
					zero = 0;
					break;
				}
			if(!zero){
				if(top > j)
					top = j;
				bot = j+1;
			}
		}
		if(top > j)
			top = 0;
		if(top!=fc->top || bot!=fc->bottom){
			fc->top = top;
			fc->bottom = bot;
			for(nt=thing; nt; nt=nt->next)
				if(nt->parent==t && nt->c==i)
					text(nt);
		}
	}
	if(b)
		freeimage(b);
}

void
twidpix(Thing *t, Point p, int set)
{
	Image *b, *v;
	int c;

	b = t->b;
	if(!ptinrect(p, b->r))
		return;
	if(set)
		c = but1val;
	else
		c = but2val;
	if(b->chan == GREY8)
		v = greyvalues[c];
	else
		v = values[c];
	draw(b, Rect(p.x, p.y, p.x+1, p.y+1), v, nil, ZP);
	p = screenpt(t, p);
	draw(screen, Rect(p.x, p.y, p.x+t->mag, p.y+t->mag), v, nil, ZP);
}

void
twiddle(Thing *t)
{
	int set;
	Point p, lastp;
	Image *b;
	Thing *nt;
	Rectangle mod;

	if(mouse.buttons!=1 && mouse.buttons!=2){
		buttons(Up);
		return;
	}
	set = mouse.buttons==1;
	b = t->b;
	lastp = addpt(b->r.min, Pt(-1, -1));
	mod = Rpt(addpt(b->r.max, Pt(1, 1)), lastp);
	while(mouse.buttons){
		p = realpt(t, mouse.xy);
		if(!eqpt(p, lastp)){
			lastp = p;
			if(ptinrect(p, b->r)){
				for(nt=thing; nt; nt=nt->next)
					if(nt->parent==t->parent || nt==t->parent)
						twidpix(nt, p, set);
				if(t->parent)
					t->parent->mod = 1;
				else
					t->mod = 1;
				if(p.x < mod.min.x)
					mod.min.x = p.x;
				if(p.y < mod.min.y)
					mod.min.y = p.y;
				if(p.x >= mod.max.x)
					mod.max.x = p.x+1;
				if(p.y >= mod.max.y)
					mod.max.y = p.y+1;
			}
		}
		mouse = emouse();
	}
	ckinfo(t, mod);
}

void
xselect(void)
{
	Thing *t;
	char line[128], buf[128];
	Point p;

	if(ptinrect(mouse.xy, cntlr)){
		scntl(line);
		if(atline(cntlr.min.x, mouse.xy, line, buf)){
			if(mouse.buttons == 1)
				cntledit(buf);
			else
				buttons(Up);
			return;
		}
		return;
	}
	for(t=thing; t; t=t->next){
		if(attext(t, mouse.xy, buf)){
			if(mouse.buttons == 1)
				textedit(t, buf);
			else
				buttons(Up);
			return;
		}
		if(ptinrect(mouse.xy, t->r)){
			if(t->parent == 0){
				if(mouse.buttons == 1){
					p = mouse.xy;
					buttons(Up);
					openedit(t, p, -1);
				}else
					buttons(Up);
				return;
			}
			twiddle(t);
			return;
		}
	}
}

void
twrite(Thing *t)
{
	int i, j, x, y, fd, ws, ld;
	Biobuf buf;
	Rectangle r;

	if(t->parent)
		t = t->parent;
	esetcursor(&busy);
	fd = create(t->name, OWRITE, 0666);
	if(fd < 0){
		mesg("can't write %s: %r", t->name);
		return;
	}
	if(t->face && t->b->depth <= 4){
		r = t->b->r;
		ld = xlog2(t->b->depth);
		/* This heuristic reflects peculiarly different formats */
		ws = 4;
		if(t->face == 2)	/* cursor file */
			ws = 1;
		else if(Dx(r)<32 || ld==0)
			ws = 2;
		Binit(&buf, fd, OWRITE);
		if(t->face == CURSOR)
			Bprint(&buf, "{");
		for(y=r.min.y; y<r.max.y; y++){
			unloadimage(t->b, Rect(r.min.x, y, r.max.x, y+1), data, sizeof data);
			j = 0;
			for(x=r.min.x; x<r.max.x; j+=ws,x+=ws*8>>ld){
				Bprint(&buf, "0x");
				for(i=0; i<ws; i++)
					Bprint(&buf, "%.2x", data[i+j]);
				Bprint(&buf, ", ");
			}
			if(t->face == CURSOR){
				switch(y){
				case 3: case 7: case 11: case 19: case 23: case 27:
					Bprint(&buf, "\n ");
					break;
				case 15:
					Bprint(&buf, "},\n{");
					break;
				case 31:
					Bprint(&buf, "}\n");
					break;
				}
			}else
				Bprint(&buf, "\n");
		}
		Bterm(&buf);
	}else
		if(writeimage(fd, t->b, 0)<0 || (t->s && writesubfont(fd, t->s)<0)){
			close(fd);
			mesg("can't write %s: %r", t->name);
		}
	t->mod = 0;
	close(fd);
	mesg("wrote %s", t->name);
}

void
tpixels(void)
{
	Thing *t;
	Point p, lastp;

	esetcursor(&pixel);
	for(;;){
		buttons(Down);
		if(mouse.buttons != 4)
			break;
		for(t=thing; t; t=t->next){
			lastp = Pt(-1, -1);
			if(ptinrect(mouse.xy, t->r)){
				while(ptinrect(mouse.xy, t->r) && mouse.buttons==4){
					p = realpt(t, mouse.xy);
					if(!eqpt(p, lastp)){
						if(p.y != lastp.y)
							unloadimage(t->b, Rect(t->b->r.min.x, p.y, t->b->r.max.x, p.y+1), data, sizeof data);
						mesg("[%d,%d] = %d=0x%ux", p.x, p.y, value(t->b, p.x), value(t->b, p.x));
						lastp = p;
					}
					mouse = emouse();
				}
				goto Continue;
			}
		}
		mouse = emouse();
    Continue:;
	}
	buttons(Up);
	esetcursor(0);
}

void
tclose1(Thing *t)
{
	Thing *nt;

	if(t == thing)
		thing = t->next;
	else{
		for(nt=thing; nt->next!=t; nt=nt->next)
			;
		nt->next = t->next;
	}
	do
		for(nt=thing; nt; nt=nt->next)
			if(nt->parent == t){
				tclose1(nt);
				break;
			}
	while(nt);
	if(t->s)
		freesubfont(t->s);
	else
		freeimage(t->b);
	free(t->name);
	free(t);
}

void
tclose(Thing *t)
{
	Thing *ct;

	if(t->mod){
		mesg("%s modified", t->name);
		t->mod = 0;
		return;
	}
	/* fiddle to save redrawing unmoved things */
	if(t == thing)
		ct = 0;
	else
		for(ct=thing; ct; ct=ct->next)
			if(ct->next==t || ct->next->parent==t)
				break;
	tclose1(t);
	if(ct)
		ct = ct->next;
	else
		ct = thing;
	redraw(ct);
}

void
tread(Thing *t)
{
	Thing *nt, *new;
	Fontchar *i;
	Rectangle r;
	int nclosed;

	if(t->parent)
		t = t->parent;
	new = tget(t->name);
	if(new == 0)
		return;
	nclosed = 0;
    again:
	for(nt=thing; nt; nt=nt->next)
		if(nt->parent == t){
			if(!rectinrect(nt->b->r, new->b->r)
			|| new->b->depth!=nt->b->depth){
    closeit:
				nclosed++;
				nt->parent = 0;
				tclose1(nt);
				goto again;
			}
			if((t->s==0) != (new->s==0))
				goto closeit;
			if((t->face==0) != (new->face==0))
				goto closeit;
			if(t->s){	/* check same char */
				if(nt->c >= new->s->n)
					goto closeit;
				i = &new->s->info[nt->c];
				r.min.x = i[0].x;
				r.max.x = i[1].x;
				r.min.y = new->b->r.min.y;
				r.max.y = new->b->r.max.y;
				if(!eqrect(r, nt->b->r))
					goto closeit;
			}
			nt->parent = new;
			draw(nt->b, nt->b->r, new->b, nil, nt->b->r.min);
		}
	new->next = t->next;
	if(t == thing)
		thing = new;
	else{
		for(nt=thing; nt->next!=t; nt=nt->next)
			;
		nt->next = new;
	}
	if(t->s)
		freesubfont(t->s);
	else
		freeimage(t->b);
	free(t->name);
	free(t);
	for(nt=thing; nt; nt=nt->next)
		if(nt==new || nt->parent==new)
			if(nclosed == 0)
				drawthing(nt, 0);	/* can draw in place */
			else{
				redraw(nt);	/* must redraw all below */
				break;
			}
}

void
tchar(Thing *t)
{
	char buf[256], *p;
	Rune r;
	ulong c, d;

	if(t->s == 0){
		t = t->parent;
		if(t==0 || t->s==0){
			mesg("not a subfont");
			return;
		}
	}
	if(type(buf, "char (hex or character or hex-hex)") == 0)
		return;
	if(utflen(buf) == 1){
		chartorune(&r, buf);
		c = r;
		d = r;
	}else{
		if(!strchr(hex, buf[0])){
			mesg("illegal hex character");
			return;
		}
		c = strtoul(buf, 0, 16);
		d = c;
		p = utfrune(buf, '-');
		if(p){
			d = strtoul(p+1, 0, 16);
			if(d < c){
				mesg("invalid range");
				return;
			}
		}
	}
	c -= t->off;
	d -= t->off;
	while(c <= d){
		if(c<0 || c>=t->s->n){
			mesg("0x%lux not in font %s", c+t->off, t->name);
			return;
		}
		openedit(t, Pt(0, 0), c);
		c++;
	}
}

void
apply(void (*f)(Thing*))
{
	Thing *t;

	esetcursor(&sight);
	buttons(Down);
	if(mouse.buttons == 4)
		for(t=thing; t; t=t->next)
			if(ptinrect(mouse.xy, t->er)){
				buttons(Up);
				f(t);
				break;
			}
	buttons(Up);
	esetcursor(0);
}

int
complement(Image *t)
{
	int i, n;
	uchar *buf;

	n = Dy(t->r)*bytesperline(t->r, t->depth);
	buf = malloc(n);
	if(buf == 0)
		return 0;
	unloadimage(t, t->r, buf, n);
	for(i=0; i<n; i++)
		buf[i] = ~buf[i];
	loadimage(t, t->r, buf, n);
	free(buf);
	return 1;
}

void
copy(void)
{
	Thing *st, *dt, *nt;
	Rectangle sr, dr, fr;
	Image *tmp;
	Point p1, p2;
	int but, up;

	if(!sweep(3, &sr))
		return;
	for(st=thing; st; st=st->next)
		if(rectXrect(sr, st->r))
			break;
	if(st == 0)
		return;
	/* click gives full rectangle */
	if(Dx(sr)<4 && Dy(sr)<4)
		sr = st->r;
	rectclip(&sr, st->r);
	p1 = realpt(st, sr.min);
	p2 = realpt(st, Pt(sr.min.x, sr.max.y));
	up = 0;
	if(p1.x != p2.x){	/* swept across a fold */
   onafold:
		mesg("sweep spans a fold");
		goto Return;
	}
	p2 = realpt(st, sr.max);
	sr.min = p1;
	sr.max = p2;
	fr.min = screenpt(st, sr.min);
	fr.max = screenpt(st, sr.max);
	p1 = subpt(p2, p1);	/* diagonal */
	if(p1.x==0 || p1.y==0)
		return;
	border(screen, fr, -1, values[Blue], ZP);
	esetcursor(&box);
	for(; mouse.buttons==0; mouse=emouse()){
		for(dt=thing; dt; dt=dt->next)
			if(ptinrect(mouse.xy, dt->er))
				break;
		if(up)
			edrawgetrect(insetrect(dr, -Borderwidth), 0);
		up = 0;
		if(dt == 0)
			continue;
		dr.max = screenpt(dt, realpt(dt, mouse.xy));
		dr.min = subpt(dr.max, mulpt(p1, dt->mag));
		if(!rectXrect(dr, dt->r))
			continue;
		edrawgetrect(insetrect(dr, -Borderwidth), 1);
		up = 1;
	}
	/* if up==1, we had a hit */
	esetcursor(0);
	if(up)
		edrawgetrect(insetrect(dr, -Borderwidth), 0);
	but = mouse.buttons;
	buttons(Up);
	if(!up || but!=4)
		goto Return;
	dt = 0;
	for(nt=thing; nt; nt=nt->next)
		if(rectXrect(dr, nt->r)){
			if(dt){
				mesg("ambiguous sweep");
				return;
			}
			dt = nt;
		}
	if(dt == 0)
		goto Return;
	p1 = realpt(dt, dr.min);
	p2 = realpt(dt, Pt(dr.min.x, dr.max.y));
	if(p1.x != p2.x)
		goto onafold;
	p2 = realpt(dt, dr.max);
	dr.min = p1;
	dr.max = p2;

	if(invert){
		tmp = allocimage(display, dr, dt->b->chan, 0, 255);
		if(tmp == 0){
    nomem:
			mesg("can't allocate temporary");
			goto Return;
		}
		draw(tmp, dr, st->b, nil, sr.min);
		if(!complement(tmp))
			goto nomem;
		draw(dt->b, dr, tmp, nil, dr.min);
		freeimage(tmp);
	}else
		draw(dt->b, dr, st->b, nil, sr.min);
	if(dt->parent){
		draw(dt->parent->b, dr, dt->b, nil, dr.min);
		dt = dt->parent;
	}
	drawthing(dt, 0);
	for(nt=thing; nt; nt=nt->next)
		if(nt->parent==dt && rectXrect(dr, nt->b->r)){
			draw(nt->b, dr, dt->b, nil, dr.min);
			drawthing(nt, 0);
		}
	ckinfo(dt, dr);
	dt->mod = 1;

Return:
	/* clear blue box */
	drawthing(st, 0);
}

void
menu(void)
{
	Thing *t;
	char *mod;
	int sel;
	char buf[256];

	sel = emenuhit(3, &mouse, &menu3);
	switch(sel){
	case Mopen:
		if(type(buf, "file")){
			t = tget(buf);
			if(t)
				drawthing(t, 1);
		}
		break;
	case Mwrite:
		apply(twrite);
		break;
	case Mread:
		apply(tread);
		break;
	case Mchar:
		apply(tchar);
		break;
	case Mcopy:
		copy();
		break;
	case Mpixels:
		tpixels();
		break;
	case Mclose:
		apply(tclose);
		break;
	case Mexit:
		mod = 0;
		for(t=thing; t; t=t->next)
			if(t->mod){
				mod = t->name;
				t->mod = 0;
			}
		if(mod){
			mesg("%s modified", mod);
			break;
		}
		esetcursor(&skull);
		buttons(Down);
		if(mouse.buttons == 4){
			buttons(Up);
			exits(0);
		}
		buttons(Up);
		esetcursor(0);
		break;
	}
}
