// InputService.h : Declaration of the cInputService

#ifndef __INPUTSERVICE_H_
#define __INPUTSERVICE_H_

#include "resource.h"       // main symbols
#include <DecalImpl.h>

#include "WndMsg.h"

class cTimer;
class cHotkey;
class cWinMsgHook;
class cInputBuffer;

/////////////////////////////////////////////////////////////////////////////
// cInputService
class ATL_NO_VTABLE cInputService : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<cInputService, &CLSID_InputService>,
   public IDecalServiceImpl< cInputService >,
   public IDecalRenderImpl,
	public IDispatchImpl<IInputService, &IID_IInputService, &LIBID_DecalInput>
{
public:
	cInputService()
      : m_hWndHook( NULL ),
      m_pfnHook( NULL ),
      m_pnOffset1( NULL ),
      m_pnOffset2( NULL ),
      m_pMessage( NULL ),
      m_pActive( NULL )
	{
	}

   typedef std::map< _bstr_t, WORD > cCommandMap;
   cCommandMap m_commands;

   typedef std::list< cTimer * > cTimerList;
   cTimerList m_timers;

   typedef std::list< cHotkey * > cHotkeyList;
   cHotkeyList m_hotkeys;

   typedef std::list< cWinMsgHook * > cWinMsgHookList;
   cWinMsgHookList m_msghooks;

   CComObject< cWndMsg > *m_pMessage;

   HWND m_hWndHook;
   WNDPROC m_pfnHook;

   static LRESULT CALLBACK wndProc( HWND, UINT, WPARAM, LPARAM );

   enum eWindowsType
   {
      eWindowsNT,
      eWindows98WithMemLocs,
      eWindows98NoMemLocs
   };

   eWindowsType m_eWindows;
   long *m_pnOffset1,
      *m_pnOffset2;

   struct cActionType
   {
      TCHAR szAction[ 20 ];
      CLSID m_clsid;
   };

   typedef std::vector< cActionType > cActionTypeList;
   cActionTypeList m_actiontypes;

   cInputBuffer *m_pActive;

   static cInputService *g_p;

   HRESULT onInitialize();
   void onTerminate();

   // Key-name mapping
   struct cCharNames
   {
      LPCTSTR szName;
      WORD m_nVKey;
   };

   static cCharNames *begin_chars();
   static cCharNames *end_chars();
   static cCharNames *charFromVK( int nVK );
   static cCharNames *charFromName( LPCTSTR szName, int nLength );

DECLARE_REGISTRY_RESOURCEID(IDR_INPUTSERVICE)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(cInputService)
   COM_INTERFACE_ENTRY(IDecalRender)
   COM_INTERFACE_ENTRY(IDecalService)
	COM_INTERFACE_ENTRY(IInputService)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// IInputService
public:
	STDMETHOD(get_CommandKey)(BSTR strCommand, /*[out, retval]*/ long *pVal);
	STDMETHOD(get_KeyByName)(BSTR strName, /*[out, retval]*/ long *pVal);
	STDMETHOD(get_Decal)(/*[out, retval]*/ IDecal * *pVal);
	STDMETHOD(get_Command)(BSTR strCommandName, /*[out, retval]*/ BSTR *pVal);

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

   // IDecalRender
   STDMETHOD(Render2D)();
   STDMETHOD(ChangeHWND)();
};

#endif //__INPUTSERVICE_H_
