#include <u.h>
#include <libc.h>
#include <bio.h>
#include <draw.h>
#include <event.h>
#include "sky.h"
#include "strings.c"

enum
{
	NNGC=7840,	/* number of NGC numbers [1..NNGC] */
	NIC = 5386,	/* number of IC numbers */
	NNGCrec=NNGC+NIC,	/* number of records in the NGC catalog (including IC's, starting at NNGC */
	NMrec=122,	/* number of M records */
	NM=110,		/* number of M numbers */
	NAbell=2712,	/* number of records in the Abell catalog */
	NName=1000,	/* number of prose names; estimated maximum (read from editable text file) */
	NBayer=1517,	/* number of bayer entries */
	NSAO=258998,	/* number of SAO stars */
	MAXcon=1932,	/* maximum number of patches in a constellation */
	Ncon=88,	/* number of constellations */
	Npatch=92053,	/* highest patch number */
};

char		ngctype[NNGCrec];
Mindexrec	mindex[NMrec];
Namerec		name[NName];
Bayerec		bayer[NBayer];
long		con[MAXcon];
ushort		conindex[Ncon+1];
long		patchaddr[Npatch+1];

Record	*rec;
Record	*orec;
Record	*cur;

char	*dir;
int	saodb;
int	ngcdb;
int	abelldb;
int	ngctypedb;
int	mindexdb;
int	namedb;
int	bayerdb;
int	condb;
int	conindexdb;
int	patchdb;
char	parsed[3];
long	nrec;
long	nreca;
long	norec;
long	noreca;

Biobuf	bin;
Biobuf	bout;

void
main(int argc, char *argv[])
{
	char *line;

	dir = unsharp(DIR);
	Binit(&bin, 0, OREAD);
	Binit(&bout, 1, OWRITE);
	if(argc != 1)
		dir = argv[1];
	astro("", 1);
	while(line = Brdline(&bin, '\n')){
		line[Blinelen(&bin)-1] = 0;
		lookup(line, 1);
		Bflush(&bout);
	}
	if(display != nil){
		closedisplay(display);
		/* automatic refresh of rio window is triggered by mouse */
	//	close(open("/dev/mouse", OREAD));
	}
	return;
}

void
reset(void)
{
	nrec = 0;
	cur = rec;
}

void
grow(void)
{
	nrec++;
	if(nreca < nrec){
		nreca = nrec+50;
		rec = realloc(rec, nreca*sizeof(Record));
		if(rec == 0){
			fprint(2, "scat: realloc fails\n");
			exits("realloc");
		}
	}
	cur = rec+nrec-1;
}

void
copy(void)
{
	if(noreca < nreca){
		noreca = nreca;
		orec = realloc(orec, nreca*sizeof(Record));
		if(orec == 0){
			fprint(2, "scat: realloc fails\n");
			exits("realloc");
		}
	}
	memmove(orec, rec, nrec*sizeof(Record));
	norec = nrec;
}

int
eopen(char *s)
{
	char buf[128];
	int f;

	sprint(buf, "%s/%s.scat", dir, s);
	f = open(buf, 0);
	if(f<0){
		fprint(2, "scat: can't open %s\n", buf);
		exits("open");
	}
	return f;
}


void
Eread(int f, char *name, void *addr, long n)
{
	if(read(f, addr, n) != n){	/* BUG! */
		fprint(2, "scat: read error on %s\n", name);
		exits("read");
	}
}

char*
skipbl(char *s)
{
	while(*s!=0 && (*s==' ' || *s=='\t'))
		s++;
	return s;
}

char*
skipstr(char *s, char *t)
{
	while(*s && *s==*t)
		s++, t++;
	return skipbl(s);
}

/* produce little-endian long at address l */
long
Long(long *l)
{
	uchar *p;

	p = (uchar*)l;
	return (long)p[0]|((long)p[1]<<8)|((long)p[2]<<16)|((long)p[3]<<24);
}

/* produce little-endian long at address l */
int
Short(short *s)
{
	uchar *p;

	p = (uchar*)s;
	return p[0]|(p[1]<<8);
}

void
nameopen(void)
{
	Biobuf b;
	int i;
	char *l, *p;

	if(namedb == 0){
		namedb = eopen("name");
		Binit(&b, namedb, OREAD);
		for(i=0; i<NName; i++){
			l = Brdline(&b, '\n');
			if(l == 0)
				break;
			p = strchr(l, '\t');
			if(p == 0){
		Badformat:
				Bprint(&bout, "warning: name.scat bad format; line %d\n", i+1);
				break;
			}
			*p++ = 0;
			strcpy(name[i].name, l);
			if(strncmp(p, "ngc", 3) == 0)
				name[i].ngc = atoi(p+3);
			else if(strncmp(p, "ic", 2) == 0)
				name[i].ngc = atoi(p+2)+NNGC;
			else if(strncmp(p, "sao", 3) == 0)
				name[i].sao = atoi(p+3);
			else if(strncmp(p, "abell", 5) == 0)
				name[i].abell = atoi(p+5);
			else
				goto Badformat;
		}
		if(i == NName)
			Bprint(&bout, "warning: too many names in name.scat (max %d); extra ignored\n", NName);
		close(namedb);

		bayerdb = eopen("bayer");
		Eread(bayerdb, "bayer", bayer, sizeof bayer);
		close(bayerdb);
		for(i=0; i<NBayer; i++)
			bayer[i].sao = Long(&bayer[i].sao);
	}
}

