#ifndef lint
static char *RCSid = "$Header: snxtitem.c,v 1.15 89/12/01 20:30:53 mr-frog Exp $";
#endif

/*
 * snxtitem.c
 *
 * arrange item selection using one of many different
 * criteria.
 *
 * Dave Pare, 1989
 */

#include "misc.h"
#include "var.h"
#include "xy.h"
#include "sect.h"
#include "nsc.h"
#include "file.h"
#include "com.h"

/*
 * setup the nstr structure for sector selection.
 * can select on NS_ALL, NS_AREA, NS_DIST, and NS_LIST.
 * iterate thru the "condarg" string looking
 * for arguments to compile into the nstr.
 */
int
snxtitem(np, type, str)
	register struct nstr_item *np;
	int	type;
	char	*str;
{
	register char *cp;
	struct	range range;
	int	list[NS_LSIZE];
	int	n;
	coord	cx, cy;
	int	dist;
	int	flags;
	char	natnumber[16];

	np->type = NS_UNDEF;
	np->sel = NS_UNDEF;
	if (str == 0) {
		str = getstring(fmt("%s(s)? ", ef_nameof(type)));
		if (str == 0)
			return 0;
	}
	if (*str == 0) {
		/* str present, but only <cr>: nil string passed by player */
		return 0;
	}
	if(type == EF_NATION && isalpha(*str)) {
		sprintf(natnumber, "%d", natarg(str, ""));
		str = natnumber;
	}
	flags = ef_flags(type);
	switch (sarg_type(str)) {
	case NS_AREA:
		if (!(flags & EFF_XY))
			return 0;
		if (!sarg_area(str, &range))
			return 0;
		snxtitem_area(np, type, &range);
		break;
	case NS_DIST:
		if (!(flags & EFF_XY))
			return 0;
		if (!sarg_range(str, &cx, &cy, &dist))
			return 0;
		snxtitem_dist(np, type, cx, cy, dist);
		break;
	case NS_ALL:
		snxtitem_all(np, type);
		break;
	case NS_LIST:
		if ((n = sarg_list(str, list, NS_LSIZE)) == 0)
			return 0;
		if (!snxtitem_list(np, type, list, n))
			return 0;
		break;
	case NS_XY:
		if (!(flags & EFF_XY))
			return 0;
		if (!sarg_xy(str, &cx, &cy))
			return 0;
		snxtitem_xy(np, type, cx, cy);
		break;
	case NS_GROUP:
		if (!(flags & EFF_GROUP))
			return 0;
		snxtitem_group(np, type, *str);
		break;
	default:
		return 0;
	}
	np->flags = flags;
	if (condarg == 0)
		return 1;
	cp = condarg;
	while ((cp = nstr_comp(np->cond, &np->ncond, type, cp)) && *cp)
		;
	if (cp == 0)
		return 0;
	return 1;
}

snxtitem_area(np, type, range)
	register struct nstr_item *np;
	int	type;
	struct	range *range;
{
	bzero(np, sizeof(*np));
	np->cur = -1;
	np->type = type;
	np->sel = NS_AREA;
	np->index = -1;
	np->range = *range;
	np->read = ef_read;
	np->flags = ef_flags(type);
	xysize_range(&np->range);
	ef_zapcache(type);
}

snxtitem_dist(np, type, cx, cy, dist)
	register struct nstr_item *np;
	int	type;
	int	cx, cy;
	int	dist;
{
	struct	range range;

	bzero(np, sizeof(*np));
	xydist_range(cx, cy, dist, &range);
	np->cur = -1;
	np->type = type;
	np->sel = NS_DIST;
	np->cx = cx;
	np->cy = cy;
	np->index = -1;
	np->range = range;
	np->dist = dist;
	np->read = ef_read;
	np->flags = ef_flags(type);
#if 0
	/* This is no longer proper. */
	/* It did the wrong thing for small, hitech worlds. */
	xysize_range(&np->range);
#endif
	ef_zapcache(type);
}

snxtitem_xy(np, type, x, y)
	register struct nstr_item *np;
	int	type;
	coord	x, y;
{
	bzero(np, sizeof(*np));
	np->cur = -1;
	np->type = type;
	np->sel = NS_XY;
	np->cx = x;
	np->cy = y;
	np->index = -1;
	np->dist = 0;
	np->read = ef_read;
	np->flags = ef_flags(type);
	ef_zapcache(type);
}

snxtitem_all(np, type)
	register struct nstr_item *np;
	int	type;
{
	bzero(np, sizeof(*np));
	np->cur = -1;
	np->sel = NS_ALL;
	np->type = type;
	np->index = -1;
	np->read = ef_read;
	np->flags = ef_flags(type);
	xysize_range(&np->range);
	ef_zapcache(type);
}

snxtitem_group(np, type, group)
	register struct nstr_item *np;
	int	type;
	char	group;
{
	if (group == '~')
		group = ' ';
	bzero(np, sizeof(*np));
	np->cur = -1;
	np->sel = NS_GROUP;
	np->group = group;
	np->type = type;
	np->index = -1;
	np->read = ef_read;
	np->flags = ef_flags(type);
	xysize_range(&np->range);
	ef_zapcache(type);
}

snxtitem_rewind(np)
	struct	nstr_item *np;
{
	np->cur = -1;
	np->index = -1;
	ef_zapcache(np->type);
}

int
snxtitem_list(np, type, list, len)
	register struct nstr_item *np;
	int	type;
	int	*list;
	int	len;
{
	int	i;

	bzero(np, sizeof(*np));
	np->cur = -1;
	np->type = type;
	np->sel = NS_LIST;
	np->index = -1;
	np->read = ef_read;
	np->flags = ef_flags(type);
	if (len <= 0 || len > NS_LSIZE)
		return 0;
	for (i=0; i<len; i++)
		np->list[i] = list[i];
	np->size = len;
	ef_zapcache(type);
	return 1;
}
