#pragma once
#include "Element.h";

template< class T >
class List
{
	public:
		
		List(void)
		{
			this->first = NULL;
			this->count = 0;
		}

		
		~List(void)
		{
			Element<T> *walker = first;
			for ( int i = 0; i < this->count; i++ )
			{
				Element<T> *temp = walker->next;
				walker = walker->next;

				delete temp;
			}
		}

		
		void addFirst(const T& item)
		{
			Element<T> *temp = new Element<T>(item);
			if ( first == NULL )
				first = temp;
			else
			{
				temp->next = first;
				first = temp;
			}
				

			this->count += 1;
		}

		void addElementAt(int index, const T& item)
		{
			if ( index == 0 ) {
				addFirst(item);
			}
			else {
				Element<T> *temp = new Element<T>(item);
				Element<T> *walker = first;
				if ( index >= count ) {
					while ( walker->next != NULL )
						walker = walker->next;
					walker->next = temp;
				}
				else {
					for(int i = 0; i < ( index - 1 ); i++)
						walker = walker->next;
					temp->next = walker->next;
					walker->next = temp;
				}
				
				this->count += 1;
			}
		}

		bool deleteElementAt(int index)
		{
			if ( index > this->count )
				return false;
			else if (index == 0)
			{
				Element<T> *temp = this->first->next;
				first = temp;
			}
			else
			{
				Element<T> *walker = this->first;
				for ( int i = 0; i < (index-1); i ++ )
				{
					walker = walker->next;
				}
				
				Element<T> *temp = walker->next;
				walker->next = walker->next->next;

				delete temp;
			}
			
			this->count--;

			return true;
		}

		bool deleteElement(const T& item)
		{
			if ( first == NULL )
				return false;
			else if ( first->data == item )
			{
				Element<T> *temp = first;
				first = temp->next;

				delete temp;
	
				this->count--;
				
				return true;
			}
			else
			{
				Element<T> *walker = this->first;
				while(walker->next->data != item && walker->next->next != NULL)
					walker = walker->next;
				Element<T> *temp = walker->next;
				walker->next = temp->next;
				delete temp;

				this->count--;

				return true;
			}
			return false;
		}

		bool isEmpty() const
		{
			if ( this->count > 0 )
				return false;

			return true;
		}

		bool SearchContent(const T& item) const
		{
			Element<T> *walker = first;
			for ( int i = 0; i < this->count; i++ )
			{
				if ( walker == item )
				{
					return true;
				}
				else
				{
					Element<T> *temp = walker->next;
					walker = walker->next;
				}
			}

			return false;
		}

		bool set(int index, const T& item)
		{
			if ( index > this->count )
				return false;

			else
			{
				Element<T> *walker = this->first;

				for ( int i = 0; i < index; i ++ )
				{
					walker = walker->next;
				}
				walker->data = item;
			}

			return true;
		}

		T get(int index) const
		{
			if ( index > this->count )
				return NULL;
			else
			{
				Element<T> *walker = first;
				for (int i = 0; i < index; i++)
					walker = walker->next;

				return walker->data;
			}
			return NULL;
		}

		int size()
		{
			return this->count;
		}

	private:
		Element<T>* first;
		int count;
};