void
saoopen(void)
{
	if(saodb == 0){
		nameopen();
		saodb = eopen("sao");
	}
}

void
ngcopen(void)
{
	if(ngcdb == 0){
		nameopen();
		ngcdb = eopen("ngc2000");
		ngctypedb = eopen("ngc2000type");
		Eread(ngctypedb, "ngctype", ngctype, sizeof ngctype);
		close(ngctypedb);
	}
}

void
abellopen(void)
{
	/* nothing extra to do with abell: it's directly indexed by number */
	if(abelldb == 0)
		abelldb = eopen("abell");
}

void
patchopen(void)
{
	Biobuf *b;
	long l, m;
	char buf[100];

	if(patchdb == 0){
		patchdb = eopen("patch");
		sprint(buf, "%s/patchindex.scat", dir);
		b = Bopen(buf, OREAD);
		if(b == 0){
			fprint(2, "can't open %s\n", buf);
			exits("open");
		}
		for(m=0,l=0; l<=Npatch; l++)
			patchaddr[l] = m += Bgetc(b)*4;
		Bterm(b);
	}
}

void
mopen(void)
{
	int i;

	if(mindexdb == 0){
		mindexdb = eopen("mindex");
		Eread(mindexdb, "mindex", mindex, sizeof mindex);
		close(mindexdb);
		for(i=0; i<NMrec; i++)
			mindex[i].ngc = Short(&mindex[i].ngc);
	}
}

void
constelopen(void)
{
	int i;

	if(condb == 0){
		condb = eopen("con");
		conindexdb = eopen("conindex");
		Eread(conindexdb, "conindex", conindex, sizeof conindex);
		close(conindexdb);
		for(i=0; i<Ncon+1; i++)
			conindex[i] = Short((short*)&conindex[i]);
	}
}

void
lowercase(char *s)
{
	for(; *s; s++)
		if('A'<=*s && *s<='Z')
			*s += 'a'-'A';
}

int
loadngc(long index)
{
	static int failed;
	long j;

	ngcopen();
	j = (index-1)*sizeof(NGCrec);
	grow();
	cur->type = NGC;
	cur->index = index;
	seek(ngcdb, j, 0);
	/* special case: NGC data may not be available */
	if(read(ngcdb, &cur->u.ngc, sizeof(NGCrec)) != sizeof(NGCrec)){
		if(!failed){
			fprint(2, "scat: NGC database not available\n");
			failed++;
		}
		cur->type = NONGC;
		cur->u.ngc.ngc = 0;
		cur->u.ngc.ra = 0;
		cur->u.ngc.dec = 0;
		cur->u.ngc.diam = 0;
		cur->u.ngc.mag = 0;
		return 0;
	}
	cur->u.ngc.ngc = Short(&cur->u.ngc.ngc);
	cur->u.ngc.ra = Long(&cur->u.ngc.ra);
	cur->u.ngc.dec = Long(&cur->u.ngc.dec);
	cur->u.ngc.diam = Long(&cur->u.ngc.diam);
	cur->u.ngc.mag = Short(&cur->u.ngc.mag);
	return 1;
}

int
loadabell(long index)
{
	long j;

	abellopen();
	j = index-1;
	grow();
	cur->type = Abell;
	cur->index = index;
	seek(abelldb, j*sizeof(Abellrec), 0);
	Eread(abelldb, "abell", &cur->u.abell, sizeof(Abellrec));
	cur->u.abell.abell = Short(&cur->u.abell.abell);
	if(cur->u.abell.abell != index){
		fprint(2, "bad format in abell catalog\n");
		exits("abell");
	}
	cur->u.abell.ra = Long(&cur->u.abell.ra);
	cur->u.abell.dec = Long(&cur->u.abell.dec);
	cur->u.abell.glat = Long(&cur->u.abell.glat);
	cur->u.abell.glong = Long(&cur->u.abell.glong);
	cur->u.abell.rad = Long(&cur->u.abell.rad);
	cur->u.abell.mag10 = Short(&cur->u.abell.mag10);
	cur->u.abell.pop = Short(&cur->u.abell.pop);
	cur->u.abell.dist = Short(&cur->u.abell.dist);
	return 1;
}

int
loadsao(int index)
{
	if(index<=0 || index>NSAO)
		return 0;
	saoopen();
	grow();
	cur->type = SAO;
	cur->index = index;
	seek(saodb, (index-1)*sizeof(SAOrec), 0);
	Eread(saodb, "sao", &cur->u.sao, sizeof(SAOrec));
	cur->u.sao.ra = Long(&cur->u.sao.ra);
	cur->u.sao.dec = Long(&cur->u.sao.dec);
	cur->u.sao.dra = Long(&cur->u.sao.dra);
	cur->u.sao.ddec = Long(&cur->u.sao.ddec);
	cur->u.sao.mag = Short(&cur->u.sao.mag);
	cur->u.sao.mpg = Short(&cur->u.sao.mpg);
	cur->u.sao.hd = Long(&cur->u.sao.hd);
	return 1;
}

int
loadplanet(int index, Record *r)
{
	if(index<0 || index>NPlanet || planet[index].name[0]=='\0')
		return 0;
	grow();
	cur->type = Planet;
	cur->index = index;
	/* check whether to take new or existing record */
	if(r == nil)
		memmove(&cur->u.planet, &planet[index], sizeof(Planetrec));
	else
		memmove(&cur->u.planet, &r->u.planet, sizeof(Planetrec));
	return 1;
}

