#include <v_lib.h>
#include "iset.h"
#include "util.h"

iset_p isetAlloc(ISET_LIST_TYPE max_elems)
{
	iset_p set = (iset_p)memAllocZ(sizeof(iset_t));
	set->max_elems = max_elems;
	set->in = (ISET_FLAG_TYPE*)memAllocZ(max_elems * sizeof(ISET_FLAG_TYPE));
	set->list = (ISET_LIST_TYPE*)memAllocZ(max_elems * sizeof(ISET_LIST_TYPE));
	return set;
}

iset_p *isetsAlloc(ISET_LIST_TYPE num_isets,ISET_LIST_TYPE max_elems)
{
	ISET_LIST_TYPE i;
	iset_p *sets = (iset_p*)memAllocZ(num_isets * sizeof(iset_p));
	for(i = 0;i < num_isets;i++)
		sets[i] = isetAlloc(max_elems);
	return sets;
}

void isetFree(iset_p set)
{
	memFree(set->in);
	memFree(set->list);
	memFree(set);
}

void isetsFree(iset_p *sets,ISET_LIST_TYPE num_isets)
{
	ISET_LIST_TYPE i;
	for(i = 0;i < num_isets;i++)
		isetFree(sets[i]);
	memFree(sets);
}


void isetClear(iset_p set)
{
	memZero(set->in, set->max_elems * sizeof(ISET_FLAG_TYPE));
	memZero(set->list, set->max_elems * sizeof(ISET_LIST_TYPE));
	set->num_elems = 0;
}

void isetsClear(iset_p *sets,ISET_LIST_TYPE num_isets)
{
	ISET_LIST_TYPE i;
	for(i = 0;i < num_isets;i++)
		isetClear(sets[i]);
}

void isetAdd(iset_p set,ISET_LIST_TYPE elem_n)
{
	V_ASSERT(set->max_elems > elem_n);
	if(set->in[elem_n])
		return;
	set->in[elem_n] = 1;
	set->num_elems++;
}

void isetDel(iset_p set,ISET_LIST_TYPE elem)
{
	if(!set->in[elem])
		return;
	set->in[elem] = 0;
	set->num_elems--;
}

vboolean isetGetNext(iset_p set,ISET_LIST_TYPE *ret_val)
{
	ISET_LIST_TYPE i;
	if(!set->num_elems)
		return false;
	for(i = 0;!set->in[i];i++);
	*ret_val = i;
	return true;
}

void isetUpdateList(iset_p set)
{
	ISET_LIST_TYPE i, count;
	for(i = count = 0;count < set->num_elems;i++)
	{
		if(set->in[i])
			set->list[count++] = i;
	}
}

void isetPrintList(iset_p set)
{
	ISET_LIST_TYPE i;
	if(!set || !set->num_elems)
	{
		conPuts("empty\n");
		return;
	}
	conPrintf("num_elems%s%u%selems", CSV_COMMA, set->num_elems, CSV_COMMA);
	for(i = 0;i < set->num_elems;i++)
		conPrintf("%s%u", CSV_COMMA, set->list[i]);
	conPuts("\n");
}
