#include "Script.hpp"

extern HGOSHEAP gScriptHeap[];

gosScript_List::gosScript_List()
{
	length = 0;
	index = 0;
	head = 0;
	tail = 0;
	cur = 0;
}

void gosScript_List::Add(VARIABLE * addme, int type,int index)
{
	if (tail == 0)
	{
		// first item, set head and tail
		head = tail = (gosScript_ListItem *) gos_Malloc(sizeof(gosScript_ListItem), gScriptHeap[1] );
		head->pNext = 0;
		head->pPrev = 0;
		head->pListItemVar = addme;
		head->Index = index;
		head->Type = type;
	}
	else
	{
		// add to end of list
		tail->pNext = (gosScript_ListItem *) gos_Malloc(sizeof(gosScript_ListItem), gScriptHeap[1]);
		tail->pNext->pNext = 0;
		tail->pNext->pListItemVar = addme;
		tail->pNext->Index = index;
		tail->pNext->Type = type;
		tail->pNext->pPrev = tail;
		tail = tail->pNext;
	}
	length++;
}

bool gosScript_List::Del(VARIABLE * delme, int type, int index)
{
	gosScript_ListItem * itr =  head;
	gosScript_ListItem * prev =  NULL;

	if (cur->pListItemVar == delme)
		cur = cur->pNext;

	while(itr)
	{
		if ((itr->pListItemVar == delme) && (itr->Index == index) && (itr->Type == type) )
		{
			if (prev)
			{
				prev->pNext = itr->pNext;
				if (itr->pNext)
					itr->pNext->pPrev = prev;
				if (itr == head)
				{
					head = itr->pNext;
					if (itr->pNext)
						itr->pNext->pPrev = itr->pPrev;
				}
				if (itr == tail)
				{
					tail = prev;
				}
			}
			else
			{
				head = itr->pNext;
				itr->pNext->pPrev = 0;
			}
			length--;
			gos_Free(itr);
			return true;
		}
		prev = itr;
		itr = itr->pNext;
	}
	
	return false;
}

bool gosScript_List::Next()
{
	if (cur)
	{
		index++;
		cur = cur->pNext;
	}
	if (cur)
		return true;
	else
		return false;
}

bool gosScript_List::Prev()
{
	if (cur)
	{
		cur = cur->pPrev;
	}
	if (cur)
	{
		index--;
		return true;
	}
	else
		return false;
}

VARIABLE * gosScript_List::GetCurrent()
{
	if (cur)
		return cur->pListItemVar;
	else
		return 0;
}

int gosScript_List::GetCurrentType()
{
	if (cur)
	{
		return cur->Type;
	}
	else
		return 0;
}

int gosScript_List::GetCurrentIndex()
{
	if (cur)
	{
		return cur->Index;
	}
	else
		return 0;
}

void gosScript_List::Top()
{
	cur = head;
}

void gosScript_List::Bottom()
{
	cur = tail;
}

int gosScript_List::Length()
{
	return length;
}

int gosScript_List::Empty()
{
	gosScript_ListItem * itr =  head;
	gosScript_ListItem * next =  NULL;
	int count = 0;
	while(itr)
	{
		next = itr->pNext;
		gos_Free(itr);
		itr = next;
		count++;
	}
	length = 0;
	index = 0;
	head = 0;
	tail = 0;
	cur = 0;
	return count;
}



gosScript_List::~gosScript_List()
{
	// whack the linked list
	gosScript_ListItem * itr =  head;
	gosScript_ListItem * next =  NULL;
	while(itr)
	{
		next = itr->pNext;
		gos_Free(itr);
		itr = next;
	}
}