#ifndef __Set__H
#define __Set__H

#include "WimpLib:std.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct Set Set;
typedef struct SetVPtr SetVPtr;
typedef struct SetNode SetNode;

typedef void* (*Set_FAlloc)(void* pHandle, const void* pData) throws(mem);
typedef void (*Set_FDelete)(void* pHandle, void* pData);
typedef int (*Set_FCompare)(const void*, const void*);

/*
 * FAlloc    Function used to make a copy of any data to insert.
 *           Use NULL to simply insert the original data.
 * FDelete   Function used to delete the data associated to any deleted node.
 *           Use NULL if alloc is NULL.
 * FCompare  Function to use to compare elements (Find).
 */

struct SetVPtr
{
	Set_FAlloc    FAlloc;
	Set_FDelete   FDelete;
	Set_FCompare  FCompare;
};

Set*         New_Set            (void* pHandle, const SetVPtr* VPtr) throws(mem);
void         Delete_Set         (Set*);

int          Set_Count          (const Set*);
Set_FCompare Set_GetFCompare    (const Set*);

SetNode*     Set_InsertAfter    (Set*, SetNode* pNode, const void* pData) throws(mem);
SetNode*     Set_InsertBefore   (Set*, SetNode* pNode, const void* pData) throws(mem);
void         Set_SetNodeData    (Set*, SetNode* pNode, const void* pData) throws(null);
void         Set_RemoveNode     (Set*, SetNode* pNode);

SetNode*     Set_Insert         (Set*, int index, const void* pData) throws(mem index);
void         Set_SetData        (Set*, int index, const void* pData) throws(index);
void         Set_Remove         (Set*, int index) throws(index);
void         Set_Clear          (Set*);

int          Set_GetNodeIndex   (const Set*, const SetNode* pNode) throws(null);
void*        Set_GetNodeData    (const Set*, const SetNode* pNode) throws(null);
SetNode*     Set_GetSuccessor   (const Set*, const SetNode* pNode);
SetNode*     Set_GetPredeccessor(const Set*, const SetNode* pNode);
SetNode*     Set_FindNode       (const Set*, const SetNode* pFirst, const void* pData);

SetNode*     Set_GetNode        (const Set*, int index) throws(index);
void*        Set_GetData        (const Set*, int index) throws(index);
int          Set_Find           (const Set*, int start, const void* pData) throws(index);

#ifdef __cplusplus
}
#endif

#endif
