// 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.

///////////////////////////////////////////////////////////////////////////////

// PersonInfo.h  a collection of smart structs holding person information

///////////////////////////////////////////////////////////////////////////////

#ifndef PERSONINFO_H_
#define PERSONINFO_H_

#include "StringList.h"


// NameInfo is a simple struct for holding the last name, first name, and
// nickname of a person and the name of the person's company or business.

struct NameInfo {

	string LastName;
	string FirstName;
	string NickName;
	string Business;


	NameInfo& Set (
		const string& last,
		const string& first,
		const string& nick,
		const string& business
	)	{

		LastName  = last;
		FirstName = first;
		NickName  = nick;
		Business  = business;

		return *this;
	};

	void Get(string& last, string& first, string& nick, string& business) const {
		last     = LastName;
		first    = FirstName;
		nick     = NickName;
		business = Business;
	};


	NameInfo() {};

	NameInfo (
		const string& last,
		const string& first,
		const string& nick,
		const string& business
	)	
		{ Set(last, first, nick, business); };


	// Reading reads the name fields
	// Reading returns the count of fields that are non-empty

	int Reading() {
		if (! Confirm("\nEnter Name Info?", true)) return 0;

		int count = 0;

		if (ReadingString("Last Name:  ", LastName))  count++;
		if (ReadingString("First Name: ", FirstName)) count++;
		if (ReadingString("Nick Name:  ", NickName))  count++;
		if (ReadingString("Business:   ", Business))  count++;

		return count;
	};


	// Print prints the fields that are non-empty

	void Print(ostream& os = cout) const {
		// see if any fields have data

		int count = LastName.length();
		count += FirstName.length();
		count += NickName.length();
		count += Business.length();
		
		// print if there is data

		if (count) {
			if (LastName.length())
				os << "Last Name:  " << LastName  << endl;

			if (FirstName.length())
				os << "First Name: " << FirstName << endl;

			if (NickName.length())
				os << "Nick Name:  " << NickName  << endl;

			if (Business.length())
				os << "Business:   " << Business  << endl;

			os << endl;
		}
	};


	// Clear makes all data empty

	void Clear() {
		LastName  = "";
		FirstName = "";
		NickName  = "";
		Business  = "";
	};

}; // NameInfo


// Location collects information about one place at which a person may be located

struct Location {

	StringList Address;		// List of text lines in the location address
	StringList Phone;		// List of phone numbers at the location
	StringList Fax;			// List of fax   numbers at the location


	// Reading reads the location data
	// Reading returns the count of strings read

	int Reading() {
		if (! Confirm("\nEnter Location Info?", true)) return 0;

		int count = 0;

		count += Address.Reading("  Address:  ");
		count += Phone.Reading  ("    Phone:  ");
		count += Fax.Reading    ("      Fax:  ");

		return count;
	};


	// Print prints the relevant information

	void Print(ostream& os = cout) const {
		if (Address.ValidSize() + Phone.ValidSize() + Fax.ValidSize()) {
			Address.Print(os, "  Address:  ");
			Phone.Print  (os, "    Phone:  ");
			Fax.Print    (os, "      Fax:  ");
			os << endl;
		}
	};


	// Clear marks all data as invalid
	// The data is not actually physically erased

	void Clear() {
		Address.ValidateNone();
		Phone.ValidateNone();
		Fax.ValidateNone();
	};
}; // Location


// LocationList collects an array of Location information

struct LocationList : public Array<Location> {

	LocationList(int size = 1) : Array<Location>(size) { };


	// Reading reads zero or more Location's and appends them to the list
	// Reading returns the count of Location's read

	int Reading() {
		int count = 0;

		Location L;

		while (L.Reading()) {
			Append(L);
			L.Clear();
			count++;
		}

		return count;
	};


	// Print prints all Location's in the list

	void Print(ostream& os = cout) const {
		int i;
		int size = ValidSize();

		for (i = 0; i < size; i++)
			FastAccess(i).Print(os);
	};


	// Clear marks all data as invalid
	// The data is not actually physically erased

	void Clear() { ValidateNone(); };

}; // LocationList


struct PersonInfo {

	NameInfo     Name;
	LocationList Info;

	// Reading reads the Name and the Location Info
	// If non-trivial Name information is read
	//     Location Info is also read
	//     Return is true

	bool Reading() {
		Clear();

		if (Name.Reading()) {
			Info.Reading();
			return true;
		}
		else
			return false;
	};


	// Print prints the Name and Info data

	void Print(ostream& os = cout) const {
		Name.Print(os);
		Info.Print(os);
	};


	// Clear makes information empty or invalid

	void Clear() {
		Name.Clear();
		Info.Clear();
	};

}; // PersonInfo


// PersonInfoList collects an array of PersonInfo information

struct PersonInfoList : public Array<PersonInfo> {

	PersonInfoList(int size = 1) : Array<PersonInfo>(size) { };


	// Reading reads zero or more PersonInfo's and appends them to the list
	// Reading returns the count of PersonInfo's read

	int Reading() {
		int count = 0;

		PersonInfo P;

		while (P.Reading()) {
			Append(P);
			P.Clear();
			count++;
		}

		return count;
	};


	// Print prints all PersonInfo's in the list

	void Print(ostream& os = cout) const {
		int i;
		int size = ValidSize();

		for (i = 0; i < size; i++)
			FastAccess(i).Print(os);
	};


	// Clear marks all data as invalid
	// The data is not actually physically erased

	void Clear() { ValidateNone(); };

}; // PersonInfoList


#endif // PERSONINFO_H_