int
loadpatch(long index)
{
	int i;

	patchopen();
	if(index<=0 || index>Npatch)
		return 0;
	grow();
	cur->type = Patch;
	cur->index = index;
	seek(patchdb, patchaddr[index-1], 0);
	cur->u.patch.nkey = (patchaddr[index]-patchaddr[index-1])/4;
	Eread(patchdb, "patch", cur->u.patch.key, cur->u.patch.nkey*4);
	for(i=0; i<cur->u.patch.nkey; i++)
		cur->u.patch.key[i] = Long(&cur->u.patch.key[i]);
	return 1;
}

int
loadtype(int t)
{
	int i;

	ngcopen();
	for(i=0; i<NNGCrec; i++)
		if(t == (ngctype[i])){
			grow();
			cur->type = NGCN;
			cur->index = i+1;
		}
	return 1;
}

void
flatten(void)
{
	int i, j, notflat;
	Record *or;
	long key;

    loop:
	copy();
	reset();
	notflat = 0;
	for(i=0,or=orec; i<norec; i++,or++){
		switch(or->type){
		default:
			fprint(2, "bad type %d in flatten\n", or->type);
			break;

		case NONGC:
			break;

		case Planet:
		case Abell:
		case NGC:
		case SAO:
			grow();
			memmove(cur, or, sizeof(Record));
			break;

		case NGCN:
			if(loadngc(or->index))
				notflat = 1;
			break;

		case NamedSAO:
			loadsao(or->index);
			notflat = 1;
			break;

		case NamedNGC:
			if(loadngc(or->index))
				notflat = 1;
			break;

		case NamedAbell:
			loadabell(or->index);
			notflat = 1;
			break;

		case PatchC:
			loadpatch(or->index);
			notflat = 1;
			break;

		case Patch:
			for(j=1; j<or->u.patch.nkey; j++){
				key = or->u.patch.key[j];
				if((key&0x3F) == SAO)
					loadsao((key>>8)&0xFFFFFF);
				else if((key&0x3F) == Abell)
					loadabell((key>>8)&0xFFFFFF);
				else
					loadngc((key>>16)&0xFFFF);
			}
			break;
		}
	}
	if(notflat)
		goto loop;
}

int
ism(int index)
{
	int i;

	for(i=0; i<NMrec; i++)
		if(mindex[i].ngc == index)
			return 1;
	return 0;
}

char*
alpha(char *s, char *t)
{
	int n;

	n = strlen(t);
	if(strncmp(s, t, n)==0 && (s[n]<'a' || 'z'<s[n]))
		return skipbl(s+n);
	return 0;
	
}

char*
text(char *s, char *t)
{
	int n;

	n = strlen(t);
	if(strncmp(s, t, n)==0 && (s[n]==0 || s[n]==' ' || s[n]=='\t'))
		return skipbl(s+n);
	return 0;
	
}

int
cull(char *s, int keep, int dobbox)
{
	int i, j, nobj, keepthis;
	Record *or;
	char *t;
	int dogrtr, doless, dom, dosao, dongc, doabell;
	int mgrtr, mless;
	char obj[100];

	memset(obj, 0, sizeof(obj));
	nobj = 0;
	dogrtr = 0;
	doless = 0;
	dom = 0;
	dongc = 0;
	dosao = 0;
	doabell = 0;
	mgrtr = mless= 0;
	if(dobbox)
		goto Cull;
	for(;;){
		if(s[0] == '>'){
			dogrtr = 1;
			mgrtr = 10 * strtod(s+1, &t);
			if(mgrtr==0  && t==s+1){
				fprint(2, "bad magnitude\n");
				return 0;
			}
			s = skipbl(t);
			continue;
		}
		if(s[0] == '<'){
			doless = 1;
			mless = 10 * strtod(s+1, &t);
			if(mless==0  && t==s+1){
				fprint(2, "bad magnitude\n");
				return 0;
			}
			s = skipbl(t);
			continue;
		}
		if(t = text(s, "m")){
 			dom = 1;
			s = t;
			continue;
		}
		if(t = text(s, "sao")){
			dosao = 1;
			s = t;
			continue;
		}
		if(t = text(s, "ngc")){
			dongc = 1;
			s = t;
			continue;
		}
		if(t = text(s, "abell")){
			doabell = 1;
			s = t;
			continue;
		}
		for(i=0; names[i].name; i++)
			if(t = alpha(s, names[i].name)){
				if(nobj > 100){
					fprint(2, "too many object types\n");
					return 0;
				}
				obj[nobj++] = names[i].type;
				s = t;
				goto Continue;
			}
		break;
	    Continue:;
	}
	if(*s){
		fprint(2, "syntax error in object list\n");
		return 0;
	}

    Cull:
	flatten();
	copy();
	reset();
	if(dom)
		mopen();
	if(dosao)
		saoopen();
	if(dongc || nobj)
		ngcopen();
	if(doabell)
		abellopen();
	for(i=0,or=orec; i<norec; i++,or++){
		keepthis = !keep;
		if(dobbox && inbbox(or->u.ngc.ra, or->u.ngc.dec))
			keepthis = keep;
		if(doless && or->u.ngc.mag <= mless)
			keepthis = keep;
		if(dogrtr && or->u.ngc.mag >= mgrtr)
			keepthis = keep;
		if(dom && (or->type==NGC && ism(or->u.ngc.ngc)))
			keepthis = keep;
		if(dongc && or->type==NGC)
			keepthis = keep;
		if(doabell && or->type==Abell)
			keepthis = keep;
		if(dosao && or->type==SAO)
			keepthis = keep;
		for(j=0; j<nobj; j++)
			if(or->type==NGC && or->u.ngc.type==obj[j])
				keepthis = keep;
		if(keepthis){
			grow();
			memmove(cur, or, sizeof(Record));
		}
	}
	return 1;
}

