// NetService.h : Declaration of the cNetService

#ifndef __NETSERVICE_H_
#define __NETSERVICE_H_

#include "resource.h"       // main symbols

#include <DecalImpl.h>
#include "ProtocolStack.h"

class cMessage;

/////////////////////////////////////////////////////////////////////////////
// cNetService
class ATL_NO_VTABLE cNetService : 
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<cNetService, &CLSID_NetService>,
	public INetService,
   public IDecalServiceImpl< cNetService >,
   public IDecalDirectory,
   public ACMessageSink
{
public:
	cNetService()
	{
	}

   cMessageStack m_stack;

   // IDecalServiceImpl overrides
   HRESULT onInitialize();
   void onTerminate();

	CComPtr< IACHooks > m_pHooks;

	static cNetService *g_pService;
	typedef int (PASCAL *fn_recvfrom)(SOCKET, char FAR*, int , int, struct sockaddr FAR*, int FAR*);
	typedef int (PASCAL *fn_sendto)(SOCKET, const char FAR*, int , int, const struct sockaddr FAR*, int);
	static fn_recvfrom g_fn_recvfrom;
	static fn_sendto g_fn_sendto;

	// ACMessageSink overrides
   virtual void onMessage( ACMessage& );
	virtual void onMessageOut( ACMessage& );

	// The network filter list
	enum ePluginVersion { eVersion1, eVersion2 };
	struct cFilter
	{
		ePluginVersion m_ver;
		CLSID m_clsid;
		CComPtr< INetworkFilter2 > m_p;
	};

   typedef std::list< cFilter > cFilterList;
   cFilterList m_filters;

   // The message parsing container
   cMessage *m_pMessage;

DECLARE_REGISTRY_RESOURCEID(IDR_NETSERVICE)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(cNetService)
	COM_INTERFACE_ENTRY(INetService)
   COM_INTERFACE_ENTRY(IDecalService)
   COM_INTERFACE_ENTRY(IDecalDirectory)
END_COM_MAP()

public:
   // IDecalService
   STDMETHOD(BeforePlugins)();
   STDMETHOD(AfterPlugins)();

   // IDecalDirectory
   STDMETHOD(Lookup)(BSTR strName, IUnknown **ppvItf);

   // INetService
	STDMETHOD(get_Decal)(/*[out, retval]*/ IDecal * *pVal);
	STDMETHOD(get_Hooks)(IACHooks **pVal);
	STDMETHOD(get_Filter)(REFCLSID clsid, REFIID iid, /*[out, retval]*/ LPVOID *pVal);
	STDMETHOD(get_FilterVB)(BSTR strProgID, /*[out, retval]*/ LPDISPATCH *pVal);
};

#endif //__NETSERVICE_H_
