/*
 * A* definitions.
 *
 * @(#)as.h	1.9	11/13/90
 */

/*
 * Coordinate.
 */
struct as_coord {
	int	x, y;
};

/*
 * Path, made up of a linked list of coordinates.
 */
struct as_path {
	struct as_coord	c;
	struct as_path	*next;
};

/*
 * Basic node, used internally by A* algorithm.
 */
struct as_node {
	struct as_coord	c;		/* our coordinate */
	double		knowncost;	/* cost so far  */
	double		lbcost;		/* lower bound on cost to dest */
	double		inclbcost;	/* incremental lower bound cost */
	double		seccost;	/* used to break ties */
	int		step;
	int		flags;
	struct as_node	*back;
};
#define	AS_TRIED	1		/* we've tried this node before */

/*
 * Linked list of nodes, used internally by A* algorithm.
 */
struct as_queue {
	struct as_node	*np;
	struct as_queue	*next;
	struct as_queue	*prev;
};

/*
 * Hash table entry, used to determine if we've seen a particular
 * coordinate before.
 */
struct as_hash {
	struct as_coord	c;
	struct as_queue	*qp;
	struct as_hash	*next;
};

/*
 * User's handle on A*, returned by as_init().  Some of the data here is
 * used by A* internals.
 */
struct as_data {
	int		maxneighbors;	/* max # of neighbors a cell can have */
	int		hashsize;	/* size of internal hash table */
	int		(*hash)();	/* hash function (coord -> int) */
	int		(*neighbor)();	/* function to find neighbors */
	double		(*lbcost)();	/* function to give lower bound cost */
	double		(*realcost)();	/* function to give real cost */
	double		(*seccost)();	/* function to secondary cost */
	char		*userdata;	/* user's data, passed to callbacks */
	struct as_coord	from;		/* from coordinate */
	struct as_coord	to;		/* to coordinate */
	struct as_path	*path;		/* solution */

	/* below are "private" to as_ routines */
	struct as_queue	*head;
	struct as_queue	*tried;
	struct as_hash	**hashtab;
	struct as_queue	*subsumed;
	struct as_coord	*neighbor_coords;
	struct as_node	**neighbor_nodes;
};

/*
 * Some cheezy allocation macros.
 */
#define	AS_NEW_ARRAY(p, type, n, err) \
	(p) = (type *)calloc((n), sizeof (*(p))); \
	if ((p) == NULL) \
		return err; \

#define	AS_NEW(p, type, err) \
	AS_NEW_ARRAY((p), type, 1, err);

/* Functions that the user can call.  */

extern	struct as_data	*as_init();
extern	int		as_search();
extern	void		as_delete();
extern	void		as_reset();

/* Funcrtions that are "private" to algorithm */

extern	int		as_costcomp();
extern	struct as_queue	*as_extend();
extern	struct as_queue	*as_merge();
extern	struct as_queue	*as_iscinq();
extern	void		as_setcinq();
extern	void		as_free_hashtab();
