#include <iostream>
#include "LinkedList.cpp"
#include "StackException.cpp"

using namespace std;

#ifndef STACK_CLASS_INCLUDED
#define STACK_CLASS_INCLUDED

/*
	Stack Class
	LastModification : 2008. 5. 5
	Version : 1.0.0
	myllyj(myllyj at myllyj dot com) / http://program.myllyj.com

	Requirements:
		require LinkedList class.
		require StackException classes.

*/

template <class T>
class Stack
{
private :
	LinkedList<T>* stackList;

public :
	Stack();

	void Push(T data);
	T Pop();
	T Top();

	int Count();

	void Clear();
	T* ToArray();

};

template <class T>
Stack<T>::Stack()
{
	stackList = new LinkedList<T>();
}

// ½ºÅÃÀÇ ¸Ç À§¿¡ »ðÀÔÇÕ´Ï´Ù.
template <class T>
void Stack<T>::Push(T data)
{
	stackList->AddLast(data);
}

// ½ºÅÃÀÇ ¸Ç À§¿¡¼­ °³Ã¼¸¦ Á¦°ÅÇÏ°í ¹ÝÈ¯ÇÕ´Ï´Ù.
template <class T>
T Stack<T>::Pop()
{
	if (this->Count()<=0) throw StackNoElementException();
	T data = Top();
	stackList->Remove();
	return data;
}

// ½ºÅÃÀÇ ¸Ç À§¿¡¼­ °³Ã¼¸¦ Á¦°ÅÇÏÁö ¾Ê°í ¹ÝÈ¯ÇÕ´Ï´Ù.
template <class T>
T Stack<T>::Top()
{
	if (this->Count()<=0) throw StackNoElementException();
	stackList->MoveLast();
	return stackList->Get();
}

// ½ºÅÃ¿¡ ½ÇÁ¦·Î Æ÷ÇÔµÈ ¿ä¼ÒÀÇ ¼ö¸¦ °¡Á®¿É´Ï´Ù.
template <class T>
int Stack<T>::Count()
{
	return stackList->Count();
}

// ½ºÅÃ¿¡¼­ °³Ã¼¸¦ ¸ðµÎ Á¦°ÅÇÕ´Ï´Ù.
template <class T>
void Stack<T>::Clear()
{
	stackList->Clear();
}

// ½ºÅÃÀÇ ¿ä¼Ò¸¦ »õ ¹è¿­¿¡ º¹»çÇÕ´Ï´Ù.
template <class T>
T* Stack<T>::ToArray()
{
	return stackList->ToArray();
}

#endif