// LinkedList.cpp: implementation of the CLinkedList class.
//
//////////////////////////////////////////////////////////////////////

#include "LinkedList.h"
#define NULL 0
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CLinkedList::CLinkedList()
{
	this->head = new sListNode;
	this->head->prev = NULL;
	this->head->next = NULL;
	this->tail = this->head;
	this->numItems = -1;
	this->lastSelectedItemIndex = -20;
	this->lastSelectedItem = NULL;
	//not sure why I need to append one,
	//but it makes it work...
	//this->AppendItem(NULL);
}

CLinkedList::~CLinkedList()
{
	while(this->numItems != -1)
		this->DeleteItem(0);
}

int CLinkedList::AppendItem(void *item)
{
	this->tail->next = new sListNode;
	tail->next->prev = tail;
	this->tail = this->tail->next;
	this->tail->next = NULL;
	this->tail->itemPointer = item;
	this->numItems++;
	return 0;
}

int CLinkedList::InsertItem(void *item)
{
	sListNode *temp;
	temp = head;
	head = new sListNode;
	head->next = temp;
	temp->prev = head;
	head->itemPointer = item;
	head->prev = NULL;
	this->numItems++;
	return 0;
}

void *CLinkedList::GetItem(int index)
{
	if((index > this->numItems) || (index < 0))
		return NULL;
    
	//optimize!! Linked lists are terribly slow at pulling stuff,
	//so optimize for sequential acccess
  if(this->lastSelectedItemIndex == (index - 1))
	{
		lastSelectedItemIndex = index;
		this->lastSelectedItem = lastSelectedItem->next;
   
    return lastSelectedItem->itemPointer;
	}
	else if(this->lastSelectedItemIndex == (index + 1))
	{
		lastSelectedItemIndex = index;
		this->lastSelectedItem = lastSelectedItem->prev;
		
    return lastSelectedItem->itemPointer;
	}
	
	sListNode *node = this->head;
	
	for(int i = 0; i <= index; i++)
	{
		node = node->next;
	}

	lastSelectedItemIndex = index;
	lastSelectedItem = node;

  if(node != NULL)
    return node->itemPointer;
  else
    return NULL;
}

int CLinkedList::DeleteItem(int index)
{
	sListNode *node = this->head;
	 
	for(int i = 0; i <= index; i++)
	{
		node = node->next;
		if(node == NULL)
             return 0;
	}

	if(node->next != NULL)
		node->next->prev = node->prev;
	if(node->prev != NULL)
	{
	 node->prev->next = node->next;
  }
    
    if(node == head)
     head = node->next;
     
    if(node == tail)
     tail = node->prev;
	
	if(lastSelectedItem == node)
	{
      lastSelectedItemIndex = -20;
	    lastSelectedItem == NULL;
  }
	
	delete node;
	
    this->numItems--;
	return 0;
}

int CLinkedList::GetNumItems()
{
	return this->numItems + 1;
}

