#ifndef __LISTS_H_
#define __LISTS_H_

template <class TYPE> class NamedItemList 
{

private:

	class ListNode
	{
	public:
		TCHAR			name[80];
		TYPE*			m_pobject;

		ListNode*		next;
		ListNode*		prev;
	};

	ListNode*		m_pHead;
	
public:

	NamedItemList() : m_pHead(NULL)
	{
	}

	~NamedItemList()
	{
		ListNode*			tmp = m_pHead;

		while( tmp )
		{
			m_pHead = tmp->next;
			if( tmp->m_pobject )
				delete tmp->m_pobject;

			delete tmp;			
			tmp = m_pHead;
		}
	}

	TYPE* FindByName( TCHAR* name )
	{
		ListNode*			tmp = m_pHead;

		for( ; tmp && strcmpi( name, tmp->name ) ; tmp=tmp->next );

		if( tmp )
			return tmp->m_pobject;
		else
			return NULL;
	}

	TYPE* GetItem( int index )
	{
		ListNode*			tmp = m_pHead;

		for( int i = 0 ; tmp && i<index ; tmp=tmp->next, i++ );
		
		if( tmp )
			return tmp->m_pobject;
		else
			return NULL;
	}

	TCHAR*	GetName( int index )
	{
		ListNode*			tmp = m_pHead;

		for( int i = 0 ; tmp && i<index ; tmp=tmp->next, i++ );
		
		if( tmp )
			return tmp->name;
		else
			return NULL;
	}


	VOID AddItem( TYPE* item, TCHAR* name )
	{
		ListNode*			tmp = new ListNode;

		tmp->m_pobject = item;
		strcpy( tmp->name, name );

		if( !m_pHead )
		{
			tmp->next = NULL;
			tmp->prev = NULL;
			m_pHead = tmp;
		}
		else
		{
			for( ListNode* last = m_pHead ; last->next ; last = last->next );
			last->next = tmp;
			tmp->next = NULL;
			tmp->prev = last;
		}
	}

	VOID DeleteItem( TCHAR* name )
	{
		ListNode*			tmp = m_pHead;

		for( ; tmp && strcmpi( name, tmp->name ) ; tmp=tmp->next );

		if( !tmp )
			return;

		tmp->prev->next = tmp->next;
		tmp->next->prev = tmp->prev;

		if( tmp->m_pobject )
			delete m_pobject;

		delete tmp;
	}

	TYPE* RemoveItem( TCHAR* name )
	{
		ListNode*			tmp = m_pHead;
		TYPE*				object;

		for( ; tmp && strcmpi( name, tmp->name ) ; tmp=tmp->next );

		if( !tmp )
			return NULL;

		tmp->prev->next = tmp->next;
		tmp->next->prev = tmp->prev;

		object = tmp->m_pobject;

		delete tmp;

		return object;
	}		
};

template <class TYPE> class List 
{

private:

	class ListNode
	{
	public:		
		TYPE*			m_pobject;
		ListNode*		next;
		ListNode*		prev;
	};

	ListNode*		m_pHead;

public:

	List() : m_pHead(NULL)
	{
	}

	~List()
	{
		ListNode*			tmp = m_pHead;

		while( tmp )
		{
			m_pHead = tmp->next;			

			if( tmp->m_pobject )
				delete tmp->m_pobject;

			delete tmp;

			tmp = m_pHead;
		}
	}

	TYPE* GetItem( int index )
	{
		ListNode*			tmp = m_pHead;

		for( int i = 0 ; tmp && i<index ; tmp=tmp->next, i++ );

		if( tmp )
			return tmp->m_pobject;
		else
			return NULL;
	}

	VOID AddItem( TYPE* item )
	{
		ListNode*			tmp = new ListNode;

		tmp->m_pobject = item;		

		tmp->prev = NULL;
		tmp->next = m_pHead;
		if( m_pHead )
			m_pHead->prev = tmp;

		m_pHead = tmp;
	}

};

#endif
