#include <iostream>
#include <string>

#ifndef DASTACK
#define DASTACK

using namespace std;

#include "DAStackExceptions.h"

#define NULLVAL -1

typedef int Element;
typedef Element *ElementsInStack;
const int DEFAULT = 5;

class DAStack 
{
  public:

    /* default constructor */
    /* For this constructor, initialize (i.e. instantiate) the size of the dynamic array of Element pointed to byElementsInStack (see below) to 5.
       The capacity data member (see below) should therefore be initialized to 5.
       The top data element (see below) should be initialized to NULLVAL (i.e., the stack is empty to start).
     */ 
    DAStack( );


    /* explicit value constructor */
    /* Same idea as above, but header includes integer parameter initialSize.
       Initialize the size of the dynamic array to that of the input parameter initialSize, etc.
     */
    DAStack(int initialCapacity);

  
    /* copy constructor */
    /* Given an instance of DAStack, instantiates a new DAStack object
       whose data members have exactly the same values as the given object.
     */ 
    DAStack(const DAStack & original);


    /* destructor */
    /* Destroys the dynamically allocated array pointed to byElementsInStack.
     */ 
    ~DAStack( );

    /* predicate */
    /* Is stack empty? 
     */
    bool isEmpty();


    /* mutator */
    /* Adds a new element to top of the stack.
     */
    void push(Element element); 


    /* mutator */
    /* Removes an element from the top of the stack.
     */
    void pop( ) throw (Empty); 


    /* accessor */
    /* Get number of items in stack */
    int getSize() const;


    /* accessor */
    /* Return the Element stored on the top of the stack.  Does not remove it! */
    Element  getTop() const throw (Empty);


    /* output */
    /* Display all the elements on the stack from top down. Isn't really part of a stack ADT implementation, but is used for debugging.
     */
    void display(ostream & out) const;

    /* input */
    /* Input elements to a stack */
    void read(istream & out);



    /* overloaded assignment operator */
    DAStack & operator=(const DAStack & original);


  private:
    int      capacity;
    int      top;
    int      size;
   ElementsInStack elements;

    /* copy old array info to new array */
    void modifyArraySize(const string message);

    /* verify that dynamic memory allocation was successful */
    bool verifyAllocation(const string messageSource,ElementsInStack newPtr);
};


  /* overloaded output operator */
  /* Allows a DAStack object to be output.
   */
  ostream & operator<<(ostream & out, const DAStack & DAStack);


  /* overloaded input operator */
  /* Allows a DAStack object to be input.
   */
  istream & operator>>(istream & in, DAStack & DAStack);

#endif
