#pragma once

//#pragma warning(disable : 4251)
#include <mutex>
#include "Aclapi.h"
#include "dt.h"

#ifdef SYSTEM_RESOURCE_EXPORTS
#define SYSTEM_RESOURCE_DLL_API __declspec(dllexport)
#else
#define SYSTEM_RESOURCE_DLL_API //__declspec(dllimport)
#endif

enum DEVICE_RUN_MODE { NONE = 0, AUTO = 1, DRY_RUN = 2,};

#define  BOND_KEY_START_EVENT  "Global\\__BOND_KEY_START__"
#define  BOND_KEY_STOP_EVENT  "Global\\__BOND_KEY_STOP__"

#define	CLOSE_EVENT(e)													\
	if (e) { CloseHandle(e);	e = NULL;}

#define	OPEN_EVENT(e,strName)											\
	(e) = OpenEvent(EVENT_ALL_ACCESS ,FALSE,strName);

#define	CREATE_EVENT(e, bManual, bInitState,strName)					\
	if ((e) == NULL) {													\
		(e) = ::CreateEventA(NULL, (bManual), (bInitState), strName);	\
	}																	\
	if ((e) != NULL) {													\
		if (bInitState == TRUE) {										\
			SetEvent(e);												\
		} else if(bInitState == FALSE) {								\
			ResetEvent(e);												\
		}																\
	}

#define	SET_EVENT(e)													\
	if (e)	SetEvent(e);

#define	RESET_EVENT(e)													\
	if (e)	ResetEvent(e);

#define	OPEN_BOND_KEY											\
	SystemResources::GetInstance()->OpenBondKey();

#define	SET_BOND_STOP_KEY											\
	SystemResources::GetInstance()->SetBondStartKey(false);

#define	SET_BOND_START_KEY											\
	SystemResources::GetInstance()->SetBondStartKey(true);

#define CHECK_STOP_KEY  \
	(SystemResources::GetInstance()->IsBondStartKey() == false)

#define CHECK_BOND_STOP_BREAK											\
	if (SystemResources::GetInstance()->IsBondStartKey() == false) {	break;	}

#define CHECK_BOND_STOP_RETURN											\
	if (SystemResources::GetInstance()->IsBondStartKey() == false) {	return STOP;	}

#define CHECK_BOND_STOP_RETURN_FAIL										\
	if (SystemResources::GetInstance()->IsBondStartKey() == false) {	return FAIL;}

#define CHECK_BOND_STOP_GOTO											\
	if (SystemResources::GetInstance()->IsBondStartKey() == false) {	goto DONE;	}

#define WAIT_EVENT(e,t)											\
	if(SystemResources::GetInstance()->WaitEvent(e,t)) {	return FAIL;};

#define CHECK_IS_DRY_RUN\
	SystemResources::GetInstance()->GetIsDryRunMode()

class SYSTEM_RESOURCE_DLL_API SystemResources
{
private:
	static SystemResources* m_pSysRes;
	static std::mutex m_Mutex;

	bool g_bPause;									//��ͣ����
	DEVICE_RUN_MODE g_eDeviceRunMode;				//�豸����ģʽ
	HANDLE g_hBondKeyStartEvent = NULL;				//�̾���ʼ�¼�
	HANDLE g_hBondKeyStopEvent = NULL;				//�̾�ֹͣ�¼�

	PTP_POOL sm_tPool;
	TP_CALLBACK_ENVIRON* m_tcEnv;
	void CreateThreadPool();

	SystemResources();

public:
	static SystemResources* GetInstance();

	bool IsBondStartKey();
	bool OpenBondKey();
	VOID SetBondStartKey(bool isStart);

	VOID SetDeviceRunMode(DEVICE_RUN_MODE bMode);
	bool GetIsDryRunMode();
	bool GetAutoMode();

	//������ͣ��־
	void SetPause(bool bPause);
	//��ȡ��ͣ��־
	bool GetPause();

	//��ȡ�̳߳���Դ
	TP_CALLBACK_ENVIRON* GetThreadPoolEnviron();
	LONG ThreadPoolWork(PTP_WORK_CALLBACK pfnwk, PVOID pv);
	bool WaitEvent(HANDLE hEvent, ULONG nWaitTime);
};