#ifndef lint
static char *RCSid = "$Header: /u/dhay/stan/kent/lib/common/RCS/natfield.c,v 1.2 91/03/19 03:13:13 dhay Exp Locker: dhay $";
#endif

/*
 * natfield.c
 *
 * Return definition of nation structure fields.
 * Assign values to in-memory copy of nation structure.
 *
 * Dave Pare, 1989
 */

#include "misc.h"
#include <fcntl.h>
#include "nat.h"
#include "file.h"
#include "tm.h"
#include "sect.h"

struct fixnat fixnat[] = {
	"nat_cnam", NF_STRING,1,NF_NOTIFY,	OFFSET(natstr, nat_cnam[0]),
	"nat_pnam", NF_STRING,1,NF_PRIVATE,	OFFSET(natstr, nat_pnam[0]),
	"nat_login", NF_CHAR,1,	NF_PRIVATE, 	OFFSET(natstr, nat_login),
	"nat_xcap", NF_COORD,1,	NF_NOTIFY,	OFFSET(natstr, nat_xcap),
	"nat_ycap", NF_COORD,1,	NF_NOTIFY,	OFFSET(natstr, nat_ycap),
	"nat_xorg", NF_COORD,1,	NF_NOTIFY,	OFFSET(natstr, nat_xorg),
	"nat_yorg", NF_COORD,1,	NF_NOTIFY,	OFFSET(natstr, nat_yorg),
	"nat_stat", NF_CHAR,1,	NF_NOTIFY,	OFFSET(natstr, nat_stat),
#ifdef	DEMANDUPDATE
	"nat_update", NF_CHAR,1,NF_NOTIFY,	OFFSET(natstr, nat_update),
	"nat_missed", NF_UCHAR,1,NF_NOTIFY,	OFFSET(natstr, nat_missed),
#endif	DEMANDUPDATE
	"nat_dayno", NF_CHAR,1,	NF_PRIVATE,	OFFSET(natstr, nat_dayno),
	"nat_btu", NF_LONG,1,	NF_PRIVATE,	OFFSET(natstr, nat_btu),
	"nat_reserve", NF_LONG,1,NF_PRIVATE,	OFFSET(natstr, nat_reserve),
	"nat_tgms", NF_LONG,1,	NF_PRIVATE,	OFFSET(natstr, nat_tgms),
	"nat_ann",   NF_LONG,1,	NF_PRIVATE,	OFFSET(natstr, nat_ann),
	"nat_minused", NF_LONG,1,NF_PRIVATE,	OFFSET(natstr, nat_minused),
	"nat_date", NF_LONG,1,	NF_PRIVATE,	OFFSET(natstr, nat_date),
	"nat_money", NF_LONG,1,	NF_NOTIFY,	OFFSET(natstr, nat_money),
	"nat_newstim", NF_LONG,1,NF_PRIVATE,	OFFSET(natstr, nat_newstim),
#ifdef SLOW_WAR
	"nat_relate", NF_SHORT,MAXNOC,NF_NOTIFY,OFFSET(natstr, nat_relate[0]),
#else
	"nat_relate", NF_SHORT,MAXNOC/8,NF_NOTIFY,OFFSET(natstr, nat_relate[0]),
#endif /* SLOW_WAR */
	"nat_b", NF_BOUND,MAXNOR,NF_PRIVATE,	OFFSET(natstr, nat_b[0]),
	"nat_level", NF_FLOAT,4,NF_PRIVATE,	OFFSET(natstr, nat_level[0]),
#ifdef        REJECTS
	"nat_rejects",NF_SHORT,MAXNOC/4,NF_NOTIFY,OFFSET(natstr,nat_rejects[0]),
#endif        REJECTS
#ifdef BUDGET
	"nat_priorities",NF_CHAR,SCT_MAXDEF+6,NF_PRIVATE,OFFSET(natstr,nat_priorities[0]),
#endif /* BUDGET */
	0,	0,	0,		-1,
};

struct fixnat *
natfield(offset)
	int	offset;
{
	register struct fixnat *fp;

	for (fp = fixnat; fp->offset >= 0; fp++) {
		if (fp->offset == offset)
			return fp;
	}
	return 0;
}

/*
 * XXX will cause sun 4 compiler (SunOS 4.0.1) to generate
 * wrong code; use gcc.
 */
union natelem {
	char *ch;
	u_char *uch;
	short *sh;
	long *lo;
	float *fl;
	double *dbl;
	struct boundstr *bnd;
	char *str;
};

int
natassign(fp, ptr, valp, ind, how)
	struct	fixnat *fp;
	char	*ptr;
	char	*valp;
	int	ind;
	int	how;
{
	union natelem addr;

	addr.ch = ptr;
	switch (fp->type) {
	case NF_CHAR:
		if (how == NF_DELTA)
			addr.ch[ind] += atoi(valp);
		else
			addr.ch[ind] = atoi(valp);
		break;
	case NF_UCHAR:
		if (how == NF_DELTA)
			addr.uch[ind] += atoi(valp);
		else
			addr.uch[ind] = atoi(valp);
		break;
	case NF_SHORT:
		if (how == NF_DELTA)
			addr.sh[ind] += atoi(valp);
		else
			addr.sh[ind] = atoi(valp);
		break;
	case NF_LONG:
		if (how == NF_DELTA)
			addr.lo[ind] += atoi(valp);
		else
			addr.lo[ind] = atoi(valp);
		break;
	case NF_FLOAT:
		if (how == NF_DELTA)
			addr.fl[ind] += atof(valp);
		else
			addr.fl[ind] = atof(valp);
		break;
	case NF_DOUBLE:
		if (how == NF_DELTA)
			addr.dbl[ind] += atof(valp);
		else
			addr.dbl[ind] = atof(valp);
		break;
	case NF_STRING:
		strcpy(addr.str, valp);
		break;
	case NF_BOUND:
		if (*valp)
			addr.bnd[ind].b_xl = atoip(&valp);
		if (*valp)
			addr.bnd[ind].b_xh = atoip(&valp);
		if (*valp)
			addr.bnd[ind].b_yl = atoip(&valp);
		if (*valp)
			addr.bnd[ind].b_yh = atoip(&valp);
		break;
	default:
		logerror("bad case value %d", fp->type);
	}
}
