//Megat Irfan Zackry Bin Ismail
//A20EC0205

#include <iostream>
using namespace std;
const int size = 5;

struct stud{
	string name;
	int age;
	char gender;
	stud *next;
};

class QueueLL{
	private: 
		stud *frontPtr;
		stud *backPtr;
	
	public:
		QueueLL();
		~QueueLL();
		bool isEmpty();
		void enQueue(string n, int a, char g);
		void deQueue();
		stud *getFront();
		stud *getRear();
		
};
 
QueueLL::QueueLL(){
	frontPtr = NULL;
	backPtr = NULL;
}

QueueLL::~QueueLL(){
	stud *temp = frontPtr;
	while(temp){
		frontPtr = temp->next;
		delete temp;
		temp = frontPtr;
	}
}

void QueueLL::deQueue(){
	if(isEmpty()){
		cout<<"\nUnable to deQ. Queue is empty. ";
	}
	else{
		stud *temp = frontPtr;
		frontPtr = frontPtr->next;
		delete(temp);
	}
}

stud *QueueLL::getRear(){
	return backPtr;
}

stud *QueueLL::getFront(){
	return frontPtr;
}

bool QueueLL::isEmpty(){
	return (frontPtr == NULL && backPtr == NULL);
}

void QueueLL::enQueue(string n, int a, char g){
	stud *nn = new stud;
	nn->name = n;
	nn->age = a;
	nn->gender = g;
	nn->next = NULL;
	
	if(isEmpty()){
		frontPtr = nn;
		backPtr = nn;
	}
	else{
		backPtr->next = nn;
		backPtr = nn;			
	}
}

void menu(){
	QueueLL *ql = new QueueLL;
	
	int i, a;
	string n;
	char g;
	
	do{
	
	cout<<"\n\nQUEUE MENU";
	cout<<"\n\nSelect an option";
	cout<<"\n1. isempty";
	cout<<"\n2. enq";
	cout<<"\n3. deq";
	cout<<"\n4. getrear";
	cout<<"\n5. getfront";
	cout<<"\n6. Call destructor";
	cout<<"\n7. End Program"<<endl;
	
	cout<<"\nOption: ";
	cin>>i;
	
	switch(i){
		case 1: {
			cout<<"\nIs Empty? : " <<ql->isEmpty() <<endl;	
			break;
		}
		
		case 2: {
			cout<<"\nEnter student details";
			cout<<"\nName: ";
			cin>>n;
			cout<<"Age: ";
			cin>>a;
			cout<<"Gender(m/f): ";
			cin>>g;
			ql->enQueue(n,a,g);
				break;
		}
		
		case 3: {
			cout<<"\nLets deQueue";
			ql->deQueue();
			cout<<"\nLets call getFront and getRear";	
				break;
		}
				
		case 4: {
			cout<<"\nLets call getRear";
			stud *atrear = ql->getRear();
			cout<<"\nStud at rear is : " <<atrear->name;
				break;
		}
		
		case 5: {
			cout<<"\nLets call getFront";
			stud *atFront = ql->getFront();
			cout<<"\nStud at front is : " <<atFront->name;	
				break;
		}
		
		case 6: {
			cout<<"\nAFTER DESTRUCTOR";
			ql->~QueueLL();
				break;
		}
			
		default : cout<<"\nEnd Program";
		}
	}
	
while (i!=7);
}

int main(){
	
	menu();
	
		return 0;
}
