/* Link list functions */
#include "gameinc.h"

/* Create a linklist head */
p_LinkListHead LinkList_Create(void)
{
	p_LinkListHead this;

	if ( (this = calloc(1,sizeof (struct s_LinkListHead)))==NULL)
	{
		fatal("out of memory for linklist header!");
	}

	return this;
}


/* Destroy an entire link list including all children etc */
void LinkList_Destroy(p_LinkListHead this)
{
	p_LinkList node,tmp;
	int nument;

	if (this == NULL)
		return;

	nument=this->entries;
	node=this->start;

	while (node != NULL)
	{
		tmp=node->next;
		free(node);
		node=tmp;
		nument--;
	}

	if (nument != 0)
	{
		fatal("Number of entries in linklist doesn't match physical entries!!");
	}

	free(this);
}


p_LinkList LinkList_Add(p_LinkListHead this,void * block)
{
	p_LinkList node, nodeend;

	if ( (node=calloc(1,sizeof(struct s_LinkList))) ==NULL)
	{
		fatal("out of memory for linklist node!");
	}

	nodeend=this->end;

	if (nodeend != NULL)
	{
		if (nodeend->next != NULL)
			fatal("LinkList seems to be broken!!");

		nodeend->next=node;
	}

	if (this->start == NULL)
		this->start = node;

	node->prev=nodeend;
	this->end=node;
	node->data=block;
	node->head=this;
	this->entries++;

	return node;
}


void LinkList_Remove(p_LinkList node)
{
	p_LinkList nodenext=NULL,nodeprev=NULL;
	p_LinkListHead head;

	nodenext=node->next;
	nodeprev=node->prev;

	head=node->head;
	head->entries--;

	if (node == head->end)
		head->end = nodeprev;
	if (node == head->start)
		head->start = nodenext;

	if (nodenext != NULL)
		nodenext->prev=nodeprev;
	if (nodeprev != NULL)
		nodeprev->next=nodenext;

	free(node);
}

