#pragma once

#include "LinkList.h"

namespace FDK
{
	template <class T, bool NULLABLE = FALSE> 
	private class ComPtrList : public LinkList<T*>
	{
	public:
		typedef T *Ptr;
		
		void Clear()
		{
			LinkList<Ptr>::Clear( ComAutoRelease() );
		}
		~ComPtrList()
		{
			this->Clear();
		}
	
	protected:
		
		HRESULT InsertAfter( Ptr item, Node *pBefore )
		{
			// NULLABLE = TRUE でないなら NULL アイテムは許可しない。
			if( !item && !NULLABLE )
				return E_POINTER;
			
			if( item )
				item->AddRef();
			
			HRESULT hr = LinkList<Ptr>::InsertAfter( item, pBefore );
			if( FAILED( hr ) )
				SAFE_COM_RELEASE( item );
			
			return hr;
		}
		HRESULT GetItem( const Node *pNode, Ptr *ppItem )
		{
			Ptr pItem = NULL;
			
			// 親クラス(List<>)は、AddRef() せずにアイテムを返してくる。なので、ここで AddRef() する。
			
			HRESULT hr = LinkList<Ptr>::GetItem( pNode, &pItem );
			
			if (SUCCEEDED(hr))
			{
				if( pItem )
				{
					*ppItem = pItem;
					(*ppItem)->AddRef();
				}
			}
			return hr;
		}
		HRESULT RemoveItem( Node *pNode, Ptr *ppItem )
		{
			// ppItem が非 NULL なら AddRef() して返す。

			Ptr pItem = NULL;

			HRESULT hr = LinkList<Ptr>::RemoveItem( pNode, &pItem );
			
			if( SUCCEEDED( hr ) )
			{
				if( ppItem && pItem )
				{
					*ppItem = pItem;
					(*ppItem)->AddRef();
				}
				SAFE_COM_RELEASE( pItem );
			}
			
			return hr;
		}
	};


	// ビデオサンプルのリスト

	typedef ComPtrList<IMFSample>	CVideoSampleList;
}
