
//-----------------------------------------------------------------
//
//  linked_l.C
//
//  Defines the LinkedList class 
//
//  Items included in this file:
//
//	Linked List class
//		constructor
//		destructor
//		InsertAtTail
//		TotalNodes
//		Print (to stdout)
//		Exists
//		GetNode
//		Start
//		NextNode
//		Print (to file)
//
//-----------------------------------------------------------------

#include "drgen.h"

//-------------------------------------------------------------------
// A Generic LINKED-LIST.  Objects of any class derived from
// `BaseClass' can be used to form a linked list.
// Even objects of two or more different classes can be in the
// same list provided the classes have been derived from `BaseClass'.

LinkedList::LinkedList() {
	Total = 0;
	head = new BaseClass;     // get a dummy node
	if (head == NULL)
		cerr << "Linked List constructor: Memory allocation error!\n";
	head->next = NULL;
	tail = head;
}

LinkedList::~LinkedList() {
	BaseClass *walk, *prev;

	prev = head;
	walk = head -> next;
	while (walk != NULL) {
		delete prev;
		prev = walk;
		walk = walk -> next;
	}
	delete prev;
}


void LinkedList::InsertAtTail (BaseClass *p) {
	tail->next = p;
	tail = p;
	tail->next = NULL;
	Total++;
}


int LinkedList::TotalNodes () {
	return Total;
}


void LinkedList::Print() {
	BaseClass *walk;

	walk = head -> next;    // skip dummy node
	while (walk != NULL) {
		walk -> Print();   // print is specific to class used
		walk = walk -> next;
	}
}


int LinkedList::Exists(BaseClass *p) {
	BaseClass *walk;

	walk = head -> next;    // skip dummy node
	while (walk != NULL) {
		if (walk->Compare(p))
			return 1;  // compare is specific to class used
		walk = walk->next;
	}
	return 0;
}


// returns a linked list node which matches node `p'
BaseClass *LinkedList::GetNode(BaseClass *p) {
	BaseClass *walk;

	walk = head -> next;    // skip dummy node
	while (walk != NULL) {   // compare is specific to class used
		if (walk->Compare(p))
			return walk;
		walk = walk->next;
	}
	return NULL;
}

void LinkedList::Start() {
	walk = head;
}

BaseClass *LinkedList::NextNode() {
	if (walk != NULL)
		walk = walk -> next;
	return walk;
}

void LinkedList::Print(ofstream &out_stream) {
	BaseClass *walk;

	walk = head -> next;    // skip dummy node
	while (walk != NULL) {
		walk -> Print(out_stream);   // print is specific to class used
		walk = walk -> next;
	}
}