int
compar(const void *va, const void *vb)
{
	Record *a=(Record*)va, *b=(Record*)vb;

	if(a->type == b->type)
		return a->index - b->index;
	return a->type - b->type;
}

void
sort(void)
{
	int i;
	Record *r, *s;

	if(nrec == 0)
		return;
	qsort(rec, nrec, sizeof(Record), compar);
	r = rec+1;
	s = rec;
	for(i=1; i<nrec; i++,r++){
		/* may have multiple instances of a planet in the scene */
		if(r->type==s->type && r->index==s->index && r->type!=Planet)
			continue;
		memmove(++s, r, sizeof(Record));
	}
	nrec = (s+1)-rec;
}

char	greekbuf[128];

char*
togreek(char *s)
{
	char *t;
	int i, n;
	Rune r;

	t = greekbuf;
	while(*s){
		for(i=1; i<=24; i++){
			n = strlen(greek[i]);
			if(strncmp(s, greek[i], n)==0 && (s[n]==' ' || s[n]=='\t')){
				s += n;
				t += runetochar(t, &greeklet[i]);
				goto Cont;
			}
		}
		n = chartorune(&r, s);
		for(i=0; i<n; i++)
			*t++ = *s++;
    Cont:;
	}
	*t = 0;
	return greekbuf;
}

char*
fromgreek(char *s)
{
	char *t;
	int i, n;
	Rune r;

	t = greekbuf;
	while(*s){
		n = chartorune(&r, s);
		for(i=1; i<=24; i++){
			if(r == greeklet[i]){
				strcpy(t, greek[i]);
				t += strlen(greek[i]);
				s += n;
				goto Cont;
			}
		}
		for(i=0; i<n; i++)
			*t++ = *s++;
    Cont:;
	}
	*t = 0;
	return greekbuf;
}

#ifdef OLD
/*
 * Old version
 */
int
coords(int deg)
{
	int i;
	int x, y;
	Record *or;
	long dec, ra, ndec, nra;
	int rdeg;

	flatten();
	copy();
	reset();
	deg *= 2;
	for(i=0,or=orec; i<norec; i++,or++){
		if(or->type == Planet)	/* must keep it here */
			loadplanet(or->index, or);
		dec = or->u.ngc.dec/MILLIARCSEC;
		ra = or->u.ngc.ra/MILLIARCSEC;
		rdeg = deg/cos((dec*PI)/180);
		for(y=-deg; y<=+deg; y++){
			ndec = dec*2+y;
			if(ndec/2>=90 || ndec/2<=-90)
				continue;
			/* fp errors hurt here, so we round 1' to the pole */
			if(ndec >= 0)
				ndec = ndec*500*60*60 + 60000;
			else
				ndec = ndec*500*60*60 - 60000;
			for(x=-rdeg; x<=+rdeg; x++){
				nra = ra*2+x;
				if(nra/2 < 0)
					nra += 360*2;
				if(nra/2 >= 360)
					nra -= 360*2;
				/* fp errors hurt here, so we round up 1' */
				nra = nra/2*MILLIARCSEC + 60000;
				loadpatch(patcha(angle(nra), angle(ndec)));
			}
		}
	}
	sort();
	return 1;
}
#endif

/*
 * New version attempts to match the boundaries of the plot better.
 */
int
coords(int deg)
{
	int i;
	int x, y, xx;
	Record *or;
	long min, circle;
	double factor;

	flatten();
	circle = 360*MILLIARCSEC;
	deg *= MILLIARCSEC;

	/* find center */
	folded = 0;
	bbox(0, 0, 0);
	/* now expand */
	factor = cos(angle((decmax+decmin)/2));
	if(factor < .2)
		factor = .2;
	factor = floor(1/factor);
	folded = 0;
	bbox(factor*deg, deg, 1);
	Bprint(&bout, "%s to ", hms(angle(ramin)));
	Bprint(&bout, "%s\n", hms(angle(ramax)));
	Bprint(&bout, "%s to ", dms(angle(decmin)));
	Bprint(&bout, "%s\n", dms(angle(decmax)));
	copy();
	reset();
	for(i=0,or=orec; i<norec; i++,or++)
		if(or->type == Planet)	/* must keep it here */
			loadplanet(or->index, or);
	min = ramin;
	if(ramin > ramax)
		min -= circle;
	for(x=min; x<=ramax; x+=250*60*60){
		xx = x;
		if(xx < 0)
			xx += circle;
		for(y=decmin; y<=decmax; y+=250*60*60)
			if(-circle/4 < y && y < circle/4)
				loadpatch(patcha(angle(xx), angle(y)));
	}
	sort();
	cull(nil, 1, 1);
	return 1;
}

