// Project SECJ1023-06
// AHMAD NAZRAN BIN YUSRI A20EC0179
// MEGAT IRFAN ZACKRY BIN ISMAIL A20EC0205
// MUHAMMAD HAFIZZUL BIN ABDUL MANAP A20EC0211

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
using namespace std;

class Stationary {
	private:
		string stationaryName;
		double stationaryPrice;
		int sQuantity;
	public:
		Stationary() {
			stationaryName = "";
			stationaryPrice = 0.0;
			sQuantity = 0;
		}
		Stationary(string sN, double sP) {
			stationaryName =sN;
			stationaryPrice =sP;
		}
		void stationaryCatalog() {
			string sN[4] = { "Pencil", "Pen", "Eraser", "Ruler"};
			double sP[4] = { 1.00, 1.50, 0.80, 1.00};
			cout << endl;
			cout << "-----------------------------" << endl;
			cout << left <<"No. "<< setw(15) << "Product" << "Price (RM)" << endl; 
			cout << "-----------------------------" << endl;
			for (int i = 0; i < 4; i++)
			{
				cout << i+1 <<"-  " << left << setw(15) << sN[i]
				 	 << fixed << setprecision(2) << sP[i] <<endl;				 	 
			}
			cout << left << "-----------------------------" << endl << endl ;
			cout << "Enter 0 to return!";
		}
		string getStationary_Name() const { return stationaryName;}
		double getStationary_Price() const { return stationaryPrice;}
		int getsQuantity() const { return sQuantity;}
		void setsQuantity(int q) { sQuantity =q;}	
};

class Media {
	private:
		string mediaName;
		double mediaPrice;
		int mQuantity;
	public:
		Media() {
			mediaName = "";
			mediaPrice = 0.0;
			mQuantity = 0;
		}
		Media(string mN, double mP) {
			mediaName =mN;
			mediaPrice =mP;
		}
		void mediaCatalog() {
			string mN[4] = { "Podcast Series (mp4)", "Educational DVD", "Newspaper", "Magazine"};
			double mP[4] = { 15.00, 8.60, 1.70, 4.60};
			cout << endl;
			cout << "---------------------------------------" << endl;
			cout << left <<"No. "<< setw(25) << "Product" << "Price (RM)" << endl; 
			cout << "---------------------------------------" << endl;
			for (int i = 0; i < 4; i++)
			{
				cout << i+1 <<"-  " << left << setw(25) << mN[i]
				 	 << fixed << setprecision(2) << mP[i] <<endl;				 	 
			}
			cout << "---------------------------------------" << endl << endl ;
			cout << "Enter 0 to return!";
		}
		string getMedia_Name() const { return mediaName;}
		double getMedia_Price() const { return mediaPrice;}
		int getmQuantity() const { return mQuantity;}
		void setmQuantity(int q) { mQuantity =q;}	
};

class Ebook {
	private:
		string ebookName;
		double ebookPrice;
		int ebQuantity;
	public:
		Ebook() {
			ebookName = "";
			ebookPrice = 0.0;
			ebQuantity = 0;
		}
		Ebook(string eBN, double eBP) {
			ebookName =eBN;
			ebookPrice =eBP;
		}
		void ebookCatalog() {
			string eBN[4] = { "Chemistry (pdf)", "Mathematics (pdf)", "Biology (pdf)", "Physics (pdf)"};
			double eBP[4] = { 15.00, 16.00, 17.00, 18.00};
			cout << endl;
			cout << "---------------------------------------" << endl;
			cout << left <<"No. "<< setw(25) << "Product" << "Price (RM)" << endl; 
			cout << "---------------------------------------" << endl;
			for (int i = 0; i < 4; i++)
			{
				cout << i+1 <<"-  " << left << setw(25) << eBN[i]
				 	 << fixed << setprecision(2) << eBP[i] <<endl;				 	 
			}
			cout << "---------------------------------------" << endl << endl ;
			cout << "Enter 0 to return!";
		}
		string getEbook_Name() const { return ebookName;}
		double getEbook_Price() const { return ebookPrice;}
		int getebQuantity() const { return ebQuantity;}
		void setebQuantity(int q) { ebQuantity =q;}	
};

