////////////////////////////////////////////////////////////////////////////////
// School of Computing, Universiti Teknologi Malaysia
// SECJ/SCSJ1023 - Programming Technique II
// Semester 2, 2020/2021
// Final Exam, Problem Solving
// Student's Name: Megat Irfan Zackry Bin Ismail
// Matric Number: A20EC0205
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>

#define DISC 15   // Discount rate 
#define SIZE 50   //The maximum number of purchases

using namespace std;

//----------------------------------
// The Address class is FULLY given
class Address
{
	private:
		string postcode, city ;

	public:
		void readAddress()
		{
			cout << "Address [postcode]: ";
			getline (cin, postcode);
			cout << "Address [city]: ";
			getline (cin, city);
		}

		void dispAddress()
		{
			cout << postcode << ", " << city;
		}
};

//----------------------------------
// The House class is PARTIALLY given
//TASK 1 (7 Marks)
//TODO: Complete the definition of the House class
class House
{
	protected:
		//Task 1(a): Define all the member variables [3 marks]
		string houseName;
		double price;
		

	public:
	
		Address address;
		
		//Complete default arguments constructor
		House (string houseName = 0, double price = 0)
		{
			this->houseName = houseName;
			this->price = price;
		}
		
		//Complete getName function
		string getName()
		{
			return houseName;
		}
		
		//Incomplete readInput function
		void readInput(string name)
		{
		//Task 1(b): Complete the definition of the readInput function [1 marks]
		houseName=name;
		
		}

		//Task 1(c)(i): Define the virtual displayDetails function [3 marks]
		virtual void displayDetails();


		//Task 1(b)(ii): Define the pure virtual calcPrice function [2 mark]
		virtual void calPrice() = 0;
};


//----------------------------------
//Bungalow class is PARTIALLY given

//TASK 2 (10 Marks)
//TODO: Complete the definition of the Bungalow class

//Task 2(a): Specify the Bungalow class as a child of the House class [1 mark]

class Bungalow : public House
{
			
	public:

		//Task 2(b): Define the constructor with arguments [2 marks]
		Bungalow(string n=0, double p=0): House(n, p){}


		//Task 2(c): Define the calcDisc function [2 marks]
		double calcDisc(){
			return DISC*price/100;
		}


		//Task 2(d): Define the calcPrice function [2 marks]
		double calcPrice(){
			int d = this->calcDisc();
			return price-d;
		}
		
		
		//Task 2(e): Define the displayDetails function [3 marks]
		//___________________________________
};


//----------------------------------
//Terrace class is PARTIALLY given

//TASK 3 (9 Marks)
//TODO: Complete the definition of the Terrace class

//Task 3(a): Specify the Terrace class as a child of the House class [1 mark]

class Terrace: public House
{
	private:

	public:

		//Task 3(b): Define the constructor with arguments [3 marks]
		Terrace( string n=0, double p=0): House(n, p){
		}


		//Task 3(c): Define the calcPrice function [2 marks]
		double calcPrice(){
			return price;
		}


		//Task 3(d): Define the displayDetails function [3 marks]
		//___________________________________
};

//----------------------------------
//Loan class is PARTIALLY given

//TASK 4 (7 Marks)
//TODO: Complete the definition of the Loan class
class Loan
{
	private:
		string bankName;
		double totLoan;
		
	public:
		//Task 4(a): Define the constructor with arguments [3 marks]
		Loan (string bn, double tl){
			bankName=bn;
			totLoan=tl;
		}
		
		//Task 4(b): Complete the getBname function [2 marks]
		string getBname(){
			return bankName;
		}
		
		//Task 4(b): Complete the getLoanVal function [2 marks]
		double getLoanVal(){
			return totLoan;
		}
};

//----------------------------------
// The Buyer class is PARTIALLY given
class Buyer
{
	//TASK 5 (19 Marks)
	//TODO: Complete the definition of the Buyer class

	private:
		//Task 5(a): Define all the member variables [4 marks]
		string name;
		double loanVal;
		int numTerrace, numBungalow;
		int numPurchase, qttyList[];
		House *purchaseList[SIZE];
		
