#ifndef _KDTREE_H_
#define _KDTREE_H_

#ifdef __cplusplus
extern "C" {
#endif

void *kd_create(void);
void kd_free(void *tree);

/* remove all the elements from the tree */
void kd_clear(void *tree);

/* if called with non-null 2nd argument, the function provided
 * will be called on data pointers (see kd_insert) when nodes
 * are to be removed from the tree.
 */
void kd_data_destructor(void *tree, void (*destr)(void*));

/* insert a node, specifying its 3D position, and optional data */
int kd_insert(void *tree, float x, float y, float z, void *data);

/* Find the N nearest nodes from the specified point.
 *
 * This function returns a pointer to a result set, which can be manipulated
 * by the kd_res_* functions.
 * The returned pointer can be null as an indication of an error. Otherwise
 * a valid result set is always returned which may contain 0 or more elements.
 */
void *kd_nearest_n(void *tree, float x, float y, float z, int num);

/* Find any nearest nodes from the specified point within a range.
 *
 * This function returns a pointer to a result set, which can be manipulated
 * by the kd_res_* functions.
 * The returned pointer can be null as an indication of an error. Otherwise
 * a valid result set is always returned which may contain 0 or more elements.
 */
void *kd_nearest_range(void *tree, float x, float y, float z, float range);


/* returns the size of the result set (in elements) */
int kd_res_size(void *set);

/* rewinds the result set iterator */
void kd_res_rewind(void *set);

/* advances the result set iterator, returns non-zero on success, zero if
 * there are no more elements in the result set.
 */
int kd_res_next(void *set);

/* returns the data pointer (can be null) of the current result set item
 * and optionally sets its position to the x, y, z pointers, if not null.
 */
void *kd_res_item(void *set, float *x, float *y, float *z);

/* equivalent to kd_res_item(set, 0, 0, 0) */
void *kd_res_item_data(void *set);


#ifdef __cplusplus
}
#endif

#endif  /* _KDTREE_H_ */