#include <iostream.h>
#include <fstream.h>
#include <string.h>

/* Lab 6 Part 3 CIS 280 Jonathan LaZor
INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
1

Enter data to add:
Title: stuff
Playing Time: 1.00
Release Year: 2000
Price: 3.00

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
1

Enter data to add:
Title: cats
Playing Time: 2.00
Release Year: 2001
Price: 4.00

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
1

Enter data to add:
Title: gators
Playing Time: 3.00
Release Year: 2002
Price: 5.00

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
2

Enter name to update: stuff
Enter updated data:
Title: stuff
Playing Time: 1.50
Release Year: 2000
Price: 3.50

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
3

Enter name to delete: stuff

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
1

Enter data to add:
Title: stuff
Playing Time: 1.50
Release Year: 2000
Price: 3.00

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
4

Title: cats
Playing Time: 2
Release Year: 2001
Price: 4

Title: gators
Playing Time: 3
Release Year: 2002
Price: 5

Title: stuff
Playing Time: 1.5
Release Year: 2000
Price: 3


INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
5

Enter name to search: gators
Title: gators
Playing Time: 3
Release Year: 2002
Price: 5

INT LIST MENU
1. Add
2. Update
3. Delete
4. Display
5. Search
6. Quit
*/

template <class T>
struct Node {
	T data;
	Node<T>* next;
	Node();
	Node(T i);
};

template <class T>
class List {
	Node<T>* head;
public:
	List();
	~List();
	void append(T i);
	void insert(T i);
	T* search(const char* const i);
	void del(const char* const i);
	void display();
	void save();
	void load();
	int operator++();
};

class VideoTape {
	char name[80];
	double playingTime;
	int releaseYear;
	double price;
public:
	VideoTape();
	operator int();
	int operator==(const char* const s);
	int operator<(VideoTape& v);
	int operator==(VideoTape& v);
	friend ostream& operator<<(ostream& out, VideoTape& v);
	friend istream& operator>>(istream& in, VideoTape& v);
	friend ofstream& operator<<(ofstream& outf, VideoTape& v);
	friend ifstream& operator>>(ifstream& inf, VideoTape& v);
};

template <class T>
Node<T>::Node() : data(0), next(NULL) {}

template <class T>
Node<T>::Node(T i) : data(i), next(NULL) {}

template <class T>
List<T>::List() : head(NULL) {load();}

template <class T>
List<T>::~List() {
	Node<T>* current, *loop = head;
	while(loop) {
		current = loop;
		loop = loop->next;
		// cout << "Deleting " << current->data << "\n";
		delete current;
	}
}

template <class T>
void List<T>::append(T i) {
	Node<T>* tail = head;
	while(tail) //find tail (free node)
		tail = tail->next;
	tail = new Node<T>(i);
}

template <class T>
void List<T>::insert(T i) {
	Node<T>* previous = NULL, *current = head, *newNode = new Node<T>(i);
	if(!head) {
		head = newNode;
		return;
	}
	while(current && current->data < i) { //find first node>i or tail
		previous = current;
		current = current->next;
	}
	if(previous) { //if while loop processed
		if(current && current->data == i) {
			cout << "Entry already in list\n";
			return;
		}
		previous->next = newNode;
		newNode->next = current;
	}
	else { //else current = head (there's only 1 node in list)
		if(head->data == i) {
			cout << "Entry already in list\n";
			return;
		}
		if(head->data < i)
			head->next = newNode;
		else {
			previous = head;
			head = newNode;
			head->next = previous;
		}
	}
}

template <class T>
T* List<T>::search(const char* const i) {
	Node<T>* current = head;
	while(current) { //loop all
		if(current->data == i)
			return &(current->data);
		current = current->next;
	}
	return NULL;
}

template <class T>
void List<T>::del(const char* const i) {
	Node<T>* previous = NULL, *current = head;
	while(current) { //loop all
		if(current->data == i) {
			if(previous) //loop ran at least once (head doesn't match)
				previous->next = current->next;
			else head = current->next;
			delete current;
			return;
		}
		previous = current;
		current = current->next;
	}
	cout << "Entry not found.\n";
}

template <class T>
void List<T>::display() {
	Node<T>* current = head;
	while(current) {
		cout << current -> data << endl;
		current = current -> next;
	}
}

template <class T>
void List<T>::save() {
	ofstream outFile; outFile.open("list.dat");
	Node<T>* current = head;
	while(current) {
		outFile << current->data << '\n';
		current = current->next;
	}
	outFile << flush;
	outFile.close();
}

template <class T>
void List<T>::load() {
	ifstream inFile; inFile.open("list.dat");
	T data;
	while(!inFile.eof()) {
		if(data) insert(data);
		inFile >> data;
	}
	inFile.close();
}

template <class T>
int List<T>::operator++() {
	int i;
	char s[80];
	T t;
	T* ptr;
	cout << "INT LIST MENU\n1. Add\n2. Update\n3. Delete\n"
		<< "4. Display\n5. Search\n6. Quit\n";
	cin >> i;
	cout << "\n";
	switch(i) {
	case 1:
		cout << "Enter data to add: ";
		cin >> t;
		insert(t);
		break;
	case 2:
		cout << "Enter name to update: ";
		cin >> s;
		ptr = search(s);
		if(!ptr) cout << "Not found";
		else {
			cout << "Enter updated data: ";
			cin >> t;
			*ptr = t;
		}
		break;
	case 3:
		cout << "Enter name to delete: ";
		cin >> s;
		del(s);
		break;
	case 4:
		display();
		break;
	case 5:
		cout << "Enter name to search: ";
		cin >> s;
		ptr = search(s);
		if(!ptr) cout << "Not found";
		else cout << *ptr;
		break;
	case 6:
		save();
		return 0;
	default:
		break;
	}
	cout << "\n";
	return 1;
}

VideoTape::VideoTape() {
	strcpy(name, "0");
	playingTime = 0;
	releaseYear = 0;
	price = 0;
}

VideoTape::operator int() {
	if(strlen(name) < 1) return 0;
	if(playingTime < .01) return 0;
	if(!releaseYear) return 0;
	if(price < 0) return 0;
	return 1;
}

int VideoTape::operator==(const char* const s) {
	return (strcmp(name, s) == 0);
}

int VideoTape::operator<(VideoTape& v) {
	return strcmp(name, v.name);
}

int VideoTape::operator==(VideoTape& v) {
	return (strcmp(name, v.name) == 0);
}

ostream& operator<<(ostream& out, VideoTape& v) {
	return out << "Title: " << v.name << "\nPlaying Time: " << v.playingTime
		<< "\nRelease Year: " << v.releaseYear << "\nPrice: " << v.price << '\n';
}

istream& operator>>(istream& in, VideoTape& v) {
	cout << "\nTitle: ";
	in >> v.name;
	cout << "Playing Time: ";
	in >> v.playingTime;
	cout << "Release Year: ";
	in >> v.releaseYear;
	cout << "Price: ";
	return in >> v.price;
}

ofstream& operator<<(ofstream& outf, VideoTape& v) {
	// cout << "Writing Tape\n";
	outf << v.name << '\n' << v.playingTime << ' ' << v.releaseYear << ' ' << v.price;
	return outf;
}

ifstream& operator>>(ifstream& inf, VideoTape& v) {
	//inf.getline(v.name, 79); if(inf.eof()) return inf;
	inf >> v.name >> v.playingTime >> v.releaseYear >> v.price;
	// cout << "Reading Tape\n";
	return inf;
}

int main() {
	List<VideoTape> list;

	while(++list);

	return 1;
}