#include <iostream>
#include "LinkedList.cpp"
#include "QueueException.cpp"

using namespace std;

#ifndef QUEUE_CLASS_INCLUDED
#define QUEUE_CLASS_INCLUDED

/*
	Queue Class
	LastModification : 2008. 5. 5
	Version : 1.0.0
	myllyj(myllyj at myllyj dot com) / http://program.myllyj.com

	Requirements:
		require LinkedList class.
		require QueueException classes

	Comment:
		ÀÌ classÀÇ methodÀÇ ¸í¸í¹ýÀº C#°è¿­À» ÁÖ·Î µû¸§.
		±âÁ¸ÀÇ C++ÀÇ ¸í¸í¹ý°ú´Â ´Ù¼Ò Â÷ÀÌ°¡ ÀÖÀ½.
		¿¹¸¦ µé¾î Å¥¿¡ ³Ö´Â °ÍÀ» insert, Å¥¿¡¼­ ÇÏ³ª Á¦°ÅÇÏ´Â°ÍÀ»
		popÀÌ¶ó°í ¹¬½ÃÀûÀ¸·Î ¾²Áö¸¸, C#°ú °°Àº ÇüÅÂÀÇ ¸Þ¼Òµå¸íÀ» »ç¿ëÇØ¼­
		enQueue, deQueue, peak °°Àº ¸íÀÌ »ç¿ëµÇ°í ÀÖÀ½.

*/

template <class T>
class Queue
{
private:
	LinkedList<T>* queueList;

public:
	Queue();
	void Enqueue(T data);
	T Dequeue();
	T Peak();

	int Count();

	void Clear();
	T* ToArray();

};

template <class T>
Queue<T>::Queue()
{
	this->queueList = new LinkedList<T>();
}

// Å¥¿¡ ½ÇÁ¦·Î Æ÷ÇÔµÈ ¿ä¼ÒÀÇ ¼ö¸¦ °¡Á®¿É´Ï´Ù.
template <class T>
int Queue<T>::Count()
{
	return this->queueList->Count();
}

// °³Ã¼¸¦ Å¥ÀÇ ³¡ ºÎºÐ¿¡ Ãß°¡ÇÕ´Ï´Ù.
template <class T>
void Queue<T>::Enqueue(T data)
{
	queueList->AddLast(data);
}

// Å¥ÀÇ ½ÃÀÛ ºÎºÐ¿¡¼­ °³Ã¼¸¦ Á¦°ÅÇÏ°í ¹ÝÈ¯ÇÕ´Ï´Ù.
template <class T>
T Queue<T>::Dequeue()
{
	if (this->Count()<=0) throw QueueNoElementException();
	T data = this->Peak();
	queueList->Remove();

	return data;
}

// Å¥ÀÇ ½ÃÀÛ ºÎºÐ¿¡¼­ °³Ã¼¸¦ Á¦°ÅÇÏÁö ¾Ê°í ¹ÝÈ¯ÇÕ´Ï´Ù.
template <class T>
T Queue<T>::Peak()
{
	if (this->Count()<=0) throw QueueNoElementException();

	queueList->MoveFirst();
	return queueList->Get();
}

// Å¥¿¡¼­ °³Ã¼¸¦ ¸ðµÎ Á¦°ÅÇÕ´Ï´Ù.
template <class T>
void Queue<T>::Clear()
{
	queueList->Clear();
}

// Å¥ÀÇ ¿ä¼Ò¸¦ »õ ¹è¿­¿¡ º¹»çÇÕ´Ï´Ù.
template <class T>
T* Queue<T>::ToArray()
{
	return queueList->ToArray()
}

#endif
