#pragma once

// Logging macro
#define ADDSTATUS(s, e) CStatusCtrl::Instance()->AddStatus(s, e)

#define WM_USER_StatusUpdate WM_USER + 0x2030

// Type of status messages
typedef enum 
{
	STATUSMSG_Status,
	STATUSMSG_Error,
	STATUSMSG_Receive,
	STATUSMSG_Send,
	STATUSMSG_Notif,
} TYPE_STATUS_MSG;

///////////////////////////////////////////////////////////////////////////////
///
///	Singleton class which manges the status control on the GUI.  Current
/// implementation relies on a CListCtrl.  Logging functionality is thread safe.		
///
///////////////////////////////////////////////////////////////////////////////
class CStatusCtrl
{
	friend class CGobiTestAppDlg;

public:
	///////////////////////////////////////////////////////////////////////////////
	///
	///	Creates and initializes instance of object.
	///
	///	\param	[IN] pStatusCtrl
	///			Pointer to status control to manage
	///
	///	\return	Instance of object if successfully initialized, NULL otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	static CStatusCtrl* Instance(CListCtrl* pStatusCtrl);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Returns instance of object.
	///
	///	\param	None
	///
	///	\return	Instance of object if successfully initialized, NULL otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	static CStatusCtrl* Instance();

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Destroys instance of object.
	///
	///	\param	None
	///
	///	\return	None			
	///
	///////////////////////////////////////////////////////////////////////////////
	static void DeleteInstance();

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Add text to status control.
	///
	///	\param	[IN] pszStatus
	///			String message to add to status control
	/// 
	/// \param [IN] eType
	///			Type of message to add
	///
	///	\return	TRUE if message successfully added to control, FALSE otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL AddStatus(const WCHAR* pszStatus, TYPE_STATUS_MSG eType = STATUSMSG_Status);

protected:
	CListCtrl* m_pStatusCtrl;		// pointer to status control
	CRITICAL_SECTION m_csStatus;	// critical section thread safety

	// structure of status item
	typedef struct STRUCT_StatusItem
	{
		TYPE_STATUS_MSG eMsgType;
		CString szStatusMsg;
	};

	// list of status items to be updated by GUI
	CList <STRUCT_StatusItem, STRUCT_StatusItem&> m_lstStatusItems;

	UINT m_nNumberLines;	// Number of lines in the status control
	BOOL m_bAutoScroll;		// Automatically scroll to end when new line is added

	CStatusCtrl(CWnd* pParent = NULL);   // standard constructor
	virtual ~CStatusCtrl();

	BOOL Initialize(CListCtrl* pStatusCtrl);

	// called by GUI thread to update control
	void UpdateStatus(void);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Format current local time in HH:MM:SS.sss format
	///
	///	\param	[IN] psBuffer
	///			Buffer for the output formatted string
	/// 
	/// \param	[IN] sizeBuffer
	///			Size of psBuffer
	///
	///	\return	TRUE if successfully formatted, FALSE otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	bool GetLocalTimeFormat(LPTSTR psBuffer, size_t sizeBuffer);

private:
	 static CStatusCtrl* s_Instance;	// Singleton instance

};
