// BarLayer.h : Declaration of the cBarLayer

#ifndef __BARLAYER_H_
#define __BARLAYER_H_

#include "resource.h"		// main symbols

#include "SinkImpl.h"

// Control IDs
#define PAGER_CLIENT 1
#define BUTTON_BACK 2
#define BUTTON_FORWARD 3
#define BUTTON_MINMAX 4
#define BUTTON_DOCKCYCLE 5

/////////////////////////////////////////////////////////////////////////////
// cBarLayer
class ATL_NO_VTABLE cBarLayer : 
	public CComObjectRootEx<CComMultiThreadModel>,
	public ILayerImpl< cBarLayer >,
	public ILayerRenderImpl,
	public IBarManager,
	public ICommandEventsImpl< BUTTON_BACK, cBarLayer >,
	public ICommandEventsImpl< BUTTON_FORWARD, cBarLayer >,
	public ICommandEventsImpl< BUTTON_MINMAX, cBarLayer >,
	public ICommandEventsImpl< BUTTON_DOCKCYCLE, cBarLayer >,
	public ILayerMouseImpl,
	public cNoEventsImpl,
	public IPagerEventsImpl< PAGER_CLIENT, cBarLayer >
{
public:
	cBarLayer();

	// Important child objects
	CComPtr< IPluginSite > m_pPlugin;
	CComPtr< IACHooks > m_pHooks;
	CComPtr< IPager > m_pPager;
	CComPtr< IButton > m_pBtnForwards,
		m_pBtnBackwards, m_pBtnMinMax, m_pBtnDockCycle;

	CComPtr< IImageCache > m_pBackground;

	// This the the list of bars
	typedef std::vector< long > cOffsetList;
	cOffsetList m_offsets;
	unsigned long m_nPosition;
	unsigned long m_nMinMax;

	long m_DeltaX;
	long m_DeltaY;
	long m_nScreenWidth;
	long m_nScreenHeight;
	//long m_TotalDelta;
	long *m_p3DH;
	long *m_p3DW;

	long m_nBarStartPos;
	long m_nBarLength;

	int m_nDragging;
	int m_nBarDock;
	bool m_bRadarDraw;
	bool m_bButtonDown;
	bool m_bLocked;
	bool m_bDocked;

	void onCreate();
	void onDestroy();

BEGIN_COM_MAP(cBarLayer)
	COM_INTERFACE_ENTRY(ILayer)
	COM_INTERFACE_ENTRY(ILayerRender)
	COM_INTERFACE_ENTRY(ILayerMouse)
	COM_INTERFACE_ENTRY(IBarManager)
END_COM_MAP()

BEGIN_SINK_MAP(cBarLayer)
	SINK_ENTRY_EX( BUTTON_BACK, DIID_ICommandEvents, DISPID_HIT, onCommandHit )
	SINK_ENTRY_EX( BUTTON_BACK, DIID_ICommandEvents, DISPID_UNHIT, onCommandUnhit )
	SINK_ENTRY_EX( BUTTON_FORWARD, DIID_ICommandEvents, DISPID_HIT, onCommandHit )
	SINK_ENTRY_EX( BUTTON_FORWARD, DIID_ICommandEvents, DISPID_UNHIT, onCommandUnhit )
	SINK_ENTRY_EX( BUTTON_MINMAX, DIID_ICommandEvents, DISPID_HIT, onMinMaxHit )
	SINK_ENTRY_EX( BUTTON_DOCKCYCLE, DIID_ICommandEvents, DISPID_HIT, onDockCycleHit )
	SINK_ENTRY_EX( PAGER_CLIENT, DIID_IPagerEvents, DISPID_GETNEXTPOSITION, onClientGetNextPosition )
END_SINK_MAP()

public:
	// IBarManager
	STDMETHOD(get_Bar)(long nViewID, /*[out, retval]*/ ViewParams *pVal);
	STDMETHOD(put_Bar)(long nViewID, /*[in]*/ ViewParams * newVal);
	STDMETHOD(RemoveBar)(long nViewID);
	STDMETHOD(AddBar)(long nViewID, ViewParams *pParams);

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

	// Button Back and Forward event handlers
	void __stdcall onCommandHit( long nID )
	{
		m_bButtonDown = TRUE;
		m_pPager->put_Command( nID );
	}

	void __stdcall onCommandUnhit( long )
	{
		m_bButtonDown = FALSE;
		m_bLocked = FALSE;
		m_pPager->FinishCommand();
	}

	void __stdcall onMinMaxHit(long nID);
	void __stdcall onDockCycleHit(long nID);

	// Pager event handlers
	VARIANT_BOOL __stdcall onClientGetNextPosition( long nID, long nCommand, long *pnX, long *pnY );
	STDMETHOD(MouseEvent)(long nMsg, long wParam, long lParam);
};

#endif //__BARLAYER_H_
