/* LabelList- a datastructure for storing an arbitrarily long list of character
**            strings. They may be accessed by their index in the list (as in
**            an array) or searched for by label.
*/
#ifndef _JSW_LABELLIST_H_
#define _JSW_LABELLIST_H_

#include "bintree.h"

/* LabelList data structure, members should never be accessed directly */
typedef struct labellist_t LabelList;

#define DEFAULTLEN	4

typedef struct {
	const char *label;
	int idx;
} Node;

struct labellist_t {
   char **list;          /* an array of the labels                           */
   unsigned int curLen;  /* the current length of the list (index of last    **
                         **  label plus one)                                 */
   unsigned int listLen; /* number of labels that the list can hold without  **
                         **  resizing the list array                         */
   BinTree *bt;          /* tree containing the labels for searching         */
};

/*#ifdef __cplusplus
extern "C" {
#endif*/

/* resizeList- function to resize the labellist to allow for by more/fewer
**             labels
*/
static int resizeList(LabelList *ll, int by);

/* icomp- insertion comparison function for the BinTree data structure */
static int icomp(const void *a, const void *b);

/* fcomp- search comparison function for the BinTree data structure */
static int fcomp(const void *a, const void *b);


/*******************       constructors/destructor         *******************/
/* initLabelList- creates a LabelList data structure
**
** *input parameters*
** int               initialLength initial length of the list
**
** *return*
** LabelList       *               initialized label list structure
*/
LabelList *initLabelList(int initialLength);

/* copyLabelList- creates a LabelList data structure
**
** *input parameters*
** const LabelList * from          list to copy from
**
** *return*
** LabelList       *               initialized label list structure that is a
**                                 copy of the provided list
*/
LabelList *copyLabelList(const LabelList *from);

/* freeLabelList- frees a LabelList data structure
**
** *input parameters*
** LabelList       * ll          LabelList to free
*/
void freeLabelList(LabelList *ll);

/*******************           accessor functions          *******************/
/* ll_getIndex- get an index of the provided label
**
** *input parameters*
** const LabelList * ll          LabelList to access
** const char      * label         label to search for, if NULL, returns the
**                                 next label that matches the prevously
**                                 sought label
**
** *output parameters*
** int             * err           optional error code, 0 means no error
**
** *return*
** int                             index of the label or 0 on error
*/
unsigned int ll_getIndex(const LabelList *ll, const char *label, int *err);

/* ll_getLabel- gets the label at the provided index
**
** *input parameters*
** const LabelList * ll          LabelList to access
** int               idx           index of the label to return, zero based
**
** *return*
** const char      *               label corresponding to the provided index
**                                 or < 0 on error
*/
const char *ll_getLabel(const LabelList *ll, unsigned int idx);

/* ll_getLength- get the length of the list
**
** *input parameters*
** const LabelList * ll          LabelList to access
**
** *return*
** int                             list length or 0 on error (or if empty)
*/
unsigned int ll_getLength(const LabelList *ll);

/* ll_getLabels- get the labels as an array of strings
**
** *input parameters*
** const LabelList * ll          LabelList to access
**
** *return*
** const char      **              array of strings containing labels
*/
const char **ll_getLabels(const LabelList *ll);

/*******************           modifier functions          *******************/
/* ll_setLabel- set a label in the list or delete it if the label is NULL
**
** *input parameters*
** LabelList       * ll          LabelList to access
** int               idx           index of the label to set
** const char      * label         label to set to, if NULL, will erase the
**                                 label at the specified position
**
** *return*
** int                             0 on success, < 0 on error
*/
int ll_setLabel(LabelList *ll, int idx, const char *label);

/* ll_appendLabel- append a label to the list
**
** *input parameters*
** LabelList       * ll          LabelList to access
** const char      * label         label to append, should not be NULL
**
** *return*
** int                             0 on success, < 0 on error
*/
int ll_appendLabel(LabelList *ll, const char *label);

/* ll_compactList- reduce excess memory usage in the list
**
** *input parameters*
** LabelList       * ll          LabelList to compact
**
** *return*
** int                             0 on success, < 0 on error
*/
int ll_compactList(LabelList *ll);

/*#ifdef __cplusplus
}
#endif*/

#endif