void
pplate(char *flags)
{
	int i;
	long c;
	int na, rah, ram, d1, d2;
	double r0;
	int ra, dec;
	long ramin, ramax, decmin, decmax;	/* all in degrees */
	Record *r;
	int folded;
	Angle racenter, deccenter, rasize, decsize, a[4];
	Picture *pic;

	rasize = -1.0;
	decsize = -1.0;
	na = 0;
	for(;;){
		while(*flags==' ')
			flags++;
		if(('0'<=*flags && *flags<='9') || *flags=='+' || *flags=='-'){
			if(na >= 3)
				goto err;
			a[na++] = getra(flags);
			while(*flags && *flags!=' ')
				flags++;
			continue;
		}
		if(*flags){
	err:
			Bprint(&bout, "syntax error in plate\n");
			return;
		}
		break;
	}
	switch(na){
	case 0:
		break;
	case 1:
		rasize = a[0];
		decsize = rasize;
		break;
	case 2:
		rasize = a[0];
		decsize = a[1];
		break;
	case 3:
	case 4:
		racenter = a[0];
		deccenter = a[1];
		rasize = a[2];
		if(na == 4)
			decsize = a[3];
		else
			decsize = rasize;
		if(rasize<0.0 || decsize<0.0){
			Bprint(&bout, "negative sizes\n");
			return;
		}
		goto done;
	}
	folded = 0;
	/* convert to milliarcsec */
	c = 1000*60*60;
    Again:
	if(nrec == 0){
		Bprint(&bout, "empty\n");
		return;
	}
	ramin = 0x7FFFFFFF;
	ramax = -0x7FFFFFFF;
	decmin = 0x7FFFFFFF;
	decmax = -0x7FFFFFFF;
	for(r=rec,i=0; i<nrec; i++,r++){
		if(r->type == Patch){
			radec(r->index, &rah, &ram, &dec);
			ra = 15*rah+ram/4;
			r0 = c/cos(RAD(dec));
			ra *= c;
			dec *= c;
			if(dec == 0)
				d1 = c, d2 = c;
			else if(dec < 0)
				d1 = c, d2 = 0;
			else
				d1 = 0, d2 = c;
		}else if(r->type==SAO || r->type==NGC || r->type==Abell){
			ra = r->u.ngc.ra;
			dec = r->u.ngc.dec;
			d1 = 0, d2 = 0, r0 = 0;
		}else if(r->type==NGCN){
			loadngc(r->index);
			continue;
		}else if(r->type==NamedSAO){
			loadsao(r->index);
			continue;
		}else if(r->type==NamedNGC){
			loadngc(r->index);
			continue;
		}else if(r->type==NamedAbell){
			loadabell(r->index);
			continue;
		}else
			continue;
		if(dec+d2 > decmax)
			decmax = dec+d2;
		if(dec-d1 < decmin)
			decmin = dec-d1;
		if(folded){
			ra -= 180*c;
			if(ra < 0)
				ra += 360*c;
		}
		if(ra+r0 > ramax)
			ramax = ra+r0;
		if(ra < ramin)
			ramin = ra;
	}
	if(!folded && ramax-ramin>270*c){
		folded = 1;
		goto Again;
	}
	racenter = angle(ramin+(ramax-ramin)/2);
	deccenter = angle(decmin+(decmax-decmin)/2);
	if(rasize<0 || decsize<0){
		rasize = angle(ramax-ramin)*cos(deccenter);
		decsize = angle(decmax-decmin);
	}
    done:
	if(DEG(rasize)>1.1 || DEG(decsize)>1.1){
		Bprint(&bout, "plate too big: %s", ms(rasize));
		Bprint(&bout, " x %s\n", ms(decsize));
		Bprint(&bout, "trimming to 30'x30'\n");
		rasize = RAD(0.5);
		decsize = RAD(0.5);
	}
	Bprint(&bout, "%s %s ", hms(racenter), dms(deccenter));
	Bprint(&bout, "%s", ms(rasize));
	Bprint(&bout, " x %s\n", ms(decsize));
	Bflush(&bout);
	flatten();
	pic = image(racenter, deccenter, rasize, decsize);
	if(pic == 0)
		return;
	Bprint(&bout, "plate %s locn %d %d %d %d\n", pic->name, pic->minx, pic->miny, pic->maxx, pic->maxy);
	Bflush(&bout);
	displaypic(pic);
}

