#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);
	}
//assert(w->body.w == w);
	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);
//assert(w->body.w == w);
	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;
//assert(w->body.w == w);
	if(clone){
		w->dirty = clone->dirty;
		w->autoindent = clone->autoindent;
		textsetselect(&w->body, clone->body.q0, clone->body.q1);
		winsettag(w);
	}
}

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

/* TAG policy here */

	if(!w->tagexpand)
		return 1;
	w->tag.fr.noredraw = 1;
	textresize(&w->tag, r, TRUE);
	w->tag.fr.noredraw = 0;
	
	/* 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;
	bufread(&w->tag.file->b, w->tag.file->b.nc-1, &rune, 1);
	if(rune == '\n')
		n++;
	return n;
}

int
winresize(Window *w, Rectangle r, int safe, int keepextra)
{
	int y, mouseintag;
	Image *b;
	Point p;
	Rectangle br, r1;

if(0) fprint(2, "winresize %d %R safe=%d keep=%d h=%d\n", w->id, r, safe, keepextra, font->height);
	w->tagtop = r;
	w->tagtop.max.y = r.min.y+font->height;

/* 
 * TAG If necessary, recompute the number of lines that should
 * be in the tag.
 */
	r1 = r;
	r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height);
	y = r1.max.y;
	mouseintag = ptinrect(mouse->xy, w->tag.all);
	if(1 || !safe || !w->tagsafe || !eqrect(w->tag.all, r1)){

		w->taglines = wintaglines(w, r);
		w->tagsafe = TRUE;
	}
/* END TAG */

	r1 = r;
	r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height);
	y = r1.max.y;
	if(1 || !safe || !eqrect(w->tag.all, r1)){
if(0) fprint(2, "resize tag %R => %R", w->tag.all, r1);
		textresize(&w->tag, r1, TRUE);
if(0) fprint(2, "=> %R (%R)\n", w->tag.all, w->tag.fr.r);
		y = w->tag.fr.r.max.y;
		b = button;
		if(w->body.file->mod && !w->isdir && !w->isscratch)
			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);
/* TAG */
		if(mouseintag && !ptinrect(mouse->xy, w->tag.all)){
			p = mouse->xy;
			p.y = w->tag.all.max.y-3;
			moveto(mousectl, p);
		}
/* END TAG */
	}

	
	r1 = r;
	r1.min.y = y;
	if(1 || !safe || !eqrect(w->body.all, r1)){
		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;
		}
if(0) fprint(2, "resize body %R => %R", w->body.all, r1);
		w->r = r;
		w->r.max.y = textresize(&w->body, r1, keepextra);
if(0) fprint(2, " => %R (%R; %R)\n", w->body.all, w->body.fr.r, w->r);
		textscrdraw(&w->body);
	}
	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 bar, dirty, i, j, k, n, ntagname;
	Rune *new, *old, *r, *tagname;
	Image *b;
	uint q0, q1;
	Rectangle br;
	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;
	
	/* make sure the file name is set correctly in the tag */
	ntagname = w->body.file->nname;
	tagname = runemalloc(ntagname);
	runemove(tagname, w->body.file->name, ntagname);
	abbrevenv(&tagname, (uint*)&ntagname);

	/*
	 * XXX Why is this here instead of letting the code
	 * down below do the work?
	 */
	if(runeeq(old, i, tagname, ntagname) == FALSE){
		q0 = w->tag.q0;
		q1 = w->tag.q1;
		textdelete(&w->tag, 0, i, TRUE);
		textinsert(&w->tag, 0, tagname, ntagname, 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';
		if(q0 >= i){
			/*
			 * XXX common case - typing at end of name
			 */
			w->tag.q0 = q0+ntagname-i;
			w->tag.q1 = q1+ntagname-i;
		}
	}
	
	/* compute the text for the whole tag, replacing current only if it differs */
	new = runemalloc(ntagname+100);
	i = 0;
	runemove(new+i, tagname, ntagname);
	i += ntagname;
	runemove(new+i, Ldelsnarf, 10);
	i += 10;
	if(w->filemenu){
		if(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;
	if(runestrlen(new) != i)
		fprint(2, "s '%S' len not %d\n", new, i);
	assert(i==runestrlen(new));
	
	/* replace tag if the new one is different */
	if(runeeq(new, i, old, k) == FALSE){
		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(tagname);
	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);
	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);
	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;
	expandenv(&r, (uint*)&i);
	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 = realloc(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);
	}
}

