/* -*- mode: c ; c-file-style: "canonware-c-style" -*-
 ****************************************************************************
 *
 * Copyright (C) 1996-1999 Jason Evans <jasone@canonware.com>.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice(s), this list of conditions and the following disclaimer as
 *    the first lines of this file unmodified other than the possible
 *    addition of one or more copyright notices.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice(s), this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************
 *
 * Version: s19990912a
 *
 * <<< Description >>>
 *
 * Implementation of arbitrary trees.  Each treen (tree node) can have an
 * arbitrary number of children.
 *
 ****************************************************************************/

/* Pseudo-opaque type. */
typedef struct cw_treen_s cw_treen_t;

struct cw_treen_s
{
#ifdef _CW_REENTRANT
  cw_bool_t is_thread_safe;
  cw_mtx_t lock;
#endif
  void * data;
  cw_uint32_t num_children;
  cw_treen_t ** children;
};

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * None.
 *
 * <<< Output(s) >>>
 *
 * retval : Pointer to a treen, or NULL.
 *          NULL : Memory allocation error.
 *
 * <<< Description >>>
 *
 * Non-thread-safe and thread-safe constructors.
 *
 ****************************************************************************/
cw_treen_t *
treen_new(void);
#ifdef _CW_REENTRANT
cw_treen_t *
treen_new_r(void);
#endif

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * <<< Output(s) >>>
 *
 * None.
 *
 * <<< Description >>>
 *
 * Destructor.  Recursively destroys all subtrees.
 *
 ****************************************************************************/
void
treen_delete(cw_treen_t * a_treen);

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * <<< Output(s) >>>
 *
 * retval : Number of children of a_treen.
 *
 * <<< Description >>>
 *
 * Return the number of children of a_treen.
 *
 ****************************************************************************/
cw_uint32_t
treen_get_num_children(cw_treen_t * a_treen);

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * a_child : Pointer to a treen.
 *
 * a_position : Which child of a_treen to insert a_child as (0..n).
 *
 * <<< Output(s) >>>
 *
 * retval : FALSE == success, TRUE == error.
 *          TRUE : a_position > number of children.
 *               : Memory allocation error.
 *
 * <<< Description >>>
 *
 * Insert a child pointer at position a_position.  If a_position is greater than
 * the number of children, return TRUE and do not insert the child pointer.
 *
 ****************************************************************************/
cw_bool_t
treen_link_child(cw_treen_t * a_treen, cw_treen_t * a_child,
		 cw_uint32_t a_position);

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * a_position : Which child of a_treen to unlink (0..n).
 *
 * <<< Output(s) >>>
 *
 * retval : FALSE == success, TRUE == error.
 *          TRUE : a_position > number of children.
 *
 * *r_child : Pointer to a treen.
 *
 * <<< Description >>>
 *
 * Delete child pointer at a_position and shuffle following children down to
 * fill the space.  If a_position is greater than the index of the last child,
 * return TRUE.
 *
 ****************************************************************************/
cw_bool_t
treen_unlink_child(cw_treen_t * a_treen, cw_uint32_t a_position,
		   cw_treen_t ** r_child);

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * a_position : Whild child of a_treen to return a pointer to (0..n).
 *
 * <<< Output(s) >>>
 *
 * retval : FALSE == success, TRUE == error.
 *          TRUE : a_position > number of children.
 *
 * *r_child : Pointer to a treen.
 *
 * <<< Description >>>
 *
 * Return a pointer to the child pointer at a_position in *r_child, unless
 * a_position is greater than the index of the last child, in which case, return
 * TRUE.
 *
 ****************************************************************************/
cw_bool_t
treen_get_child_ptr(cw_treen_t * a_treen, cw_uint32_t a_position,
		    cw_treen_t ** r_child);

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * <<< Output(s) >>>
 *
 * retval : Pointer to data.
 *
 * <<< Description >>>
 *
 * Return a pointer to the data for a_treen.
 *
 ****************************************************************************/
void *
treen_get_data_ptr(cw_treen_t * a_treen);

/****************************************************************************
 *
 * <<< Input(s) >>>
 *
 * a_treen : Pointer to a treen.
 *
 * a_data : Pointer to data.
 *
 * <<< Output(s) >>>
 *
 * retval : Pointer to old data.
 *
 * <<< Description >>>
 *
 * Set the pointer for data for a_treen.
 *
 ****************************************************************************/
void *
treen_set_data_ptr(cw_treen_t * a_treen, void * a_data);
