#include "a.h"
/*
 * 8. Number Registers
 * (Reg register implementation is also here.)
 */

/*
 *	\nx		N
 *	\n(xx	N
 *	\n+x		N+=M
 *	\n-x		N-=M
 *
 *	.nr R ±N M
 *	.af R c
 *
 *	formats
 *		1	0, 1, 2, 3, ...
 *		001	001, 002, 003, ...
 *		i	0, i, ii, iii, iv, v, ...
 *		I	0, I, II, III, IV, V, ...
 *		a	0, a, b, ..., aa, ab, ..., zz, aaa, ...
 *		A	0, A, B, ..., AA, AB, ..., ZZ, AAA, ...
 *
 *	\gx \g(xx return format of number register
 *
 *	.rr R
 */

typedef struct Reg Reg;
struct Reg
{
	Reg *next;
	Rune *name;
	Rune *val;
	Rune *fmt;
	int inc;
};

Reg *dslist;
Reg *nrlist;

/*
 * Define strings and numbers.
 */
void
dsnr(Rune *name, Rune *val, Reg **l)
{
	Reg *s;

	for(s = *l; s != nil; s = *l){
		if(runestrcmp(s->name, name) == 0)
			break;
		l = &s->next;
	}
	if(val == nil){
		if(s){
			*l = s->next;
			free(s->val);
			free(s->fmt);
			free(s);
		}
		return;
	}
	if(s == nil){
		s = emalloc(sizeof(Reg));
		*l = s;
		s->name = erunestrdup(name);
	}else
		free(s->val);
	s->val = erunestrdup(val);
}

Rune*
getdsnr(Rune *name, Reg *list)
{
	Reg *s;
	
	for(s=list; s; s=s->next)
		if(runestrcmp(name, s->name) == 0)
			return s->val;
	return nil;
}

void
ds(Rune *name, Rune *val)
{
	dsnr(name, val, &dslist);
}

void
as(Rune *name, Rune *val)
{
	Rune *p, *q;
	
	p = getds(name);
	if(p == nil)
		p = L("");
	q = runemalloc(runestrlen(p)+runestrlen(val)+1);
	runestrcpy(q, p);
	runestrcat(q, val);
	ds(name, q);
	free(q);
}

Rune*
getds(Rune *name)
{
	return getdsnr(name, dslist);
}

void
printds(int t)
{
	int n, total;
	Reg *s;
	
	total = 0;
	for(s=dslist; s; s=s->next){
		if(s->val)
			n = runestrlen(s->val);
		else
			n = 0;
		total += n;
		if(!t)
			fprint(2, "%S\t%d\n", s->name, n);
	}
	fprint(2, "total\t%d\n", total);
}

void
nr(Rune *name, int val)
{
	Rune buf[20];
	
	runesnprint(buf, nelem(buf), "%d", val);
	_nr(name, buf);
}

void
af(Rune *name, Rune *fmt)
{
	Reg *s;

	if(_getnr(name) == nil)
		_nr(name, L("0"));
	for(s=nrlist; s; s=s->next)
		if(runestrcmp(s->name, name) == 0)
			s->fmt = erunestrdup(fmt);
}

Rune*
getaf(Rune *name)
{
	Reg *s;
	
	for(s=nrlist; s; s=s->next)
		if(runestrcmp(s->name, name) == 0)
			return s->fmt;
	return nil;
}

void
printnr(void)
{
	Reg *r;
	
	for(r=nrlist; r; r=r->next)
		fprint(2, "%S %S %d\n", r->name, r->val, r->inc);
}

/*
 * Some internal number registers are actually strings,
 * so provide _ versions to get at them.
 */
void
_nr(Rune *name, Rune *val)
{
	dsnr(name, val, &nrlist);
}

Rune*
_getnr(Rune *name)
{
	return getdsnr(name, nrlist);
}

int
getnr(Rune *name)
{
	Rune *p;

	p = _getnr(name);
	if(p == nil)
		return 0;
	return eval(p);
}

/* new register */
void
r_nr(int argc, Rune **argv)
{
	Reg *s;

	if(argc < 2)
		return;
	if(argc < 3)
		nr(argv[1], 0);
	else{
		if(argv[2][0] == '+')
			nr(argv[1], getnr(argv[1])+eval(argv[2]+1));
		else if(argv[2][0] == '-')
			nr(argv[1], getnr(argv[1])-eval(argv[2]+1));
		else
			nr(argv[1], eval(argv[2]));
	}
	if(argc > 3){
		for(s=nrlist; s; s=s->next)
			if(runestrcmp(s->name, argv[1]) == 0)
				s->inc = eval(argv[3]);
	}
}