	public:
		//Complete default constructor
		Buyer()
		{
			numTerrace = 0;
			numBungalow = 0;
			numPurchase = 0;
		}

		//Complete getName function
		string getName()
		{
			return name;
		}

		//Complete getDateTime function
		/*void getDateTime()
		{
			cout << " (";
			date.dispDate();
			cout << ", ";
			time.dispTime();
			cout << ")";
		}*/

		//Incomplete readInput function
		void readInput(string name)
		{
			//Task 4(b): Complete the definition of the readInput function [1 marks]
			this->name=name;
		}

		//Incomplete addPurchase function
		void addPurchase(House *p)
		{
			//Task 5(c): Complete the definition of the addPurchase function [5 marks]

			if (dynamic_cast <Bungalow *> (p)) //To check if p is an instance of Bungalow
			{
				numBungalow++;
			}
			else
			{
				numTerrace++;
			}
			purchaseList[numPurchase]=p;
			numPurchase++;
		}

		//Incomplete displayInfoBuyer function
		void displayInfoBuyer()
		{
			//Task 5(d): Complete the definition of the displayInfoBuyer function [1 marks]
			//___________________________________
		}

		//Incomplete displayInfoPurchase function
		void displayInfoPurchase()
		{
			double totalPurchase = 0, total;

			if (numPurchase == 0)
				cout << "\nNo puchase data!" << endl;
			else
			{
				cout << "\nNumber of All Purchase: " << numPurchase << endl
					 << "Number of Bungalow  : "   << numBungalow << endl
					 << "Number of Terrace   : "   << numTerrace << endl << endl;

				cout << left;
				cout << setw(4)  << "No"
					 << setw(40) << "Description"
					 << setw(20) << "Address"
					 << setw(16) << "Unit Price(RM)"
					 << setw(14) << "Discount(RM)"
					 << setw(10) << "Quantity"
					 << "Total(RM)" << endl;

				//Task 5(e): Complete the definition of the displayInfoBuyer function [7 marks]
				//___________________________________

				cout << "\nTotal price = RM" << totalPurchase
					 << endl << endl;
			}
		}
};

//----------------------------------
// The menu function is FULLY given
int menu()
{
	int task;

	cout << "========== Menu ==========" << endl
		 << "[1] Add Buyer" << endl
		 << "[2] Add House" << endl
		 << "[3] Add Purchases" << endl
		 << "[4] Display Purchases" << endl
		 << "[5] Exit" << endl
		 << "==========================" << endl
		 << "\nSelect task: ";

	cin >> task;
	cin.ignore();

	return task;
}

