// ListTempl.h: interface for the CListTempl class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_LISTTEMPL_H__3B70A043_FB73_4769_9E8D_EEBFA29D5915__INCLUDED_)
#define AFX_LISTTEMPL_H__3B70A043_FB73_4769_9E8D_EEBFA29D5915__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <afxtempl.h>
template<class TYPE>
class CPtrTempl  
{
public:
	BOOL Find( TYPE p)
	{
		for( int i = 0 ; i<= m_Data.GetUpperBound() ; i ++ )
		{
			if( (TYPE)(m_Data.GetAt(i)) == p ) return TRUE;
		}
		return FALSE;
	};
	int GetFirstIdx( TYPE p )
	{
		for( int i = 0 ; i<= m_Data.GetUpperBound() ; i ++ )
		{
			if( (TYPE)(m_Data.GetAt(i)) == p ) return i;
		}
		return -1;
	};
	int GetSize(){return m_Data.GetSize();};
	int GetUpperBound(){return m_Data.GetUpperBound();}
	void SetSize(int nNewSize, int nGrowBy = -1){m_Data.SetSize( nNewSize , nGrowBy );}
	void FreeExtra( ){m_Data.FreeExtra();}
	void RemoveAll(){m_Data.RemoveAll();}
	TYPE GetAt( int idx ){ return (TYPE)m_Data.GetAt( idx ) ; }
	void SetAt( int nIndex, TYPE newElement ){ m_Data.SetAt( nIndex, newElement ); }
	TYPE &ElementAt( int idx ) { return m_Data.ElementAt( idx ) ; }
	TYPE* GetData(){ return (TYPE*)m_Data.GetData(); }
	void Add(TYPE e ){ if( !Find( e ) ) m_Data.Add( e ) ; }
	void add(TYPE e ){ m_Data.Add( e ) ; }
	void InsertAt( int nIndex, TYPE newElement, int nCount = 1 )
	{
		m_Data.InsertAt( nIndex , newElement , nCount );
	}

	void Remove(TYPE p )
	{
		for( int i = 0 ; i<= m_Data.GetUpperBound() ; i ++ )
		{
			if( (TYPE)(m_Data.GetAt(i)) == p ) 
			{
				m_Data.RemoveAt(i);
				return;
			}
		}
	}

	void RemoveAt( int nIndex, int nCount = 1 )
	{
		m_Data.RemoveAt( nIndex , nCount );
	}
	CPtrTempl(){};
	virtual ~CPtrTempl(){RemoveAll();}
private:
	CPtrArray m_Data;
};

template<class TYPE>
class CPtrStack  
{
public:
	BOOL Pop( TYPE&val )
	{
		if( m_Data.GetUpperBound() >= 0 )
		{
			val = (TYPE)m_Data.GetAt( m_Data.GetUpperBound() );
			m_Data.RemoveAt( m_Data.GetUpperBound() );
			return TRUE;
		}
		else
			return FALSE;
	};
	BOOL GetTop( TYPE&val)
	{
		if( m_Data.GetUpperBound() >= 0 )
		{
			val = (TYPE)m_Data.GetAt( m_Data.GetUpperBound() );
			return TRUE;
		}
		else
			return FALSE;
	};

	void Push( TYPE val )
	{
		add( val );
	};

	BOOL Find( TYPE p)
	{
		for( int i = 0 ; i<= m_Data.GetUpperBound() ; i ++ )
		{
			if( (TYPE)(m_Data.GetAt(i)) == p ) return TRUE;
		}
		return FALSE;
	};
	
	void Remove( TYPE p)
	{
		for( int i = 0 ; i<= m_Data.GetUpperBound() ; i ++ )
		{
			if( (TYPE)(m_Data.GetAt(i)) == p ) break;
		}
		m_Data.RemoveAt(i);
		return;
	};

	int GetSize(){return m_Data.GetSize();};
	int GetUpperBound(){return m_Data.GetUpperBound();}
	void SetSize(int nNewSize, int nGrowBy = -1){m_Data.SetSize( nNewSize , nGrowBy );}
	void FreeExtra( ){m_Data.FreeExtra();}
	void RemoveAll(){m_Data.RemoveAll();}
	TYPE GetAt( int idx ){ return (TYPE)m_Data.GetAt( idx ) ; }
	void SetAt( int nIndex, TYPE newElement ){ m_Data.SetAt( nIndex, newElement ); }
	TYPE &ElementAt( int idx ) { return m_Data.ElementAt( idx ) ; }
	TYPE* GetData(){ return (TYPE*)m_Data.GetData(); }
	void Add(TYPE e ){ if( !Find( e ) ) m_Data.Add( e ) ; }
	void add(TYPE e ){ m_Data.Add( e ) ; }
	void InsertAt( int nIndex, TYPE newElement, int nCount = 1 )
	{
		m_Data.InsertAt( nIndex , newElement , nCount );
	}
	void RemoveAt( int nIndex, int nCount = 1 )
	{
		m_Data.RemoveAt( nIndex , nCount );
	}
	CPtrStack(){};
	virtual ~CPtrStack(){RemoveAll();}
private:
	CPtrArray m_Data;
};

template<class TYPE>
class CObjTempl  
{
public:
	int GetSize(){return m_Data.GetUpperBound()+1;}
	void RemoveAll(){
		for( int i = 0 ; i <= m_Data.GetUpperBound() ; i ++ )
		{
			TYPE* p = (TYPE*) m_Data.GetAt( i );
			delete p;
		}
		m_Data.RemoveAll();
	}
	int Find( TYPE &ele )
	{
		for( int i = 0 ; i <= m_Data.GetUpperBound() ; i ++ )
		{
			TYPE *rlt;
			rlt = (TYPE*)m_Data.GetAt( i );
			if( *rlt == ele )return i;
		}
		return -1;
	};
	TYPE GetAt( int idx )
	{
		TYPE* rlt;
		rlt = (TYPE*)m_Data.GetAt( idx );
		return *rlt ; 
	}
	void SetAt( int nIndex, TYPE &newElement )
	{
		TYPE *rlt = (TYPE*)m_Data.GetAt( nIndex );
		delete rlt;
		rlt = new TYPE;
		*rlt = newElement;
		m_Data.SetAt( nIndex, rlt ); 
	}
	void Add(TYPE &e ){ TYPE* rlt = new TYPE;*rlt = e;m_Data.Add(rlt) ; }
	void InsertAt( int nIndex, TYPE newElement)
	{
		TYPE* rlt = new TYPE;
		*rlt = newElement;
		m_Data.InsertAt( nIndex , rlt , 1 );
	}
	void RemoveAt( int nIndex )
	{
		TYPE *rlt = (TYPE*)m_Data.GetAt( nIndex );
		delete rlt;
		m_Data.RemoveAt( nIndex );
	}
	CObjTempl(){};
	CObjTempl(CObjTempl<TYPE> &list)
	{
		for(int i = 0 ; i < list.GetSize() ; i ++ )
		{
			TYPE e = list.GetAt( i );
			Add( e );
		}
	};
	operator=(CObjTempl<TYPE> &list)
	{
		m_Data.RemoveAll();
		for(int i = 0 ; i < list.GetSize() ; i ++ )
		{
			TYPE e = list.GetAt( i );
			Add( e );
		}
	}
	virtual ~CObjTempl(){RemoveAll();}
private:
	CPtrArray m_Data;
};
#endif // !defined(AFX_LISTTEMPL_H__3B70A043_FB73_4769_9E8D_EEBFA29D5915__INCLUDED_)