class Book {
	private:
		string bookName;
		double bookPrice;
		int bQuantity;
	public:
		Book() {
			bookName = "";
			bookPrice = 0.0;
			bQuantity = 0;
		}
		Book(string bN, double bP) {
			bookName =bN;
			bookPrice =bP;
		}
		void bookCatalog() {
			string bN[4] = { "Chemistry", "Mathematics", "Biology", "Physics"};
			double bP[4] = { 46.30, 35.70, 65.99, 31.87};
			cout << endl;
			cout << "-----------------------------" << endl;
			cout << left <<"No. "<< setw(15) << "Product" << "Price (RM)" << endl; 
			cout << "-----------------------------" << endl;
			for (int i = 0; i < 4; i++)
			{
				cout << i+1 <<"-  " << left << setw(15) << bN[i]
				 	 << fixed << setprecision(2) << bP[i] <<endl;				 	 
			}
			cout << "-----------------------------" << endl << endl ;
			cout << "Enter 0 to return!";
		}
		string getBook_Name() const { return bookName;}
		double getBook_Price() const { return bookPrice;}
		int getbQuantity() const { return bQuantity;}
		void setbQuantity(int q) { bQuantity =q;}	
};

class User{
	protected:
		int fingerprintW, fingerprintL;
	public:
		void setfingerprintW (int width) { fingerprintW = width;}
		void setfingerprintL (int length) { fingerprintL = length;}
		int getfingerprintW () const { return fingerprintW;}
		int getfingerprintL () const { return fingerprintL;}
};

class Customer: public User {
	private:
		string detail;
	public:
		Customer (string details) { detail=details;}
		Customer () {}
		string getDetail ()const {return detail;}
};

class ShoppingCart {
	private:
		int numStationary, numMedia, numEbook, numBook;
		Stationary *stationary;
		Media *media;
		Ebook *ebook;
		Book *book;
	public:
		Customer d1, d2, d3, d4;
		double total_Amount;
		ShoppingCart(string names,string emails, string addresss, string phoneNos):d1(names), d2(emails), d3(addresss), d4(phoneNos) {
			numStationary = 0;
			numMedia = 0;
			numEbook = 0;
			numBook = 0;
			stationary = new Stationary[50];
			media = new Media[50];
			ebook = new Ebook[50];
			book = new Book[50];
		}
		void viewprofile(){
			cout << "-------------"<< endl;
			cout << "Your Profile"<< endl;
			cout << "-------------"<< endl << endl;
			cout << "Name : " << d1.getDetail() << endl;
			cout << "Email : " << d2.getDetail()  << endl;
			cout << "Address : " << d3.getDetail() << endl;
			cout << "Phone No. : " << d4.getDetail() << endl;
			system ("pause");
		}
		void addCartItem(Stationary s, int q) {
			stationary[numStationary] = s;
			stationary[numStationary].setsQuantity(q);
			numStationary++;
		}
		void addCartItem(Media m, int q) {
			media[numMedia] = m;
			media[numMedia].setmQuantity(q);
			numMedia++;
		}
		void addCartItem(Ebook eb, int q) {
			ebook[numEbook] = eb;
			ebook[numEbook].setebQuantity(q);
			numEbook++;
		}
		void addCartItem(Book b, int q) {
			book[numBook] = b;
			book[numBook].setbQuantity(q);
			numBook++;
		}
		void clearitem(){
			stationary = new Stationary[50];
			media = new Media[50];
			ebook = new Ebook[50];
			book = new Book[50];
			numStationary = 0;
			numMedia = 0;
			numEbook = 0;
			numBook = 0;
		}
		int getnumTotal() const { return numStationary+numMedia+numEbook+numBook;}
		void settotalAmount(double totalAmount) { total_Amount=totalAmount;}
		void checkout() {
			system ("cls");
			int q, k=1;
            double p, amount=0, totalAmount=0;
            cout << "Name : " << d1.getDetail() << endl;
            cout << "Number of items purchased : " << getnumTotal();
			cout << endl << "---------------------------------------------------------------" << endl;
			cout << left << setw(8) << "No." << setw(20) << "Product" << setw(10) << right << "Price" << setw(15) << "Quantity" << setw(10) << "Amount" << setw(10) << endl;
			cout << "---------------------------------------------------------------" << endl;
			for(int i = 0; i < numStationary; i++) {
				cout << left << setw(8) << (k) << setw(20) << stationary[i].getStationary_Name() << right << setw(10) << stationary[i].getStationary_Price() << setw(13) << stationary[i].getsQuantity();
				q = stationary[i].getsQuantity();
                p = stationary[i].getStationary_Price();
                amount = static_cast<double>(q) * p;
                totalAmount += amount;
                cout << setw(10) << amount << endl;
                k++;
        	}
        	for(int i = 0; i < numMedia; i++) {
        		cout << left << setw(8) << (k) << setw(20) << media[i].getMedia_Name() << right << setw(10) << media[i].getMedia_Price() << setw(13) << media[i].getmQuantity();
				q = media[i].getmQuantity();
                p = media[i].getMedia_Price();
                amount = static_cast<double>(q) * p;
                totalAmount += amount;
                cout << setw(10) << amount << endl;
                k++;
        	}
        	for(int i = 0; i < numEbook; i++) {
        		cout << left << setw(8) << (k) << setw(20) << ebook[i].getEbook_Name() << right << setw(10) << ebook[i].getEbook_Price() << setw(13) << ebook[i].getebQuantity();
				q = ebook[i].getebQuantity();
                p = ebook[i].getEbook_Price();
                amount = static_cast<double>(q) * p;
                totalAmount += amount;
                cout << setw(10) << amount << endl;
                k++;
        	}
        	for(int i = 0; i < numBook; i++) {
        		cout << left << setw(8) << (k) << setw(20) << book[i].getBook_Name() << right << setw(10) << book[i].getBook_Price() << setw(13) << book[i].getbQuantity();
				q = book[i].getbQuantity();
                p = book[i].getBook_Price();
                amount = static_cast<double>(q) * p;
                totalAmount += amount;
                cout << setw(10) << amount << endl;
                k++;
        	}
        	cout << "---------------------------------------------------------------" << endl;
        	cout << "Your total amount is : RM" << totalAmount << endl;
        	total_Amount = totalAmount;
		}
		double gettotalAmount() const { return total_Amount;}
};

