#include"CA_NODE.h"

//define class stack_node

template<class T>
class stack_node
{
public:
 stack_node();
 //~stack_node();
 void  Push(T item);
 T Pop();
 int Length();
 int Is_empty();
 T Top_data();
 void Clean_stack();
 Node<T> *GetNode(const T& item, Node<T> *pNext = NULL);
 void DisplaySta();
private:
 Node<T> *top;        //point to the pop
 Node<T> *bottom;    //point to the bottom
 Node<T> *curr_ptr; //point to the current node
 Node<T> *prev_ptr;// point to the prevent node

 int size ;   //the length of the stack   此处用个安全的数据形式  比如static
};


//construct function
template<class T>
stack_node<T>::stack_node()
{
 top = NULL;  
 bottom = NULL; 
 curr_ptr = NULL; 
 prev_ptr = NULL;
 size = 0 ; 

}

//Push a node into the stack
template<class T>   
void stack_node<T>::Push(T item)
{
 if(!bottom)
 {
  curr_ptr = GetNode(item, bottom);
  bottom = curr_ptr;
  top = curr_ptr;
  size ++;
  return;
 }
 
 Node<T> *p;
 top->InsertAfter(GetNode(item,p));
 top = top->NextNode();
 size++;

}
template<class T> //POP 的效率何在,?//efficiency is relatively ,not utterly???????
T stack_node<T>::Pop()
{
 if(!top)//  length = 0
 {
  cout<<"The stack is empty!"<<endl;
  exit(1);
 }
 T top_datum = top->GetData();
 curr_ptr = bottom;
 if(size == 1) // length = 1
 { 
  size--;

  bottom = top = NULL;
  return  top_datum;
 }
 else //Length>=2
 {
  int i =  1;
  while(i < size-1 )//curr_ptr point to the prevent node of the top
  {
   curr_ptr = curr_ptr->NextNode();
   i++;
  }
  top = curr_ptr;
  top->DeleteAfter();
  size--;
  return top_datum;
 }
}
template<class T>//¥
int stack_node<T>::Length()
{
 return size;
}
template<class T>//¥
int stack_node<T>::Is_empty()
{
 if(bottom == NULL)
 {
  return 1;
 }
 else
 {
  return 0;
 }
}
template<class T>//¥
T stack_node<T>::Top_data()

 if(!top )
 {
  cout<<"The stack is empty !"<<endl;
 }
 return top->GetData();
}

//clean all data of the stack

template<class T>//¥
void stack_node<T>::Clean_stack()

 curr_ptr = bottom;
 if(size >2)
 {
  for(int i= 1; i < size ;i++)
  {
   curr_ptr->DeleteAfter();
   size--;
  }
 }
 else if(size == 2)
 {
  bottom->DeleteAfter();
  size --;
  delete bottom;
  size --;
 }
 else 
 { 
  size--;
  delete bottom;
 }
}

template<class T>//$
Node<T> *stack_node<T>::GetNode(const T& item, Node<T> *pNext = NULL)
{
 Node<T> *newNode;
 //新分配一结点存储空间并初始化数据成员
 newNode = new Node<T>(item, pNext);
 if (!newNode)
 {
  cerr<< "存储空间分配失败!程序将终止。" <<endl;
  exit(1);
 }

 return newNode; 
}


template<class T>   
void stack_node<T>::DisplaySta()
{
 int le = Length();
 bottom->DisplayNode();
 prev_ptr = bottom ;
 for ( int i = 1; i<le; i++)
 {
  prev_ptr = prev_ptr->NextNode();
  prev_ptr ->DisplayNode();
 }
}