#include "WimpLib:StrCol.h"

#include <stdlib.h>
#include <string.h>

#include "WimpLib:mem.h"
#include "WimpLib:std.h"
#include "WimpLib:OrderedSet.h"
#include "WimpLib:Utils.h"

int StrCol_Match(const void* a, const void* b)
{
	int len = strlen(a);
	int val = String_Collate(3, a, b, len);

	return val;
}

static int Str_Compare(const void* a, const void* b)
{
	int val = String_Collate(3, a, b, -1);

	if (!val) val = String_Collate(0, a, b, -1);

	return val;
}

static void* throw_Str_Alloc(void* pHandle, const void* p)
{
	IGNORE(pHandle);
	return throw_mem_allocstring(p);
}

static void Str_Delete(void* pHandle, void* p)
{
	IGNORE(pHandle);
	mem_free(p);
}

static const OrderedSetVPtr SetVPtr =
{
	  throw_Str_Alloc
	, Str_Delete
	, Str_Compare
};

StrCol* throw_New_StrCol(void)
{
	return New_OrderedSet(NULL, &SetVPtr);
}

void Delete_StrCol(StrCol* This)
{
	Delete_OrderedSet(This);
}

const char* throw_StrCol_Add(StrCol* This, const char* pstring)
{
	if (!pstring || !*pstring)
		return &nil;

	return (const char*) OrderedSet_GetNodeData(This, OrderedSet_Add(This, pstring));
}

void StrCol_Remove(StrCol* This, const char* pstring)
{
	if (!pstring || !*pstring)
		return;

	OrderedNode* pNode = OrderedSet_FindNode(This, pstring);
	if (pNode) OrderedSet_RemoveNode(This, pNode);
}

bool throw_StrCol_Set(StrCol* This, const char** ppdest, const char* pstring)
{
	pstring = throw_StrCol_Add(This, pstring);
	bool b = (*ppdest != pstring);
	StrCol_Remove(This, *ppdest);
	*ppdest = pstring;

	return b;
}
