#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/common/xy.c,v 2.2 1995/09/26 18:50:01 empire Exp $";
#endif

/*
 * xy.c
 *
 * x-y related conversion routines.
 *
 * Dave Pare, 1989
 */

#include <ctype.h>
#include <varargs.h>
#include "misc.h"
#include "xy.h"
#include "nat.h"
#include "sect.h"
#include "deity.h"
#include "file.h"
#include <stdio.h>

/*
 * return pointer to a string containing the x,y
 * coords as desired by a particular target country.
 */
s_char *
xyas(x, y, country)
	coord	x;
	coord	y;
	natid	country;
{
	struct	natstr *np;

	np = getnatp(country);
	return prbuf("%d,%d", xrel(np, x), yrel(np, y));
}

s_char *
ownxy(sp) 
	struct sctstr *sp;
{
	return xyas(sp->sct_x, sp->sct_y, sp->sct_own);
}

coord
xrel(np, absx)
	struct	natstr *np;
	coord	absx;
{
	coord	x;

	if ((np->nat_stat & STAT_ABS) == 0) {
		x = xnorm(absx - np->nat_xorg);
	} else {
		x = xnorm(absx);
	}
	if (x >= WORLD_X/2)
		x -= WORLD_X;
	else if (x < -WORLD_X/2)
		x += WORLD_X;
	return x;
}

coord
yrel(np, absy)
	struct	natstr *np;
	coord	absy;
{
	coord	y;

	if ((np->nat_stat & STAT_ABS) == 0) {
		y = ynorm(absy - np->nat_yorg);
	} else {
		y = ynorm(absy);
	}
	if (y >= WORLD_Y/2)
		y -= WORLD_Y;
	else if (y < -WORLD_Y/2)
		y += WORLD_Y;
	return y;
}

xyrelrange(np, src, dst)
	struct	natstr *np;
	struct	range *src;
	struct	range *dst;
{
	dst->lx = xrel(np, src->lx);
	dst->hx = xrel(np, src->hx);
	dst->ly = yrel(np, src->ly);
	dst->hy = yrel(np, src->hy);
	dst->width = src->width;
	dst->height = src->height;
}

xyabsrange(np, src, dst)
	struct	natstr *np;
	struct	range *src;
	struct	range *dst;
{
	dst->lx = xabs(np, src->lx);
	dst->hx = xabs(np, src->hx);
	dst->ly = yabs(np, src->ly);
	dst->hy = yabs(np, src->hy);
	dst->width = src->width;
	dst->height = src->height;
}

inputxy(xp, yp, cn)
	coord	*xp;
	coord	*yp;
	natid	cn;
{
	struct	natstr *np;

	np = getnatp(cn);
	*xp = xabs(np, *xp);
	*yp = yabs(np, *yp);
}

coord
xabs(np, relx)
	struct	natstr *np;
	coord	relx;
{
	if ((np->nat_stat & STAT_ABS) == 0)
		relx += np->nat_xorg;
	return xnorm(relx);
}

coord
yabs(np, rely)
	struct	natstr *np;
	coord	rely;
{
	if ((np->nat_stat & STAT_ABS) == 0)
		rely += np->nat_yorg;
	return ynorm(rely);
}

int
sctoff(x, y)
	coord	x;
	coord	y;
{
	if ((x + y) & 01) {
		logerror("%d,%d is an invalid sector specification!\n", x, y); 
		return -1;
	}
	return (ynorm(y) * WORLD_X + xnorm(x))/2;
}

coord
xnorm(x)
	register coord x;
{
	if (x < 0)
		x = WORLD_X - (-x % WORLD_X);
	return x % WORLD_X;
}

coord
ynorm(y)
	register coord y;
{
	if (y < 0)
		y = WORLD_Y - (-y % WORLD_Y);
	return y % WORLD_Y;
}

int
xyinrange(x, y, rp)
	coord	x;
	coord	y;
	struct	range *rp;
{
	if (rp->lx < rp->hx) {
		/* xrange doesn't wrap */
		if (x < rp->lx || x > rp->hx)
			return 0;
	} else {
		if (x < rp->lx && x > rp->hx)
			return 0;
	}
	if (rp->ly < rp->hy) {
		/* yrange doesn't wrap */
		if (y < rp->ly || y > rp->hy)
			return 0;
	} else {
		if (y < rp->ly && y > rp->hy)
			return 0;
	}
	return 1;
}


s_char *
prbuf(va_alist)
	va_dcl
{
	static	int	nbuf = -1;
	static	s_char	buf[20][1024];
	s_char	*format;
	va_list ap;

	if (++nbuf > 19)
		nbuf = 0;

	va_start(ap);
	format = va_arg(ap, s_char *);
	(void) vsprintf(buf[nbuf], format, ap);
	va_end(ap);

	return buf[nbuf];
}

