#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

class Person {
public:


Person(string a="unknown", string b="unknown", string c="unknown", string d="unknown")
{
	name = a;
	address = b; 
	birthDate = c; 
	deathDate = d; 
	cout <<"Constructed object for " <<name<<endl;
}

~Person(){}

void Print() {
        cout<<"\tName: "<< name <<endl;
        cout<<"\tAddress: "<<address<<endl;
        cout<<"\tDate of birth: "<<birthDate<<endl;
        cout<<"\tDate of death: "<<deathDate<<endl;
    }
    
    void SetName(string a) {name =a;}
    void SetAddress(string a) {address = a;}
    void SetBirthDate(string a) {birthDate = a;}
    void SetDeathDate(string a) { deathDate = a;}
    
    string GetName()const{return name;}
    string GetAddress()const{return address;}
    string GetBDate()const{return birthDate;}
    string GetDDate()const{return deathDate;}
    Person*  next;
private:    
    string name, address, birthDate, deathDate;

};

class slist {               	
public:
   slist() : h(0) { }       	
   ~slist();
   void prepend(Person *p);   	
   void del();
   Person* first() const { return h; }
   void print() const;
   void release();
private:
   Person*  h;          
};

void slist::prepend(Person *p)
{
     p -> next = h;
     h = p;
}

void slist::del()
{
     Person* temp = h;
     h = h -> next;
     cout << "Calling destructor for " << temp->GetName()<<endl;
     delete temp;
}

void slist::print() const   
{
    cout<<"Current list:"<<endl;
   Person* temp = h;

   while (temp != 0) {      
      temp->Print();
      temp = temp -> next;
      cout<<endl;
   }
}

// Elements returned to the heap
void slist::release()  
{
	while ( h!=0){
		del();
	}
}

slist::~slist()
{
   cout << "Linked list destructor invoked" << endl;
   release();
}

int main()
{
    slist w;
    
    Person *p1 = new Person("Joe Smith");
    w.prepend(p1);

    Person *p2 = new Person("Jane Smith", "1 Main Street", "April 1, 1966");
    w.prepend(p2);

    Person *p3 = new Person("Bob Smith", "1 Main Street");
    p3->SetDeathDate("March 21, 1953");
    p3->SetName("Robert Smith");
    w.prepend(p3);
    
    Person *p4 = new Person();
    p4->SetName("Jenny Smith");
    p4->SetAddress("2 Elm Street");
    p4->SetBirthDate("June 5, 1904");
    w.prepend(p4);

    w.print();
    
    // destructor for linked list will be invoked now automatically
}