void
lookup(char *s, int doreset)
{
	int i, j, k;
	int rah, ram, deg;
	char *starts, *inputline=s, *t, *u;
	Record *r;
	Rune c;
	long n;
	double x;
	Angle ra;

	lowercase(s);
	s = skipbl(s);

	if(*s == 0)
		goto Print;

	if(t = alpha(s, "flat")){
		if(*t){
			fprint(2, "flat takes no arguments\n");
			return;
		}
		if(nrec == 0){
			fprint(2, "no records\n");
			return;
		}
		flatten();
		goto Print;
	}

	if(t = alpha(s, "print")){
		if(*t){
			fprint(2, "print takes no arguments\n");
			return;
		}
		for(i=0,r=rec; i<nrec; i++,r++)
			prrec(r);
		return;
	}

	if(t = alpha(s, "add")){
		lookup(t, 0);
		return;
	}

	if(t = alpha(s, "sao")){
		n = strtoul(t, &u, 10);
		if(n<=0 || n>NSAO)
			goto NotFound;
		t = skipbl(u);
		if(*t){
			fprint(2, "syntax error in sao\n");
			return;
		}
		if(doreset)
			reset();
		if(!loadsao(n))
			goto NotFound;
		goto Print;
	}

	if(t = alpha(s, "ngc")){
		n = strtoul(t, &u, 10);
		if(n<=0 || n>NNGC)
			goto NotFound;
		t = skipbl(u);
		if(*t){
			fprint(2, "syntax error in ngc\n");
			return;
		}
		if(doreset)
			reset();
		if(!loadngc(n))
			goto NotFound;
		goto Print;
	}

	if(t = alpha(s, "ic")){
		n = strtoul(t, &u, 10);
		if(n<=0 || n>NIC)
			goto NotFound;
		t = skipbl(u);
		if(*t){
			fprint(2, "syntax error in ic\n");
			return;
		}
		if(doreset)
			reset();
		if(!loadngc(n+NNGC))
			goto NotFound;
		goto Print;
	}

	if(t = alpha(s, "abell")){
		n = strtoul(t, &u, 10);
		if(n<=0 || n>NAbell)
			goto NotFound;
		if(doreset)
			reset();
		if(!loadabell(n))
			goto NotFound;
		goto Print;
	}

	if(t = alpha(s, "m")){
		n = strtoul(t, &u, 10);
		if(n<=0 || n>NM)
			goto NotFound;
		mopen();
		for(j=n-1; mindex[j].m<n; j++)
			;
		if(doreset)
			reset();
		while(mindex[j].m == n){
			if(mindex[j].ngc){
				grow();
				cur->type = NGCN;
				cur->index = mindex[j].ngc;
			}
			j++;
		}
		goto Print;
	}

	for(i=1; i<=Ncon; i++)
		if(t = alpha(s, constel[i])){
			if(*t){
				fprint(2, "syntax error in constellation\n");
				return;
			}
			constelopen();
			seek(condb, 4L*conindex[i-1], 0);
			j = conindex[i]-conindex[i-1];
			Eread(condb, "con", con, 4*j);
			if(doreset)
				reset();
			for(k=0; k<j; k++){
				grow();
				cur->type = PatchC;
				cur->index = Long(&con[k]);
			}
			goto Print;
		}

	if(t = alpha(s, "expand")){
		n = 0;
		if(*t){
			if(*t<'0' && '9'<*t){
		Expanderr:
				fprint(2, "syntax error in expand\n");
				return;
			}
			n = strtoul(t, &u, 10);
			t = skipbl(u);
			if(*t)
				goto Expanderr;
		}
		coords(n);
		goto Print;
	}

	if(t = alpha(s, "plot")){
		if(nrec == 0){
			Bprint(&bout, "empty\n");
			return;
		}
		plot(t);
		return;
	}

	if(t = alpha(s, "astro")){
		astro(t, 0);
		return;
	}

	if(t = alpha(s, "plate")){
		pplate(t);
		return;
	}

	if(t = alpha(s, "gamma")){
		while(*t==' ')
			t++;
		u = t;
		x = strtod(t, &u);
		if(u > t)
			gam.gamma = x;
		Bprint(&bout, "%.2f\n", gam.gamma);
		return;
	}

	if(t = alpha(s, "keep")){
		if(!cull(t, 1, 0))
			return;
		goto Print;
	}

	if(t = alpha(s, "drop")){
		if(!cull(t, 0, 0))
			return;
		goto Print;
	}

	for(i=0; planet[i].name[0]; i++){
		if(t = alpha(s, planet[i].name)){
			if(doreset)
				reset();
			loadplanet(i, nil);
			goto Print;
		}
	}

	for(i=0; names[i].name; i++){
		if(t = alpha(s, names[i].name)){
			if(*t){
				fprint(2, "syntax error in type\n");
				return;
			}
			if(doreset)
				reset();
			loadtype(names[i].type);
			goto Print;
		}
	}

	switch(s[0]){
	case '"':
		starts = ++s;
		while(*s != '"')
			if(*s++ == 0){
				fprint(2, "bad star name\n");
				return;
			}
		*s = 0;
		if(doreset)
			reset();
		j = nrec;
		saoopen();
		starts = fromgreek(starts);
		for(i=0; i<NName; i++)
			if(equal(starts, name[i].name)){
				grow();
				if(name[i].sao){
					rec[j].type = NamedSAO;
					rec[j].index = name[i].sao;
				}
				if(name[i].ngc){
					rec[j].type = NamedNGC;
					rec[j].index = name[i].ngc;
				}
				if(name[i].abell){
					rec[j].type = NamedAbell;
					rec[j].index = name[i].abell;
				}
				strcpy(rec[j].u.named.name, name[i].name);
				j++;
			}
		if(parsename(starts))
			for(i=0; i<NBayer; i++)
				if(bayer[i].name[0]==parsed[0] &&
				  (bayer[i].name[1]==parsed[1] || parsed[1]==0) &&
				   bayer[i].name[2]==parsed[2]){
					grow();
					rec[j].type = NamedSAO;
					rec[j].index = bayer[i].sao;
					strncpy(rec[j].u.named.name, starts, sizeof(rec[j].u.named.name));
					j++;
				}
		if(j == 0){
			*s = '"';
			goto NotFound;
		}
		break;

	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
		strtoul(s, &t, 10);
		if(*t != 'h'){
	BadCoords:
			fprint(2, "bad coordinates %s\n", inputline);
			break;
		}
		ra = DEG(getra(s));
		while(*s && *s!=' ' && *s!='\t')
			s++;
		rah = ra/15;
		ra = ra-rah*15;
		ram = ra*4;
		deg = strtol(s, &t, 10);
		if(t == s)
			goto BadCoords;
		/* degree sign etc. is optional */
		chartorune(&c, t);
		if(c == 0xb0)
			deg = DEG(getra(s));
		if(doreset)
			reset();
		if(abs(deg)>=90 || rah>=24)
			goto BadCoords;
		if(!loadpatch(patch(rah, ram, deg)))
			goto NotFound;
		break;

	default:
		fprint(2, "unknown command %s\n", inputline);
		return;
	}

    Print:
	if(nrec == 0)
		Bprint(&bout, "empty\n");
	else if(nrec <= 2)
		for(i=0; i<nrec; i++)
			prrec(rec+i);
	else
		Bprint(&bout, "%ld items\n", nrec);
	return;

    NotFound:
	fprint(2, "%s not found\n", inputline);
	return;
}

