#pragma once

_ATL_FUNC_INFO _infoOnStatusMessage = { CC_STDCALL, VT_I4, 1,{ VT_DISPATCH } };
_ATL_FUNC_INFO _infoOnMessage = { CC_STDCALL, VT_I4, 1,{ VT_DISPATCH } };
_ATL_FUNC_INFO _infoOnLogin = { CC_STDCALL, VT_I4, 1,{ VT_I4 } };
_ATL_FUNC_INFO _infoOnConnectionLost = { CC_STDCALL, VT_I4, 0,{} };

IID DIID__ISrvrSessionEvents = __uuidof(_ISrvrSessionEvents);

class CSrvrSessionEvents : public IDispEventSimpleImpl<1, CSrvrSessionEvents, &DIID__ISrvrSessionEvents>
{
	CRITICAL_SECTION				m_CriticalSection;
public:
	bool							m_bConnect;

	CSrvrSessionEvents()
	{
		::InitializeCriticalSection(&m_CriticalSection);
	}

	BEGIN_SINK_MAP(CSrvrSessionEvents)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 1, OnLogin, &_infoOnLogin)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 2, OnConnectionLost, &_infoOnConnectionLost)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 3, OnMessage, &_infoOnMessage)
		SINK_ENTRY_INFO(1, DIID__ISrvrSessionEvents, 4, OnStatusMessage, &_infoOnStatusMessage)
	END_SINK_MAP()


	HRESULT  __stdcall OnStatusMessage(IDispatch* pMsg)
	{
		IStatusMessagePtr Sm(pMsg);
		printf("\tOnStatusMessage(%d, %d)[%d]\n", Sm->GetCode(), Sm->GetClass(), GetCurrentThreadId());
		return S_OK;
	}

	HRESULT  __stdcall OnLogin(long Result)
	{
		EnterCriticalSection(&m_CriticalSection);
		m_bConnect = true;
		LeaveCriticalSection(&m_CriticalSection);

		printf("\tOnLogin()[%d]\n", GetCurrentThreadId());
		return S_OK;
	}

	HRESULT  __stdcall OnConnectionLost(void)
	{
		EnterCriticalSection(&m_CriticalSection);
		m_bConnect = false;
		LeaveCriticalSection(&m_CriticalSection);

		printf("\tOnConnectionLost()[%d]\n", GetCurrentThreadId());
		return S_OK;
	}

	HRESULT  __stdcall OnMessage(IDispatch* pMsg)
	{
		printf("\tOnMessage()[%d]\n", GetCurrentThreadId());
		return S_OK;
	}
};