/*
 * This is here as a first stab at something. 
 * Run acme with the -'$' flag to enable it.
 * 
 * This code isn't quite right, in that it doesn't play well with 
 * the plumber and with other applications.  For example:
 *
 * If the window tag is $home/bin and you execute script, then acme runs
 * script in $home/bin, via the shell, so everything is fine.  If you do
 * execute "echo $home", it too goes to the shell so you see the value
 * of $home.  And if you right-click on script, then acme plumbs "script"
 * in the directory "/home/you/bin", so that works, but if you right-click
 * on "$home/bin/script", then what?  It's not correct to expand in acme
 * since what you're plumbing might be a price tag for all we know.  So the
 * plumber has to expand it, but in order to do that the plumber should
 * probably publish (and allow users to change) the set of variables it is
 * using in expansions.
 * 
 * Rob has suggested that a better solution is to make tag lines expand
 * automatically to fit the necessary number of lines.
 * 
 * The best solution, of course, is to use nice short path names, but this
 * is not always possible.
 */

int
expandenv(Rune **rp, uint *np)
{
	char *s, *t;
	Rune *p, *r, *q;
	uint n, pref;
	int nb, nr, slash;
	Runestr rs;

	if(!dodollarsigns)
		return FALSE;

	r = *rp;
	n = *np;
	if(n == 0 || r[0] != '$')
		return FALSE;
	for(p=r+1; *p && *p != '/'; p++)
		;
	pref = p-r;
	s = runetobyte(r+1, pref-1);
	if((t = getenv(s)) == nil){
		free(s);
		return FALSE;
	}

	q = runemalloc(utflen(t)+(n-pref));
	cvttorunes(t, strlen(t), q, &nb, &nr, nil);
	assert(nr==utflen(t));
	runemove(q+nr, p, n-pref);
	free(r);
	rs = runestr(q, nr+(n-pref));
	slash = rs.nr>0 && q[rs.nr-1] == '/';
	rs = cleanrname(rs);
	if(slash){
		rs.r = runerealloc(rs.r, rs.nr+1);
		rs.r[rs.nr++] = '/';
	}
	*rp = rs.r;
	*np = rs.nr;
	free(t);
	return TRUE;
}

extern char **environ;
Rune **runeenv;

/*
 * Weird sort order -- shorter names first, 
 * prefer lowercase over uppercase ($home over $HOME),
 * then do normal string comparison.
 */
int
runeenvcmp(const void *va, const void *vb)
{
	Rune *a, *b;
	int na, nb;

	a = *(Rune**)va;
	b = *(Rune**)vb;
	na = runestrchr(a, '=') - a;
	nb = runestrchr(b, '=') -  b;
	if(na < nb)
		return -1;
	if(nb > na)
		return 1;
	if(na == 0)
		return 0;
	if(islowerrune(a[0]) && !islowerrune(b[0]))
		return -1;
	if(islowerrune(b[0]) && !islowerrune(a[0]))
		return 1;
	return runestrncmp(a, b, na);
}

void
mkruneenv(void)
{
	int i, bad, n, nr;
	char *p;
	Rune *r, *q;

	n = 0;
	for(i=0; environ[i]; i++){
		/*
		 * Ignore some pollution.
		 */
		if(environ[i][0] == '_')
			continue;
		if(strncmp(environ[i], "PWD=", 4) == 0)
			continue;
		if(strncmp(environ[i], "OLDPWD=", 7) == 0)
			continue;

		/*
		 * Must be a rooted path.
		 */
		if((p = strchr(environ[i], '=')) == nil || *(p+1) != '/')
			continue;

		/*
		 * Only use the ones that we accept in look - all isfilec
		 */
		bad = 0;
		r = bytetorune(environ[i], &nr);
		for(q=r; *q != '='; q++)
			if(!isfilec(*q)){
				free(r);
				bad = 1;
				break;
			}
		if(!bad){
			runeenv = erealloc(runeenv, (n+1)*sizeof(runeenv[0]));
			runeenv[n++] = r;
		}
	}
	runeenv = erealloc(runeenv, (n+1)*sizeof(runeenv[0]));
	runeenv[n] = nil;
	qsort(runeenv, n, sizeof(runeenv[0]), runeenvcmp);
}

int
abbrevenv(Rune **rp, uint *np)
{
	int i, len, alen;
	Rune *r, *p, *q;
	uint n;

	if(!dodollarsigns)
		return FALSE;

	r = *rp;
	n = *np;
	if(n == 0 || r[0] != '/')
		return FALSE;

	if(runeenv == nil)
		mkruneenv();

	for(i=0; runeenv[i]; i++){
		p = runestrchr(runeenv[i], '=')+1;
		len = runestrlen(p);
		if(len <= n && (r[len]==0 || r[len]=='/') && runeeq(r, len, p, len)==TRUE){
			alen = (p-1) - runeenv[i];
			q = runemalloc(1+alen+n-len);
			q[0] = '$';
			runemove(q+1, runeenv[i], alen);
			runemove(q+1+alen, r+len, n-len);
			free(r);
			*rp = q;
			*np = 1+alen+n-len;
			return TRUE;
		}
	}
	return FALSE;
}

