// Choice.h : Declaration of the cChoice

#ifndef __CHOICE_H_
#define __CHOICE_H_

#include "resource.h"       // main symbols

#include "SinkImpl.h"
#include "DecalControlsCP.h"

/////////////////////////////////////////////////////////////////////////////
// cChoice
class ATL_NO_VTABLE cChoice : 
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<cChoice, &CLSID_Choice>,
	public IConnectionPointContainerImpl<cChoice>,
   public ILayerImpl< cChoice >,
   public ILayerRenderImpl,
   public ILayerMouseImpl,
   public ILayerSchema,
	public IControlImpl< cChoice, IChoice, &IID_IChoice, &LIBID_DecalControls >,
   public IProvideClassInfo2Impl< &CLSID_Choice, &DIID_IChoiceEvents, &LIBID_DecalControls >,
	public CProxyIChoiceEvents< cChoice >
{
public:
	cChoice();

   long m_nSelected;
   long m_nHotSelect;
   long m_nDropLines;

   struct cOption
   {
      _variant_t m_value;
      _bstr_t m_strText;
   };

   typedef std::deque< cOption > cOptionList;
   cOptionList m_options;

   CComPtr< IImageCache > m_pInactive;
   CComPtr< IFontCache > m_pFont;
   CComPtr< ILayerSite > m_pPopup;
   CComPtr< IScroller > m_pScroller;

   bool m_bMouseDown;
   bool m_bMouseOver;
   bool m_bPopup;

   void setPopup( bool bPopup );

   void onCreate();
   void onDestroy();

DECLARE_REGISTRY_RESOURCEID(IDR_CHOICE)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(cChoice)
   COM_INTERFACE_ENTRY(ILayerRender)
   COM_INTERFACE_ENTRY(ILayerMouse)
   COM_INTERFACE_ENTRY(ILayer)
   COM_INTERFACE_ENTRY(ILayerSchema)
	COM_INTERFACE_ENTRY(IChoice)
   COM_INTERFACE_ENTRY(IControl)
   COM_INTERFACE_ENTRY(IDispatch)
   COM_INTERFACE_ENTRY(IProvideClassInfo)
   COM_INTERFACE_ENTRY(IProvideClassInfo2)
	COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(cChoice)
CONNECTION_POINT_ENTRY(DIID_IChoiceEvents)
END_CONNECTION_POINT_MAP()

public:
	STDMETHOD(Clear)();
   // IChoice Methods
	STDMETHOD(get_Selected)(/*[out, retval]*/ long *pVal);
	STDMETHOD(put_Selected)(/*[in]*/ long newVal);
	STDMETHOD(get_Dropped)(/*[out, retval]*/ VARIANT_BOOL *pVal);
	STDMETHOD(put_Dropped)(/*[in]*/ VARIANT_BOOL newVal);
	STDMETHOD(RemoveChoice)(long nIndex);
	STDMETHOD(get_Text)(long nIndex, /*[out, retval]*/ BSTR *pVal);
	STDMETHOD(put_Text)(long nIndex, /*[in]*/ BSTR newVal);
	STDMETHOD(get_Data)(long nIndex, /*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_Data)(long nIndex, /*[in]*/ VARIANT newVal);
	STDMETHOD(get_ChoiceCount)(/*[out, retval]*/ long *pVal);
	STDMETHOD(AddChoice)(BSTR strDisplay, /*[optional]*/ VARIANT vData);
	STDMETHOD(get_DropLines)(/*[out, retval]*/ long *pVal);
	STDMETHOD(put_DropLines)(/*[in]*/ long newVal);

   // ILayerMouse Methods
   STDMETHOD(MouseDown)(MouseState *)
   {
      m_bMouseDown = true;
      m_pSite->Invalidate();

      return S_OK;
   }

   STDMETHOD(MouseEnter)(MouseState *pMS)
   {
      m_bMouseOver = true;
      m_pSite->Invalidate();

      return S_OK;
   }

   STDMETHOD(MouseExit)(MouseState *pMS)
   {
      m_bMouseOver = false;
      m_pSite->Invalidate();

      return S_OK;
   }

   STDMETHOD(MouseUp)(MouseState *pMS);

   // ILayerRender Methods
   STDMETHOD(Render)(ICanvas *pCanvas);
   STDMETHOD(Reformat)();

   // ILayerSchema Methods
   STDMETHOD(SchemaLoad)(IView *pView, IUnknown *pSchema);
};

#endif //__CHOICE_H_