/* assign format */
void
r_af(int argc, Rune **argv)
{
	USED(argc);
	
	af(argv[1], argv[2]);
}

/* remove register */
void
r_rr(int argc, Rune **argv)
{
	int i;
	
	for(i=1; i<argc; i++)
		_nr(argv[i], nil);
}

/* fmt integer in base 26 */
void
alpha(Rune *buf, int n, int a)
{
	int i, v;
	
	i = 1;
	for(v=n; v>0; v/=26)
		i++;
	if(i == 0)
		i = 1;
	buf[i] = 0;
	while(i > 0){
		buf[--i] = a+n%26;
		n /= 26;
	}
}

struct romanv {
	char *s;
	int v;
} romanv[] =
{
	"m",	1000,
	"cm", 900,
	"d", 500,
	"cd", 400,
	"c", 100,
	"xc", 90,
	"l", 50,
	"xl", 40,
	"x", 10,
	"ix", 9,
	"v", 5,
	"iv", 4,
	"i", 1
};

/* fmt integer in roman numerals! */
void
roman(Rune *buf, int n, int upper)
{
	Rune *p;
	char *q;
	struct romanv *r;
	
	if(upper)
		upper = 'A' - 'a';
	if(n >= 5000 || n <= 0){
		runestrcpy(buf, L("-"));
		return;
	}
	p = buf;
	r = romanv;
	while(n > 0){
		while(n >= r->v){
			for(q=r->s; *q; q++)
				*p++ = *q + upper;
			n -= r->v;
		}
		r++;
	}
	*p = 0;
}

Rune*
getname(void)
{
	int i, c, cc;
	static Rune buf[100];
	
	/* XXX add [name] syntax as in groff */
	c = getnext();
	if(c < 0)
		return L("");
	if(c == '\n'){
		warn("newline in name\n");
		ungetnext(c);
		return L("");
	}
	if(c == '['){
		for(i=0; i<nelem(buf)-1; i++){
			if((c = getrune()) < 0)
				return L("");
			if(c == ']'){
				buf[i] = 0;
				return buf;
			}
			buf[i] = c;
		}
		return L("");
	}
	if(c != '('){
		buf[0] = c;
		buf[1] = 0;
		return buf;
	}
	c = getnext();
	cc = getnext();
	if(c < 0 || cc < 0)
		return L("");
	if(c == '\n' | cc == '\n'){
		warn("newline in \\n");
		ungetnext(cc);
		if(c == '\n')
			ungetnext(c);
	}
	buf[0] = c;
	buf[1] = cc;
	buf[2] = 0;
	return buf;
}

/* \n - return number register */
int
e_n(void)
{
	int inc, v, l;
	Rune *name, *fmt, buf[100];
	Reg *s;
	
	inc = getnext();
	if(inc < 0)
		return -1;
	if(inc != '+' && inc != '-'){
		ungetnext(inc);
		inc = 0;
	}
	name = getname();
	if(_getnr(name) == nil)
		_nr(name, L("0"));
	for(s=nrlist; s; s=s->next){
		if(runestrcmp(s->name, name) == 0){
			if(s->fmt == nil && !inc && s->val[0]){
				/* might be a string! */
				pushinputstring(s->val);
				return 0;
			}
			v = eval(s->val);
			if(inc){
				if(inc == '+')
					v += s->inc;
				else
					v -= s->inc;
				runesnprint(buf, nelem(buf), "%d", v);
				free(s->val);
				s->val = erunestrdup(buf);
			}
			fmt = s->fmt;
			if(fmt == nil)
				fmt = L("1");
			switch(fmt[0]){
			case 'i':
			case 'I':
				roman(buf, v, fmt[0]=='I');
				break;
			case 'a':
			case 'A':
				alpha(buf, v, fmt[0]);
				break;
			default:
				l = runestrlen(fmt);
				if(l == 0)
					l = 1;
				runesnprint(buf, sizeof buf, "%0*d", l, v);
				break;
			}
			pushinputstring(buf);
			return 0;
		}
	}
	pushinputstring(L(""));
	return 0;
}

/* \g - number register format */
int
e_g(void)
{
	Rune *p;

	p = getaf(getname());
	if(p == nil)
		p = L("1");
	pushinputstring(p);
	return 0;
}

void
r_pnr(int argc, Rune **argv)
{
	USED(argc);
	USED(argv);
	printnr();
}

void
t8init(void)
{
	addreq(L("nr"), r_nr, -1);
	addreq(L("af"), r_af, 2);
	addreq(L("rr"), r_rr, -1);
	addreq(L("pnr"), r_pnr, 0);
	
	addesc('n', e_n, CopyMode|ArgMode|HtmlMode);
	addesc('g', e_g, 0);
}

