#include <iostream>

using namespace std;

#include "PStack.h"
#include "PStackExceptions.h"
   
    PStack::PStack() : top(NULLVAL), size(INIT)
    {
      const string MESSAGE = "DEFAULT CONSTRUCTOR";      
      cout << MESSAGE << endl;      
    }
    
    PStack::PStack(const PStack & original)
    {
      const string MESSAGE = "COPY CONSTRUCTOR";    
      size = original.size;
      top = NULLVAL; // just in case original is null:  will overwrite otherwise
      if(original.top != NULLVAL)
      {
        Link originalStack = original.top;
        Link newPStack = new Node(originalStack->data);
        top = newPStack;
        for (originalStack = originalStack->next; originalStack != NULLVAL; originalStack = originalStack->next)
        {
          newPStack->next = new Node(originalStack->data);
          newPStack = newPStack->next;
        }
      }
      cout << MESSAGE << endl;   
    }

    PStack::~PStack()
    {
      const string MESSAGE = "DESTRUCTOR";
      Link unzipper = top;
      while (unzipper != NULLVAL)
      {
        top = unzipper->next;
        delete unzipper;
        unzipper = top;
      } 
      cout << MESSAGE << endl;      
    }

    PStack & PStack::operator=(const PStack & original)
    {
      const string MESSAGE = "OVERLOADED ASSIGNMENT"; 
      if (this != &original)
      {
        Link oldPStack = top; //delete old PStack, if any
        while (oldPStack != NULLVAL)
        {
	  top = oldPStack->next;
	  delete oldPStack;
	  oldPStack = top;
	}
	size = original.size;
        top = NULLVAL;  // just in case original is null:  will overwrite otherwise
	if (top != NULLVAL)
	{
	  Link originalPStack = original.top;
	  Link newPStack = new Node(originalPStack->data);
          top = newPStack;
	  for (originalPStack = originalPStack->next; originalPStack !=NULLVAL; originalPStack = originalPStack->next)
	  {
	    newPStack->next = new Node(originalPStack->data);
	    newPStack = newPStack->next;
          }
        }
      }
      return * this;   
      cout << MESSAGE << endl;      
    }


    bool PStack::isEmpty() const
    {
      const string MESSAGE = "IS_EMPTY";
      cout << MESSAGE << endl;      
      return (top==NULLVAL);
    }

        
    int PStack::getSize() const
    {
      const string MESSAGE = "GET_SIZE";
      cout << MESSAGE << endl;      
      return size;
    }

    Element PStack::getTop() const
    {
      const string MESSAGE = "GET_TOP";   
      Element data;

      if (isEmpty())
        throw Empty(MESSAGE); 
      cout << MESSAGE << endl;
      return top->data;
    }
        
    void PStack::push(Element element)
    {
      const string MESSAGE = "PUSH";
      Link newNode = new Node(element, top);
      top = newNode;
      size++;
      cout << MESSAGE << endl;      
    }
    
    void PStack::pop()
    {
      const string MESSAGE = "POP";
      if (isEmpty())
        throw Empty(MESSAGE);
      Link deleteNode = top;
      top = top->next;
      delete deleteNode;
      size--;
      cout << MESSAGE << endl;      
    }
    
    void PStack::display(ostream & out) const
    {
      const string MESSAGE = "DISPLAY";
      out << "This PStack contains " << size << " members." << endl; 
      for (Link link = top; link != NULLVAL; link = link->next)
        out << link->data << "\t";
      out << endl;
      cout << MESSAGE << endl;      
    }
    
    void PStack::read(istream & in)
    {
      const string MESSAGE = "READ";
      Element element;
      char c;
      while (in>>element)
      {
        push(element);
      }
      in >> c;
      cout << MESSAGE << endl;            
    }
    
    ostream & operator<<(ostream & out, const PStack & PStack)
    {
      const string MESSAGE = "OVERLOADED<<";
      PStack.display(out);
      cout << MESSAGE << endl;      
      return out; 
    }
    
    istream & operator>>(istream & in, PStack & PStack)
    {
      const string MESSAGE = "OVERLOADED>>";
      PStack.read(in);
      cout << MESSAGE << endl;      
      return in;
    }
 