class Payment {
	private: 
		string payMethod;
		double shippingFee;
	public: 
		Payment() {
			shippingFee = 3.50;
		}
		void setpayMethod(string pM) { payMethod =pM;}
		string getpayMethod() const { return payMethod;}
		double getshippingFee() const { return shippingFee;}
};

class ShippingInfo {
	private:
		string courier, status;
	public:
		ShippingInfo() {
			status = "Shipping...";
		}
		void setCourier(string c) { courier =c;}
		string getCourier() const { return courier;}
		string getStatus() const {return status;}
};

int main ()	{
	int choice;
	do{
		//declaration
		int value=0, user_ID, width_, length_, buy, q, ctlg, options;
		bool correct=1;
		Payment pay;
		ShippingInfo si;
		string paymentMethod, courier;
		Stationary catalog1;
		Media catalog2;
		Ebook catalog3;
		Book catalog4;
		Customer cust[50];
		
		//catalog data
		Stationary s1 ("Pencil", 1.00);
		Stationary s2 ("Pen", 1.50);
		Stationary s3 ("Eraser", 0.80);
		Stationary s4 ("Ruler", 1.00);
		Media m1 ("Podcast Series (mp4)", 15.00);
		Media m2 ("Educational DVD", 8.60);
		Media m3 ("Newspaper", 1.70);
		Media m4 ("Magazine", 4.60);
		Ebook eb1 ("Chemistry (pdf)", 15.00);
		Ebook eb2 ("Mathematics (pdf)", 16.00);
		Ebook eb3 ("Biology (pdf)", 17.00);
		Ebook eb4 ("Physics (pdf)", 18.00);
		Book b1 ("Chemistry", 46.30);
		Book b2 ("Mathematics", 35.70);
		Book b3 ("Biology", 65.99);
		Book b4 ("Physics", 31.87);
		
		//signup & login loop
		do {
			string name_, email_, address_, phone_no;
			system ("cls");
			cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
			cout << " WELCOME TO MEGAH BOOKSTORE " << endl;
			cout << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
			cout << "1- Sign Up" << endl << "2- Log In" << endl ;
			if (correct==0){cout << endl << "Error! Please enter a valid choice!" << endl << endl;}
			cout << "Hello! What do you want to do today? : " ;
			cin >> value ;	
				
			//create new file for data storing
			if (value==1) {
				system ("cls");
				cout << endl << "Please insert your details below!";
				
				cin.ignore();
				fstream outname;
				outname.open("userName.txt",std::ios_base::app);
				cout <<endl << left << setw(10) << "Name" << " : " ;
				getline(cin, name_);
				outname<<name_ << endl;
				outname.close();
				
				fstream outEmail;
				outEmail.open("userEmail.txt",std::ios_base::app);
				cout << setw(10) <<  "Email" << " : ";
				cin>>email_;
				outEmail << email_ << endl;
				outEmail.close();
				
				cin.ignore();
				fstream outAddress;
				outAddress.open("userAddress.txt",std::ios_base::app);
				cout << setw(10) <<  "Address" << " : ";
				getline(cin, address_);
				outAddress << address_ << endl;
				outAddress.close();
				
				fstream outPhone;
				outPhone.open("userPhone.txt",std::ios_base::app);
				cout << setw(10) <<  "Phone No." << " : ";
				getline(cin, phone_no);
				outPhone << phone_no << endl;
				outPhone.close();
				
				fstream outFingerprintW;
				outFingerprintW.open("userFingerprintW.txt",std::ios_base::app);
				cout << endl << "Enter your fingerprint's width and length!" 
					 << endl <<  setw(10) <<  "Width" << " : ";
				cin >> width_;
				outFingerprintW << width_ << endl;
				outFingerprintW.close();
				
				fstream outFingerprintL;
				outFingerprintL.open("userFingerprintL.txt",std::ios_base::app);
				cout <<  setw(10) <<  "Length" << " : ";
				cin >> length_ ;
				outFingerprintL << length_ << endl;
				outFingerprintL.close();
				
				//continuation of user_ID
				ifstream inuserID; 
				inuserID.open("userID.txt");
	   			if(!inuserID) { 
		   			user_ID = 1;
		   			inuserID.close();
		   			ofstream outuserID;
					outuserID.open("userID.txt",std::ios_base::app);
					outuserID<<user_ID;
					outuserID.close();
				}
	    		else {
	    			int num;
	    			inuserID>>num;
	    			num=num+1;
	    			user_ID=num;
	    			inuserID.close();
	    			ofstream outuserID;
					outuserID.open("userID.txt");
					outuserID<<user_ID;
					outuserID.close();		
				}
				cout << endl << "Your account is successfully registered!" << endl;
				cout << "Your userID is " << user_ID << endl << endl;
			}
			
			//login
			else if (value==2) {	
				int i=1,o=1, num1[50], num2[50];
				bool login=0;
				correct=1;
				
				ifstream indata1;
				indata1.open("userFingerprintW.txt");
					while (!indata1.eof()) {	
					indata1 >> num1[i];
					cust[i].setfingerprintW(num1[i]);
					i++;
				}
				indata1.close();
				ifstream indata2;
				indata2.open("userFingerprintL.txt");
				while (!indata2.eof()) { 
					indata2 >> num2[o];
					cust[o].setfingerprintL(num2[o]);
					o++;
				}
				indata2.close();
					
				//login interface
				do {
					system ("cls");
					cout << endl << "Please insert your login details below!";
					cout << endl << "Enter 0 to return!"<<endl;
					if (correct==0){cout << endl << "Invalid userID or fingerprint! Please try again" << endl;}
					cout << endl << left << setw(20) << "UserID" << " : ";
					cin >> user_ID;
					if (user_ID!=0){
					cout << setw(20) <<  "Fingerprint Width" << " : ";
					cin >> width_;
					cout <<  setw(20) <<  "Fingerprint Length" << " : ";
					cin >> length_ ;
			
					if (width_ == cust[user_ID].getfingerprintW() && length_ == cust[user_ID].getfingerprintL() ) { 
					cout << endl << "Your account is successfully logged in!" << endl <<endl;
					login=1;}	//compare input with data from file
					else {correct=0;}}
					else {login=1;
					value=0;
					correct=1;}
				}	while (login==0); 
			}	
			else { correct=0;}	
		} while (value!=1&&value!=2); //loop if error choice (sign up or login)
		
		//set variable from file
		system ("pause");
		string name_[50], email_[50], address_[50], phone_no[50];
		correct=1;
		ifstream inname;
		inname.open("userName.txt"); {
			int i=1;
			while (!inname.eof()) {
				getline(inname,name_[i]);
				i++;
			}
			inname.close();
		}						
		ifstream inemail;
		inemail.open("userEmail.txt"); {
			int i=1;
			while (!inemail.eof()) {
				inemail >> email_[i];
				i++;
				}
			inemail.close();
		}
		ifstream inaddress;
		inaddress.open("userAddress.txt"); {
			int i=1;
			while (!inaddress.eof()) {
				getline(inaddress,address_[i]);
				i++;
			}
			inaddress.close();
		}
		ifstream inphone;
		inphone.open("userPhone.txt"); {
			int i=1;
			while (!inphone.eof()) {
				inphone >> phone_no[i];
				i++;
			}
			inphone.close();
		}
		ShoppingCart detail(name_[user_ID],email_[user_ID],address_[user_ID],phone_no[user_ID]);
		
		//buy item 
		do {
		system ("cls");
		cout << "-=-=-=-=-=-=-=-=-" << endl;
		cout << " MEGAH BOOKSTORE " << endl;
		cout << "-=-=-=-=-=-=-=-=-" << endl;
		cout << endl << "Hi! What do you want to do today?" << endl << "1- Open Catalog" << endl << "2- See Cart" << endl <<  "3- View Profile" << endl << "4- Log Out"<< endl;
		if (correct==0){cout << endl << "Error! Please enter a valid choice!" << endl << endl;}
		cout << endl << "Choice : ";
		cin >> choice;
		if (choice==1){
			correct=1;	
			do{
			system ("cls");
			cout << endl << "Which catalog do you want to see?" << endl << "1- Stationary" << endl << "2- Media" << endl << "3- Ebook" << endl << "4- Book" << endl <<  "0- Back" << endl;
			if (correct==0){cout << endl << "Error! Item not found. Please enter a valid choice!"  << endl;}
			cout << endl << "Catalog : " ;
			cin>>ctlg;
			
			if (ctlg==1) { catalog1.stationaryCatalog();}
			else if (ctlg==2) { catalog2.mediaCatalog();}
			else if (ctlg==3) { catalog3.ebookCatalog();}
			else if (ctlg==4) { catalog4.bookCatalog();}
				
			if (ctlg==1||ctlg==2||ctlg==3||ctlg==4) {
				cout << endl << "What do you want to buy? : ";
				cin >> buy;
				if (buy==1||buy==2||buy==3||buy==4) {
					cout << endl << "Please insert the quantity : "; 
					cin >> q;
					if (ctlg==1&&buy==1) { detail.addCartItem(s1, q);}
					else if (ctlg==1&&buy==2) { detail.addCartItem(s2, q);}
					else if (ctlg==1&&buy==3) { detail.addCartItem(s3, q);}
					else if (ctlg==1&&buy==4) { detail.addCartItem(s4, q);}
					else if (ctlg==2&&buy==1) { detail.addCartItem(m1, q);}
					else if (ctlg==2&&buy==2) { detail.addCartItem(m2, q);}
					else if (ctlg==2&&buy==3) { detail.addCartItem(m3, q);}
					else if (ctlg==2&&buy==4) { detail.addCartItem(m4, q);}
					else if (ctlg==3&&buy==1) { detail.addCartItem(eb1, q);}
					else if (ctlg==3&&buy==2) { detail.addCartItem(eb2, q);}
					else if (ctlg==3&&buy==3) { detail.addCartItem(eb3, q);}
					else if (ctlg==3&&buy==4) { detail.addCartItem(eb4, q);}
					else if (ctlg==4&&buy==1) { detail.addCartItem(b1, q);}
					else if (ctlg==4&&buy==2) { detail.addCartItem(b2, q);}
					else if (ctlg==4&&buy==3) { detail.addCartItem(b3, q);}
					else if (ctlg==4&&buy==4) { detail.addCartItem(b4, q);}
					else {correct = 0;}
				}
				else if (buy==0){correct=1;}
				else{correct=0;	}
			}
			else if(ctlg==0) { correct=1;}
			else {correct=0;}
			
			} while (ctlg!=0);
		}
		else if (choice==2) { 
			do{
			detail.checkout();
			cout << endl << "1- Proceed to Checkout" << endl << "2- Clear Cart" << endl << "0- Back" << endl << endl << "Choice : ";
			cin >> options;
			if (options==1) { // checkout
				if (detail.getnumTotal()==0) { 
					cout << endl << "You do not have any item in your cart!" << endl << endl; system("pause");}
				else {			//payment & shipping
					system("cls");
					cout << "What payment method you are using? : ";
					cin.ignore();
					getline(cin, paymentMethod);
					pay.setpayMethod(paymentMethod);
					cout << endl << "What courier do you want to use? : ";
					getline(cin, courier);
					si.setCourier(courier);
					system("cls");
					detail.checkout();
					cout << "Your final payment : RM" << detail.gettotalAmount() + pay.getshippingFee() << endl;
					cout << "Payment method : " <<  pay.getpayMethod() << endl << endl;
					cout << "Courier : " << si.getCourier() << endl;
					cout << "Delivery Status : " << si.getStatus() << endl;
					system ("pause");
					detail.clearitem();
					options=0;
				}
			}
			else if (options==2){detail.clearitem();}
			system ("cls");
			} while (options!=0);
		}
		else if (choice==3){detail.viewprofile();}
		else if (choice==4) { correct=1;}
		else { correct=0;}
		} while (choice !=4);
	}while (choice==4);//loop logout
	return 0;
}