//----------------------------------
// The main function is PARTIALLY given
int main()
{
	//TASK 6 (37 Marks)
	//TODO: Complete the definition of the main function
	
	//Local variables and instances
	char ch, ans;
	int choice1=1; //Task chosen
	int choice2; //Buyer chosen
	int choice3; //House chosen
	int choice4; //Loan chosen
	double price;	
	string name, housename, type;
	int qtty, numBuyer = 0, numHouse = 0;

	Buyer buyerObj; //Buyer object
	House *housePtr; //House pointer
	Buyer buyerList[SIZE]; //Array of buyer objects
	House *houseList[SIZE]; //Array of house objects
	
	//Task 6(a): Create 3 Loan object with data provided in question [6 mark]
	Loan l1 ("Maybank",1000000.00);
	Loan l2 ("CIMB",1500000.00);
	Loan l3 ("Bank Islam",2000500.00);
	
	

	//The process will be repeated if user enter the value in range 1 to 4
	do
	{	//Task 6(b): Enter the task chosen [1 mark]
		choice1=menu();
		
		switch (choice1)
		{
			case 1:

				cout << "\n<<< Add Buyer >>>" << endl;

				//Task 6(b-i): Enter the details of buyer [2 mark]
				cout<<"Name: ";
				cin>>name;
				buyerObj.readInput(name);


				//Task 6(b-ii): Add the Buyer object into the Buyer array [2 mark]
				buyerList[numBuyer]=buyerObj;
				
				cout << "Do buyer take loan? (Y/N): ";
				cin >> ans;
				if (ans == 'Y'||ans == 'y')
				{
					cout << "\n--- All Loan Available ---" << endl;
					cout << "(1) Maybank : RM 1000000.00" << endl
						 << "(2) CIMB Bank : RM 1500000.00" << endl
						 << "(3) Bank Islam : RM 2000500.00" << endl << endl
						 << "Choice (1/2/3): " ;
					cin >> choice4; // To enter Loan chosen
					 
					switch (choice4)
					{
						//Task 6(b-iii): Complete Loan process of buyer choice [3 mark]
						/*case 1:
							
						case 2:
						
						case 3:*/
					}

				numBuyer++;
				break;
}
			case 2:

			cout << "\n<<< Add House >>>" << endl;

				//Task 6(c-i): Enter the details of House [2 marks]
				cout<<"Type (Bungalow / Terrace): ";
				cin>>type;
				cout<<"Name: ";
				cin>>housename;
				cout<<"Price: RM ";
				cin>>price;


				//Task 6(c-ii): Dynamically allocates a new house (a bungalow
				//or terrace) object. Use a polymorphic concept. [7 marks]
				
			
				if (type == "Bungalow") //To identify the house type
				{
				}
				
				else
				{
				}
				housePtr->readInput(housename);
				

				//Task 6(c-iii): Add the House object into the House array [1 mark]
				houseList[numHouse]=housePtr;
				
				numHouse++;
				break;
				
			case 3:

				//Display an appropriate message if there is no buyer or no house
				if ((numHouse == 0) || (numBuyer == 0))
				{
					cout << "Sorry!! No buyer or house, please add buyer or house first..." << endl;
					break;
				}

				cout << "\n<<< Add Purchase >>>" << endl
				 	 << "\nBuyer list" << endl;

				//Task 5(e-i): Display the list of buyer [3 marks]
				for(int i=0;i<numBuyer;i++){
					
					string nama=buyerList[i].getName();
					cout<<i+1<<") "<<nama<<endl;
				}

				cout << "\nSelect buyer: ";
				cin >> choice2; //To enter the buyer chosen

				do
				{
					//To enter the details of purchase
					cout << "\n--- Enter Purchase Info ---" << endl;
					
					//Task 5(e-ii): Display the list of houses [3 marks]
				for(int i=0;i<numHouse;i++){
					
					string nama=houseList[i]->getName();
					cout<<i+1<<") "<<nama<<endl;
				}
					
					cout << "\nSelect house: ";
					cin >> choice3; //To enter the house chosen
					cout << "Quantity: ";
					cin >> qtty;
					cin.ignore();
					
					//Task 5(e-iii): Add purchase to the selected Buyer object [3 marks]
					

					cout << "\nPress 'Y' to continue >> ";
					cin >> ch; //To enter a value to continue to add a purchased house
					cin.ignore();
					ch = toupper(ch);
				} while (ch == 'Y'); //The process will be continued if user enter the valid input
				break;

			case 4:

				//To display an appropriate message if there is no buyer
				if (numBuyer == 0)
				{
					cout << "Sorry!! No buyer, please add buyer first..." << endl;
					break;
				}

				cout << "\n<<< Buyer(s) and Purchase(s) Info >>>" << endl;
				cout << "\nNumber of Buyer: " << numBuyer << endl;

				//Task 5(f): Display the list of purchases' details based on the buyer [4 marks]
				cout>>"Number of All Purchases : 4 "<<endl;
				cout>>"Number of Bungalow : 3"<<endl; 
				cout>>"Number of Terrace : 1"<<endl;
				cout>>"No Description Address Price(RM) After Discount(RM) Quantity Total(RM)"<<endl;
				cout>>"1. Meranti (Side) 81310 Skudai 520000.00 520000.00 1 520000.00"<<endl;
				cout>>"2. Pulai Perdana 81300 Skudai 960000.00 816000.00 2 1632000.00"<<endl;

		} //End switch

		cout << endl;

		//Task 5(f): Enter the task chosen (2 mark)
		//___________________________________

	}while (choice1!=5); //End while

	cout << "Thank you! :)" << endl;
	return 0;
}
