#include "cList.h"

template<class T>cList<T>::cList(){
	Head = Tail = This = NULL;
	Count = 0;
}

template<class T>cList<T>::~cList(){
	Clear();
}

template<class T>void cList<T>::Clear(){
	sListNode *Temp;

	while(Head){
		Temp = Head;
		Head = Head->Right;
		delete Temp;
	}
	Tail = This = NULL;
	Count = 0;
}

template<class T>bool cList<T>::IsEmpty(){
	return Head == NULL;
}

template<class T>int cList<T>::GetCount(){
	return Count;
}

/////////////////////////////////////////////// Access
template<class T>bool cList<T>::SetSelect(){
	This = Head;
	if(This) return true;
	return false;
}

template<class T>bool cList<T>::SelectPrev(){
	if(This){
		This = This->Left;
		if(This) return true;
	}
	return false;
}

template<class T>bool cList<T>::SelectNext(){
	if(This){
		This = This->Right;
		if(This) return true;
	}
	return false;
}

template<class T>void cList<T>::DeleteThis(){
	sListNode *Left, *Right;

	if(!This) return;

	Left = This->Left;
	Right = This->Right;

	if(Head == This) Head = Right;
	if(This == Tail) Tail = Left;
	if(Left) Left->Right = Right;
	if(Right) Right->Left = Left;
	delete This;

	This = Right;
	Count --;
}

template<class T>void cList<T>::Insert(T Data){
// Insert new data into this position of the list
// If this pointer is null add the data to tail position
	sListNode *Temp, *Left;

	if(This){
		Temp = new sListNode;
		Temp->Data = Data;

		Left = This->Left;
		if(Left) Left->Right = Temp;
		This->Left = Temp;
		Temp->Left = Left;
		Temp->Right = This;
		if(Head == This) Head = Temp;
		Count ++;
	}else{
		Add(pData);
	}
	Count ++;
}

template<class T>void cList<T>::Delete(T Data){
	if(SetSelect()) do{
		if(This->Data == Data){
			DeleteThis();
			return;
		}
	} while(SelectNext());
}

template<class T>void cList<T>::InsertList(cList *List){
	sListNode *Temp;
	T Data;

	Temp = List.This;

	for(List.SetSelect(); List.Get(&Data); List.SelectNext()){
		Insert(&Data);
		Count ++;
	}

	List.This = Temp;
}

template<class T>void cList<T>::Add(T Data){
// add the data at tail position
	sListNode *Temp;

	Temp = new sListNode;
	Temp->Data = Data;

	if(Tail){
		Tail->Right = Temp;
		Temp->Left = Tail;
		Temp->Right = NULL;
		Tail = Temp;
	}else{
		Temp->Left = NULL;
		Temp->Right = NULL;
		Head = This = Tail = Temp;
	}
	Count ++;
}

template<class T>bool cList<T>::Get(T *pData){
	if(!This) return false;

	*pData = This->Data;
	return true;
}