char *ngctypes[] =
{
[Galaxy] 		"Gx",
[PlanetaryN]	"Pl",
[OpenCl]		"OC",
[GlobularCl]	"Gb",
[DiffuseN]		"Nb",
[NebularCl]	"C+N",
[Asterism]		"Ast",
[Knot]		"Kt",
[Triple]		"***",
[Double]		"D*",
[Single]		"*",
[Uncertain]	"?",
[Nonexistent]	"-",
[Unknown]	" ",
[PlateDefect]	"PD",
};

char*
ngcstring(int d)
{
	if(d<Galaxy || d>PlateDefect)
		return "can't happen";
	return ngctypes[d];
}

short	descindex[NINDEX];

void
printnames(Record *r)
{
	int i, ok, done;

	done = 0;
	for(i=0; i<NName; i++){	/* stupid linear search! */
		ok = 0;
		if(r->type==SAO && r->index==name[i].sao)
			ok = 1;
		if(r->type==NGC && r->u.ngc.ngc==name[i].ngc)
			ok = 1;
		if(r->type==Abell && r->u.abell.abell==name[i].abell)
			ok = 1;
		if(ok){
			if(done++ == 0)
				Bprint(&bout, "\t");
			Bprint(&bout, " \"%s\"", togreek(name[i].name));
		}
	}
	if(done)
		Bprint(&bout, "\n");
}

int
equal(char *s1, char *s2)
{
	int c;

	while(*s1){
		if(*s1==' '){
			while(*s1==' ')
				s1++;
			continue;
		}
		while(*s2==' ')
			s2++;
		c=*s2;
		if('A'<=*s2 && *s2<='Z')
			c^=' ';
		if(*s1!=c)
			return 0;
		s1++, s2++;
	}
	return 1;
}

int
parsename(char *s)
{
	char *blank;
	int i;

	blank = strchr(s, ' ');
	if(blank==0 || strchr(blank+1, ' ') || strlen(blank+1)!=3)
		return 0;
	blank++;
	parsed[0] = parsed[1] = parsed[2] = 0;
	if('0'<=s[0] && s[0]<='9'){
		i = atoi(s);
		parsed[0] = i;
		if(i > 100)
			return 0;
	}else{
		for(i=1; i<=24; i++)
			if(strncmp(greek[i], s, strlen(greek[i]))==0){
				parsed[0]=100+i;
				goto out;
			}
		return 0;
	    out:
		if('0'<=s[strlen(greek[i])] && s[strlen(greek[i])]<='9')
			parsed[1]=s[strlen(greek[i])]-'0';
	}
	for(i=1; i<=88; i++)
		if(strcmp(constel[i], blank)==0){
			parsed[2] = i;
			return 1;
		}
	return 0;
}

char*
dist_grp(int dg)
{
	switch(dg){
	default:
		return "unknown";
	case 1:
		return "13.3-14.0";
	case 2:
		return "14.1-14.8";
	case 3:
		return "14.9-15.6";
	case 4:
		return "15.7-16.4";
	case 5:
		return "16.5-17.2";
	case 6:
		return "17.3-18.0";
	case 7:
		return ">18.0";
	}
}

char*
rich_grp(int dg)
{
	switch(dg){
	default:
		return "unknown";
	case 0:
		return "30-40";
	case 1:
		return "50-79";
	case 2:
		return "80-129";
	case 3:
		return "130-199";
	case 4:
		return "200-299";
	case 5:
		return ">=300";
	}
}

char*
nameof(Record *r)
{
	NGCrec *n;
	SAOrec *s;
	Abellrec *a;
	static char buf[128];
	int i;

	switch(r->type){
	default:
		return nil;
	case SAO:
		s = &r->u.sao;
		if(s->name[0] == 0)
			return nil;
		if(s->name[0] >= 100){
			i = snprint(buf, sizeof buf, "%C", greeklet[s->name[0]-100]);
			if(s->name[1])
				i += snprint(buf+i, sizeof buf-i, "%d", s->name[1]);
		}else
			i = snprint(buf, sizeof buf, " %d", s->name[0]);
		snprint(buf+i, sizeof buf-i, " %s", constel[(uchar)s->name[2]]);
		break;
	case NGC:
		n = &r->u.ngc;
		if(n->type >= Uncertain)
			return nil;
		if(n->ngc <= NNGC)
			snprint(buf, sizeof buf, "NGC%4d ", n->ngc);
		else
			snprint(buf, sizeof buf, "IC%4d ", n->ngc-NNGC);
		break;
	case Abell:
		a = &r->u.abell;
		snprint(buf, sizeof buf, "Abell%4d", a->abell);
		break;
	}
	return buf;
}

