#include "StdAfx.h"
#include ".\mysink.h"
#include ".\mylistener.h"
#include ".\comevtclient.h"

#include "../../Strawberry.h"

//////////////////
// Handy class to enumerate ConnectionPoints
class CConnectionPointsIterator 
{
protected:
	CComPtr<IEnumConnectionPoints> m_ConnectionPoints;
	const CComPtr<IConnectionPointContainer> m_ConnPtContainer;
public:
	CConnectionPointsIterator(CComPtr<IConnectionPointContainer> ConnPtContainer)
		: m_ConnPtContainer(ConnPtContainer)
	{
		HRESULT hr = ConnPtContainer->EnumConnectionPoints(&m_ConnectionPoints);
		ASSERT(SUCCEEDED(hr));
	};

	inline BOOL Next(CComPtr<IConnectionPoint>& ConnectionPoint)
	{
		ConnectionPoint.Release();
		ULONG nRet=0;
		return SUCCEEDED(m_ConnectionPoints->Next(1, &ConnectionPoint, &nRet)) && nRet==1;
	};
};


//
ComSupport::CComEvtClient::CComEvtClient()
{
}

ComSupport::CComEvtClient::~CComEvtClient()
{
	for(POSITION pos = m_map.GetStartPosition(); pos != NULL; )
	{
		DWORD dwObjID;
		void* p_arr_ptr_Listers = NULL;
		m_map.GetNextAssoc( pos, (void*&)dwObjID, p_arr_ptr_Listers );
		DetachEvents(dwObjID);
   }
}


BOOL ComSupport::CComEvtClient::AttachEvents(DWORD dwObjID, LPDISPATCH lpdisp )
{
	if( m_map[(void*)dwObjID] != NULL)
		return FALSE;

	m_map[(void*)dwObjID] = new CPtrArray();

	CComPtr<IDispatch> obj(lpdisp);
	CComQIPtr<IConnectionPointContainer> m_ConnPtContainer(obj);
	if(m_ConnPtContainer == NULL)
		return TRUE;//there are no conection points
	
	CConnectionPointsIterator it(m_ConnPtContainer);
	for(CComPtr<IConnectionPoint> spConnectionPoint; it.Next(spConnectionPoint); )
	{
		CMyListener* p = new CMyListener();
		BOOL bRes = p->Create(this, spConnectionPoint, obj, dwObjID);
		if(bRes)
			((CPtrArray*)(m_map[(void*)dwObjID]))->Add(p);
	}//for
	return TRUE;
};


BOOL ComSupport::CComEvtClient::DetachEvents(DWORD dwObjID)
{
	CPtrArray* p_arr_ptr_Listers = static_cast< CPtrArray* >(m_map[(void*)(dwObjID)]);
	if( p_arr_ptr_Listers == NULL)
		return FALSE;
	CPtrArray& arr_ptr_Listers = *p_arr_ptr_Listers;

	if(! arr_ptr_Listers.IsEmpty())
	{
		
		INT_PTR nCount = arr_ptr_Listers.GetCount();
		for(int i=0; i<nCount; i++)
		{
			CMyListener* pListener = static_cast< CMyListener* >(arr_ptr_Listers[i]);
			delete pListener;
			arr_ptr_Listers[i]=NULL;
		}//for i
		arr_ptr_Listers.RemoveAll();
	}//if not empty

	delete p_arr_ptr_Listers;
	m_map.RemoveKey( (void*)(dwObjID) );
	return TRUE;
};



HRESULT ComSupport::CComEvtClient::OnEvent(
	DWORD dwObjID,
	const _bstr_t& strCP_Name,
	const _bstr_t& strIdMember,
	const CArray<CComVariant,CComVariant&>& arrArgs)
{
	//AfxMessageBox("event received from CP:" + strCP_Name+" method:"+ strIdMember );
	MitiText((const char*)("event received from CP:" + strCP_Name+" method:"+ strIdMember)); 
	return S_OK;
}