// Copyright 2000
// College of Computer Science
// Northeastern University Boston MA 02115

// This software may be used for educational purposes as long as this copyright
// notice is retained at the top of all files

// Should this software be modified, the words "Modified from Original" must be
// included as a comment below this notice

// All publication rights are retained.  This software or its documentation may
// not be published in any media either in whole or in part.

///////////////////////////////////////////////////////////////////////////////

// Simple Linked Lists Lab Part 2: Checks in date order

///////////////////////////////////////////////////////////////////////////////

// The standard include files that include traditional C and C++ headers and
// many other Core Tools headers ... see CHeaders.h for additional details

#include "IOTools.h"
#include "Graphics.h"
#include "Random.h"
#include "FileTool.h"

// Enter project specific include files here as well as classes and functions
// that you choose to define in the main shell rather than in separate files


class Check{

// ********* ENTER MEMBER DATA DEFINITIONS ****************



	// simple function used in FromString

	static bool IsSeparator(char c) {
		return (c == ' ') || (c == ',');
	};

public:
// ************ DEFINE TWO CONSTRUCTORS *******************



// ************ DEFINE TWO SET FUNCTIONS *******************



// * DEFINE THREE FUNCTIONS THAT RETURN MEMBER DATA VALUES *



// Function that prints one check - no endl at the end!
	void Print(ostream& os = cout) const {
		os << left  << setw(10) << date;
		os << right << setw(6)  << number;
		os << fixed << setw(10) << setprecision(2) << amount;
	};

// FromString reads check information from a string
//
// Assumes format:
//    date number amount
//
// The date field may not contain blanks or commas
//
// The date may have many forms such as:
//    mm/dd/yy
//    mm-dd-yy

	Check& FromString(const string&	source) {
		date = "";
		number = 0;
		amount = 0;

		int length = source.length();
		int start  = 0;
		int finis  = 0;
		int error  = 0;

		// read date

		// skip separators: blank and comma
		while ((start < length) &&  IsSeparator(source[start]))
			start++;

		// assume date portion is first non-blank portion of source
		// and assume that no blanks occur within date

		finis = start;

		while ((finis < length) && !IsSeparator(source[finis]))
			finis++;

		date = source.substr(start, finis - start);

		// read number
		start = finis;

		// skip separators: blank and comma
		while ((start < length) &&  IsSeparator(source[start]))
			start++;

		number = StringToInt(source, start, finis, error);

		if (error) {
			number = 0;
			return *this;
		}

		// read amount
		start = finis;

		// skip separators: blank and comma
		while ((start < length) &&  IsSeparator(source[start]))
			start++;

		amount = StringToDouble(source, start, finis, error);

		if (error) {
			amount = 0;
			return *this;
		}

		return *this;
	};

// *********** DEFINE THE TWO OPERATORS: < AND >= **************



}; // Check


struct Node {
// *********** MODIFY THE CODE TO USE Check data; **************
	
	int	data;
	Node*	next;

	// default and full set of arguments constructor

	Node(int Data =0, Node* Next = 0): data(Data), next(Next) { };

}; // Node


// simple singly linked list with head and tail pointer
// supports traversal through an internal iterator

class List {

// ***************** COPY CLASS LIST FROM PART 1 *****************
// ************* MODIFY FUNCTION HEADERS AS NEEDED ***************
	


}; // List

// This function prints all checks in a given list
// It uses the functions SetFirst and GettingNext to traverse the list
void TestPrint(List& L, double balance, const string& Ordering) {

	int    count = 0;
	Check  check;

	cout << "Printing list of checks in " << Ordering << " order" << endl;
	cout << endl;

	L.SetFirst();					// position current at the beginning

	while (L.GettingNext(check)) {	// repeat until end of list is reached
		count++;

		check.Print();				// print the check
		balance -= check.Amount();	// find the remaining balance
		// notice the formatting directives: print remaining balance
		cout << right << setw(10) << setprecision(2) << balance << endl;

	}

	cout << endl;

	cout << "There were " << count << " checks paid." << endl;
	cout << endl;

	PressReturn();

} // TestPrint


// This function generates random default data for one Check object
// It is a lazy man's trick to avoid having to type in test user data
// Use this data as defaults in request's for user input
void GetSampleData(string& date, int& checknum, double& amount){

	amount = RandomLong(2000,9900)/100.00;	// amount from 20.00 to 99.00
	checknum = RandomLong(101, 130);		// check number 101 to 130

	date = "01/02/00";						// set initial date Jan 2 2000
	date[3] = '0' + RandomLong(0,2);		// modify 1st digit of day
	date[4] = '0' + RandomLong(1,9);		// modify 2nd digit of day

} // GetSampleData



void TestClassCheck(){
// **************** DEFINE THE FUNCTION **********************




	PressReturn("Test of class Check completed");

} // TestClassCheck


// Check input from a file
// Function FromString is used to convert one line of input
// into the three member data fields
void FileTest(){
	PressReturn("Testing the file input");

// **************** DEFINE THE FUNCTION **********************




}; // FileTest


int main(int argc, char* argv[]) {

	// Use the following line if you choose NOT to open any graphics windows

	InitializeConsole();

/*
	// Build graphics window 0
	GraphicsWindow GW0(300, 300);

	// Move the console below graphics window 0
	ConsolePlaceBelow(0);

	// Give the console the focus for user interaction

	MakeConsoleForeground();
*/

//////////

	// Enter the main program here
	SetRandomSeed();

	TestClassCheck();

	cout << "Testing the class List with user input" <<endl;
	cout << "We will request 5 sets of data" << endl << endl;

	string source;
	Check  check;			// check object

	double balance;			// account balance used in testing

	List L1;				// For head insert
	List L2;				// For tail insert
	List L3;				// For ordered insert

	string date;			// date fron user input
	int num;				// check number from user input
	double amount;			// check amount from user input
	int i;

	// variables used to generate default input data for easy testing
	int defnum;				// default check number
	double defamount;		// default check amount
	string defdate;			// default date

	// in each loop iteration:
	//		generate new default input values
	//		request user input
	//		initialize check object with given data
	//		insert check into three lists:
	//			L1: head insert
	//			L2: tail insert
	//			L3: ordered insert
	for (i = 1; i <= 5; i++){
		GetSampleData(defdate, defnum, defamount);
		  
		RequestString("Date:", defdate, date);
		num = RequestInt("Check number:", defnum);
		amount = RequestDouble("Check amount:",defamount);

// ************* ADD CODE TO BUILD ONE CHECK OBJECT ******************



// ********* ADD CODE TO INSERT CHECK OBJECT INTO THREE LISTS ********
	


	} // end of for loop

// ******** ADD CODE FOR EACH LIST TO REQUEST INITIAL BALANCE ********
// ***** AND PRINT THE DATA IN EACH LIST USING PrintData FUNCTION ****




// ** ADD CODE TO REMOVE DATA FROM LIST L3 AND INSERT INTO LIST L4 ***

	
		
// ********* ADD CODE FOR LIST L4 TO REQUEST INITIAL BALANCE *********
// ****** AND PRINT THE DATA IN LIST L4 USING PrintData FUNCTION *****

	

	// Test the file input
	FileTest();


//////////

	// The lines below make sure that the graphics windows remain open just
	// before the program terminates

	PressReturn("\nThe main program is about to terminate\n");

	return 0;
}

