#pragma once

// CCPolhemusStatusBarActiveXControlCtrl : See CPolhemusStatusBarActiveXControlCtrl.cpp for implementation.

// Using this control in C#
//((System.ComponentModel.ISupportInitialize)(this.CPolhemus)).BeginInit();
//[...]
//this.CPolhemus.Visible = false;
//this.CPolhemus.Location = new System.Drawing.Point(0, 0);
//this.CPolhemus.Size = new System.Drawing.Size(0, 0 );
//this.CPolhemus.Enabled = true;
//this.CPolhemus.Name = "CPolhemus";
//this.CPolhemus.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("CPolhemus.OcxState")));
//this.CPolhemus.WM_CPOLHEMUS_STYLUSBTN_DATA += new AxCPolhemusStatusBarActiveXControlLib._DCPolhemusStatusBarActiveXControlEvents_WM_CPOLHEMUS_STYLUSBTN_DATAEventHandler(this.OnCpolhemusStylusbtnData);
//[...]
// this.Controls.Add(this.CPolhemus);
//((System.ComponentModel.ISupportInitialize)(this.CPolhemus)).EndInit();



// CPolhemusStatusBarActiveXControlCtrl.h : Declaration of the CCPolhemusStatusBarActiveXControlCtrl ActiveX Control class.

// PDI uses a circular buffer to store continuous motion data
// The polhemus patriot operates at 60 hz. The size of the data structure
// is the sum of the sizes of the frame components for a CPDImdat struct.
#define POLHEMUS_BUFFER_SIZE 0x2EE0 // = 12,000 bytes = 10 sec * 60Hz * ( 4b bool + 4b int + 4b float + 4b float + 4b float)


class CCPolhemusStatusBarActiveXControlCtrl : public COleControl
{
	DECLARE_DYNCREATE(CCPolhemusStatusBarActiveXControlCtrl)

private:

	/* Polhemus stuff */
	// the PDI device
	CPDIdev polhemus;
	// configuration for the PDI
	CPDImdat m_pdiMDat;
	// the size of a motion frame
	int m_dwFrameSize;
	// PDI's circular buffer
	BYTE g_pMotionBuf[POLHEMUS_BUFFER_SIZE];

	/* Internal connection management stuff */
	// Timer to check status of connection if in autoconnect mode
	UINT_PTR up_PolhemusStatusTimer;
	// true when connected
	BOOL bIsPolhemusConnected;
	// true when we've seen a frame without a stylus marker
	BOOL stylusButtonReleased;
	// the frame count from the hardware
	DWORD hardwareFrameCount;
	// hardware frame count checks
	DWORD lastHardwareFrameCount;
	// the frame count from the PDI software checks
	DWORD lastSoftwareFrameCount;

	// Initialize a new connection
	void BuildUpPolhemus();
	// Exit or tear down a stale connection
	void TearDownPolhemus();
	// returns true if the device is connected
	BOOL IsPolhemusConnected();

public:
	// Constructor
	CCPolhemusStatusBarActiveXControlCtrl();

	// THESE ARE EVENTS & DISPATCHES, must match .IDL file
	enum { 
		dispidIsConnected = 5L,		
		dispidAutoReconnectPolhemus = 4L,		
		dispidConnectPolhemus = 3L,		
		dispidDisconnect = 2L,		
		dispidGetStylusPosition = 1L,		
		eventidWM_CPOLHEMUS_STYLUSBTN_DATA	=	1L,
	};

	// handlers for windows events/messages
	afx_msg int  OnCreate( LPCREATESTRUCT );
	afx_msg void OnDestroy();
	afx_msg void AboutBox();
	afx_msg void OnTimer(UINT nIDEvent);

	// handlers for PDI events/messages
	afx_msg LRESULT	OnRawDataReady		( WPARAM wP, LPARAM lP );
	afx_msg LRESULT	OnDataStarted		( WPARAM wP, LPARAM lP );
	afx_msg LRESULT	OnDataStopped		( WPARAM wP, LPARAM lP );
	afx_msg LRESULT	OnDataError 		( WPARAM wP, LPARAM lP );
	afx_msg LRESULT	OnDataWarning 		( WPARAM wP, LPARAM lP );

protected:
	// destructor
	~CCPolhemusStatusBarActiveXControlCtrl();

	// dispatch function that returns the stylus' current cartesian
	// postion into memory locations passed by caller
	HRESULT GetStylusPosition( FLOAT* _x, FLOAT* _y, FLOAT* _z );
	void DisconnectPolhemus(void);
	void ConnectPolhemus(void);

	void OnAutoReconnectPolhemusChanged(void);
	LONG m_AutoReconnectPolhemus;

	void OnIsConnectedChanged(void);
	LONG m_IsConnected;

	// call to fire an event, used when stylus button is detected
	void WM_CPOLHEMUS_STYLUSBTN_DATA(FLOAT x, FLOAT y, FLOAT z);

	// Standard Ole Control stuff
	DECLARE_OLECREATE_EX(CCPolhemusStatusBarActiveXControlCtrl)		// Class factory and guid
	DECLARE_OLETYPELIB(CCPolhemusStatusBarActiveXControlCtrl)		// GetTypeInfo
	DECLARE_PROPPAGEIDS(CCPolhemusStatusBarActiveXControlCtrl)		// Property page IDs
	DECLARE_OLECTLTYPE(CCPolhemusStatusBarActiveXControlCtrl)		// Type name and misc status

	// Subclassed control support
	//BOOL IsSubclassedControl();
	LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);


	// Declare message map
	DECLARE_MESSAGE_MAP()

	// Declare dispatch map
	DECLARE_DISPATCH_MAP()

	// Declare event map
	DECLARE_EVENT_MAP()

};


