#include "mlist.h"
#include <string.h>

/////////////////// Constructor & Destructor /////////////////
cMList::cMList(int cursor_max)
{
	mEntryNode = NULL;
	mLastNode = NULL; 

	mCursorNodes = new (sListNode*)[cursor_max];
	memset(mCursorNodes, 0, sizeof(sListNode*)*cursor_max);
}

cMList::~cMList()
{
	delete mCursorNodes;

	sListNode* node = mEntryNode;
	sListNode* next_node;

	while(node != NULL) {
		next_node = node->mNextNode;
		delete node;
		node = next_node;
	}
}

/////////////////// Working Methods //////////////////////////
cMList::sListNode* cMList::get_node(int _index)
{
	sListNode* ret = NULL;
	
	int i = 0;
	sListNode* node = mEntryNode;
	while(node != NULL) {
		if(i == _index) {
			ret = node;
		}

		i++;
		node = node->mNextNode;
	}
	
	return ret;
}

cMList::sListNode* cMList::get_node(void* _contained_item)
{
	sListNode* ret = NULL;
	
	sListNode* node = mEntryNode;
	while(node != NULL) {
		if(node->mItem == _contained_item) {
			ret = node;
		}
		
		node = node->mNextNode;
	}

	return ret;
}

cMList::sListNode* cMList::get_last_node()
{
	sListNode* ret = NULL;

	sListNode* node = mEntryNode;
	while(node != NULL) {
		if(node->mNextNode == NULL) {
			ret = node;
		}
		
		node = node->mNextNode;
	}
	
	return ret;
}

int cMList::get_index(sListNode* _node)
{
	int ret = -1;

	int i = 0;
	sListNode*	node = mEntryNode;
	while(node != NULL) {
		if(node == _node) {
			ret = i;
		}

		i++;
		node = node->mNextNode;
	}
	
	return ret;
}

//////////////////////// Properties /////////////////////
void* cMList::GetWithIndex(int _index)
{
	void* ret = NULL;
	
	if(get_node(_index) != NULL) {
		ret = get_node(_index)->mItem;
	} else {
		mMsg("Return is NULL on cMList::Get(%d)", _index);
	}
	
	return ret;
}

int cMList::Count()
{
	int ret = -1;
	
	int i = 0;
	sListNode* node = mEntryNode;
	while(node != NULL) {
		i++;
		node = node->mNextNode;
	}
	ret = i;

	return ret;
}

int cMList::IndexOf(void* _item)
{
	int ret = -1;
	
	if(get_node(_item) != NULL) {
		ret = get_index(get_node(_item));
	}

	return ret;
}

///////////////////////////// Methods ///////////////////////
void cMList::Add(void* _item)
{
	sListNode* new_node = new sListNode;
	new_node->mItem = _item;
	
	if(mEntryNode == NULL) {
		mEntryNode = new_node;
	} else {
		mLastNode->mNextNode = new_node;
	}

	mLastNode = new_node;
}

void cMList::Remove(void* _item)
{
	sListNode*	remove_node = get_node(_item);

	if(remove_node == NULL) {	
	}
	else if(remove_node == mEntryNode && remove_node == mLastNode) {
		delete remove_node;
		mEntryNode = NULL;
		mLastNode = NULL;		
	}
	else if(remove_node == mEntryNode) {
		mEntryNode = mEntryNode->mNextNode;
		delete remove_node;
	}
	else if(remove_node == mLastNode) {
		sListNode* new_last_node = get_node(get_index(mLastNode) -1);
		delete mLastNode;

		new_last_node->mNextNode = NULL;
		mLastNode = new_last_node;
	}
	else {
		get_node(get_index(remove_node) -1)->mNextNode = remove_node->mNextNode;
		delete remove_node;
	}
}

/*
void cMList::Insert(int _index, void* _item)
{
	sListNode*	new_node = new sListNode;
	new_node->mItem = _item;
	new_node->mNextNode = get_node(_index);

	if(_index == 0) {
		mEntryNode = new_node;
	}
	else if((_index > 0) && (_index < Count())) {
		get_node(_index -1)->mNextNode = new_node;
	}
}

void cMList::Delete(int _index)
{
	if(Get(_index) != NULL) {
		Remove(Get(_index));
	}
}
*/

void cMList::Clear()
{
	sListNode* node = mEntryNode;
	sListNode* next_node;

	while(node != NULL) {
		next_node = node->mNextNode;
		delete node;
		node = next_node;
	}
	
	mEntryNode = NULL;
	mLastNode = NULL;
}
