/* 
  LinkedList.cpp - Library for creating a linked list data structure. 
  Created by Alex Abreu, March 23, 2008. 
*/ 
 
extern "C" { 
  #include <stdlib.h> 
  #include <string.h> 
  #include <inttypes.h> 
} 
 
#include "WProgram.h" 
#include "HardwareSerial.h" 
#include "LinkedList.h" 
 
LinkedList::LinkedList() { 
  CreateList(); 
} 
 
void LinkedList::CreateList() { 
  pList = (LIST*)malloc(sizeof(LIST)); 
  pList->pHead = pList->pTail = NULL; 
} 
 
LinkedList::NODE* LinkedList::NewNode() { 
  NODE* pNode; 
  pNode = (NODE*)malloc(sizeof(NODE)); 
  return pNode; 
} 
 
LinkedList::NODE* LinkedList::GetHead() { 
  return pList->pHead; 
} 
 
LinkedList::NODE* LinkedList::GetTail() { 
  return pList->pTail; 
} 
 
LinkedList::NODE* LinkedList::FindNode(int address) {  
  for (NODE* pNode = pList->pTail; pNode != NULL; pNode = pNode->pPrev) { 
     if (pNode->address == address) { 
     return pNode; 
     } 
  } 
  return NULL; 
} 
 
void LinkedList::AppendNode(NODE* pNode) { 
 pNode->pPrev = NULL; 
 pNode->pNext = NULL; 
 if (pList->pHead == NULL) { 
    pNode->pPrev = NULL; 
    pList->pHead = pNode; 
  } 
  else { 
    if (pList->pHead->pNext == NULL) { 
     pList->pHead->pNext = pNode; 
    } 
    pList->pTail->pNext = pNode; 
    pNode->pPrev = pList->pTail; 
  } 
  pNode->pNext = NULL; 
  pList->pTail = pNode; 
} 
 
void LinkedList::RemoveNode(NODE* pNode) { 
  if (pNode->pPrev == NULL) { 
    pList->pHead = pNode->pNext; 
    pNode->pNext->pPrev = NULL; 
  } 
  else if (pNode->pNext == NULL) { 
    pList->pTail = pNode->pPrev; 
    pNode->pPrev->pNext = NULL; 
  } 
  else { 
    pNode->pPrev->pNext = pNode->pNext; 
    pNode->pNext->pPrev = pNode->pPrev; 
  } 
  pNode = NULL; 
  free(pNode); 
} 
 
bool LinkedList::RemoveNode(int address) { 
  for (NODE* pNode = pList->pTail; pNode != NULL; pNode = pNode->pPrev) { 
     if (pNode->address == address) { 
     RemoveNode(pNode); 
     return true; 
     } 
  } 
  return false; 
} 
 
 
void LinkedList::DeleteAllNodes() { 
  for (NODE* pNode = pList->pTail; pNode != NULL; pNode = pNode->pPrev) { 
    RemoveNode(pNode); 
  } 
  pList = NULL; 
  free(pList); 
} 
 
void LinkedList::DisplayAllNodes() { 
  for (NODE* pNode = pList->pHead; pNode != NULL; pNode = pNode->pNext) { 
     if (pNode == pList->pHead) { 
      Serial.print("HEAD: "); 
     } 
     else if (pNode == pList->pTail) { 
      Serial.print("TAIL: "); 
     } 
     else { 
      Serial.print("Node: "); 
     }     
     Serial.print(pNode->address); 
     Serial.print(" Prev: "); 
     if (pNode->pPrev != NULL) {     
       Serial.print(pNode->pPrev->address); 
     } 
     else { 
      Serial.print(" "); 
     } 
     Serial.print(" Next: "); 
     if (pNode->pNext != NULL) {     
       Serial.println(pNode->pNext->address); 
     } 
     else { 
      Serial.println(""); 
     } 
   } 
} 
 
void LinkedList::TestList() { 
  for (int i = 1; i <= 10; i++) { 
     NODE* pNode; 
     pNode = (NODE*)malloc(sizeof(NODE)); 
     pNode->address = i; 
     AppendNode(pNode); 
  } 
  DisplayAllNodes(); 
  DeleteAllNodes(); 
  DisplayAllNodes();  
} 