void
prrec(Record *r)
{
	NGCrec *n;
	SAOrec *s;
	Abellrec *a;
	Planetrec *p;
	int i, rah, ram, dec, nn;
	long key;

	if(r) switch(r->type){
	default:
		fprint(2, "can't prrec type %d\n", r->type);
		exits("type");

	case Planet:
		p = &r->u.planet;
		Bprint(&bout, "%s", p->name);
		Bprint(&bout, "\t%s %s",
			hms(angle(p->ra)),
			dms(angle(p->dec)));
		Bprint(&bout, " %3.2f° %3.2f°",
			p->az/(double)MILLIARCSEC, p->alt/(double)MILLIARCSEC);
		Bprint(&bout, " %s",
			ms(angle(p->semidiam)));
		if(r->index <= 1)
			Bprint(&bout, " %g", p->phase);
		Bprint(&bout, "\n");
		break;

	case NGC:
		n = &r->u.ngc;
		if(n->ngc <= NNGC)
			Bprint(&bout, "NGC%4d ", n->ngc);
		else
			Bprint(&bout, "IC%4d ", n->ngc-NNGC);
		Bprint(&bout, "%s ", ngcstring(n->type));
		if(n->mag == UNKNOWNMAG)
			Bprint(&bout, "----");
		else
			Bprint(&bout, "%.1f%c", n->mag/10.0, n->magtype);
		Bprint(&bout, "\t%s %s\t%c%.1f'\n",
			hm(angle(n->ra)),
			dm(angle(n->dec)),
			n->diamlim,
			DEG(angle(n->diam))*60.);
		prdesc(n->desc, desctab, descindex);
		printnames(r);
		break;

	case Abell:
		a = &r->u.abell;
		Bprint(&bout, "Abell%4d  %.1f %.2f° %dMpc", a->abell, a->mag10/10.0,
			DEG(angle(a->rad)), a->dist);
		Bprint(&bout, "\t%s %s\t%.2f %.2f\n",
			hm(angle(a->ra)),
			dm(angle(a->dec)),
			DEG(angle(a->glat)),
			DEG(angle(a->glong)));
		Bprint(&bout, "\tdist grp: %s  rich grp: %s  %d galaxies/°²\n",
			dist_grp(a->distgrp),
			rich_grp(a->richgrp),
			a->pop);
		printnames(r);
		break;

	case SAO:
		s = &r->u.sao;
		Bprint(&bout, "SAO%6ld  ", r->index);
		if(s->mag==UNKNOWNMAG)
			Bprint(&bout, "---");
		else
			Bprint(&bout, "%.1f", s->mag/10.0);
		if(s->mpg==UNKNOWNMAG)
			Bprint(&bout, ",---");
		else
			Bprint(&bout, ",%.1f", s->mpg/10.0);
		Bprint(&bout, "  %s %s  %.4fs %.3f\"",
			hms(angle(s->ra)),
			dms(angle(s->dec)),
			DEG(angle(s->dra))*(4*60),
			DEG(angle(s->ddec))*(60*60));
		Bprint(&bout, "  %.3s %c %.2s %ld %d",
			s->spec, s->code, s->compid, s->hd, s->hdcode);
		if(s->name[0])
			Bprint(&bout, " \"%s\"", nameof(r));
		Bprint(&bout, "\n");
		printnames(r);
		break;

	case Patch:
		radec(r->index, &rah, &ram, &dec);
		Bprint(&bout, "%dh%dm %d°", rah, ram, dec);
		key = r->u.patch.key[0];
		Bprint(&bout, " %s", constel[key&0xFF]);
		if((key>>=8) & 0xFF)
			Bprint(&bout, " %s", constel[key&0xFF]);
		if((key>>=8) & 0xFF)
			Bprint(&bout, " %s", constel[key&0xFF]);
		if((key>>=8) & 0xFF)
			Bprint(&bout, " %s", constel[key&0xFF]);
		for(i=1; i<r->u.patch.nkey; i++){
			key = r->u.patch.key[i];
			switch(key&0x3F){
			case SAO:
				Bprint(&bout, " SAO%ld", (key>>8)&0xFFFFFF);
				break;
			case Abell:
				Bprint(&bout, " Abell%ld", (key>>8)&0xFFFFFF);
				break;
			default:	/* NGC */
				nn = (key>>16)&0xFFFF;
				if(nn > NNGC)
					Bprint(&bout, " IC%d", nn-NNGC);
				else
					Bprint(&bout, " NGC%d", nn);
				Bprint(&bout, "(%s)", ngcstring(key&0x3F));
				break;
			}
		}
		Bprint(&bout, "\n");
		break;

	case NGCN:
		if(r->index <= NNGC)
			Bprint(&bout, "NGC%ld\n", r->index);
		else
			Bprint(&bout, "IC%ld\n", r->index-NNGC);
		break;

	case NamedSAO:
		Bprint(&bout, "SAO%ld \"%s\"\n", r->index, togreek(r->u.named.name));
		break;

	case NamedNGC:
		if(r->index <= NNGC)
			Bprint(&bout, "NGC%ld \"%s\"\n", r->index, togreek(r->u.named.name));
		else
			Bprint(&bout, "IC%ld \"%s\"\n", r->index-NNGC, togreek(r->u.named.name));
		break;

	case NamedAbell:
		Bprint(&bout, "Abell%ld \"%s\"\n", r->index, togreek(r->u.named.name));
		break;

	case PatchC:
		radec(r->index, &rah, &ram, &dec);
		Bprint(&bout, "%dh%dm %d\n", rah, ram, dec);
		break;
	}
}
