#ifndef _NODELIST_H
#define _NODELIST_H

////////////////////////////////////////////////////////////////////////////
//	defines
////////////////////////////////////////////////////////////////////////////

#define	NODE_NORMAL		0
#define	NODE_DOOR		1
#define	NODE_TELEPORTER	2
#define	NODE_ROCKETJUMP	4
#define	NODE_SWITCH		8
#define	NODE_LIFT		16


////////////////////////////////////////////////////////////////////////////
//	typedefs
////////////////////////////////////////////////////////////////////////////

typedef	struct	teleportNode_s
{
	vec3_t	start_origin;
	vec3_t	dest_origin;
} teleportNode_t;


////////////////////////////////////////////////////////////////////////////
//	globals and externs
////////////////////////////////////////////////////////////////////////////

extern		mapHeader_t	*client_nodes;
extern		int			nodes_in_map;

////////////////////////////////////////////////////////////////////////////
//	node list management functions
////////////////////////////////////////////////////////////////////////////

mapHeader_t	*node_create_header (void);
mapList_t	*node_create_nodelist (mapHeader_t *header);
void		node_delete_nodelist (mapHeader_t **header);
mapNode_t	*node_create_node (mapHeader_t **header);
mapNode_t	*node_add_node (userEntity_t *self, mapList_t *node_list, vec3_t org, mapNode_t *last_node);
mapNode_t	*node_find_node (mapList_t *node_list, vec3_t org, float dist, int type);

////////////////////////////////////////////////////////////////////////////
//	node list building functions
////////////////////////////////////////////////////////////////////////////

int			node_visible (userEntity_t *ignore, vec3_t start, vec3_t end);
void		node_link_node (mapNode_t *node1, mapNode_t *node2);
void		node_link_nodes (userEntity_t *self, mapNode_t *node1, mapNode_t *node2);
int			node_is_linked (mapNode_t *node);
void		node_log_items	(userEntity_t	*self, mapList_t *node_list);
void		node_place_spawn_node (userEntity_t *self, mapList_t *node_list);
int			node_find_cur_node (userEntity_t *self, mapList_t *node_list);
void		node_place_node (userEntity_t *self, mapList_t *node_list, vec3_t last_loc);
void		node_force_node (userEntity_t *self, mapList_t *node_list, vec3_t origin, int type, void *data);

////////////////////////////////////////////////////////////////////////////
//	routines for finding paths
////////////////////////////////////////////////////////////////////////////

pathNode_t	*path_shortest (userEntity_t *self, mapList_t *node_list, mapNode_t *start_node, mapNode_t *end_node, int &path_length);
pathNode_t	*path_last_node (pathNode_t *path);
pathNode_t	*path_delete_first (pathNode_t *path);
pathNode_t	*path_kill (pathNode_t *path);
pathNode_t	*path_add_node (pathNode_t *path, mapNode_t *map_node);
pathNode_t	*path_update_to_node (pathNode_t *path, mapNode_t *node);

////////////////////////////////////////////////////////////////////////////
//	debugging stuff
////////////////////////////////////////////////////////////////////////////

void		node_show_links	(userEntity_t	*self);
void		node_toggle_nodes	(userEntity_t	*self);
void		node_set_viewer (userEntity_t *self);

////////////////////////////////////////////////////////////////////////////
//	node navigation
////////////////////////////////////////////////////////////////////////////

float		node_time_for_ID (mapNode_t *node, int ID);
mapNode_t	*node_best_time_for_ID (mapNode_t *cur_node, int ID);
mapNode_t	*node_random_link (mapNode_t *map_node, mapNode_t *last_node);
mapNode_t	*node_next_travel (userEntity_t *self, mapList_t *node_list);
int			node_can_path (mapNode_t *start_node, mapNode_t *end_node, int depth);
mapNode_t	*node_closest (mapList_t *list, vec3_t origin, float dist);
mapNode_t	*node_linked_with_target (mapNode_t *node, char *targetname);

////////////////////////////////////////////////////////////////////////////
//	saving and restoring nodes
////////////////////////////////////////////////////////////////////////////

void		node_writelist (mapHeader_t *node_header);
void		node_readlist (mapHeader_t **node_header);
void		node_restore_links (userEntity_t *self);

#define		DllExport	extern "C"	__declspec( dllexport )
DllExport	void	node_node (userEntity_t *self);

#endif