#if !defined(AFX_COMMANDS_H__INCLUDED_)
#define AFX_COMMANDS_H__INCLUDED_

// commands.h

extern CaplLog * MainModuleLog;


#define ID_TIMER_WAIT_DLG_OPERATE  10002
#define INTERVAL_TIMER_WAIT_DLG_OPERATE 50

#define ID_TIMER_TIMEOUT_DLG_OPERATE  10003
#define INTERVAL_TIMER_TIMEOUT_DLG_OPERATE 100

#define INTERVAL_TIMER_CLEANUP 100
#define INTERVAL_TIMER_PROC_SERVERS 10000

#define MAX_PORTION_SIZE 1048576
#define MIN_PORTION_SIZE 1024

#undef APL_THROW_LEVEL
#define APL_THROW_LEVEL SaplErrorDescriptionLevel_Transport

#define APL_TRANSPORT_THROW_O(err_code) {throw(SaplErrorDescription(err_code,_T(__FILE__),_T(__DATE__),__LINE__,_T(""),SaplErrorDescriptionLevel_Transport,__APL_FUNC__,m_class_info));}
#define APL_TRANSPORT_THROW(err_code) {m_LastWsaError=WSAGetLastError();throw(SaplErrorDescription(err_code,_T(__FILE__),_T(__DATE__),__LINE__,_T(""),SaplErrorDescriptionLevel_Transport,__APL_FUNC__,m_class_info));}
#define APL_TRANSPORT_THROW_EX(err_code,m_err_descr) {m_LastWsaError=WSAGetLastError();throw(SaplErrorDescription(err_code,_T(__FILE__),_T(__DATE__),__LINE__,m_err_descr,SaplErrorDescriptionLevel_Transport,__APL_FUNC__,m_class_info));}
#define APL_TRANSPORT_THROW_EX_SYS(err_code,descr) {CString sbuf;GetDescriptionSystemError(GetLastError(),sbuf);throw(SaplErrorDescription(err_code,_T(__FILE__),_T(__DATE__),__LINE__,descr+CString(_T(": "))+sbuf,SaplErrorDescriptionLevel_Transport,__APL_FUNC__,m_class_info));}


// имена для шар 
#define NAME_PSSGlobalServicesListMutex _T("Global\\PSSGlobalServicesListMutex")
#define NAME_PSSGlobalServicesListPregion _T("Global\\PSSGlobalServicesListPregion")
#define NAME_PSSGlobalServicesListMutexU _T("Global\\PSSGlobalServicesListMutexU")
#define NAME_PSSGlobalServicesListPregionU _T("Global\\PSSGlobalServicesListPregionU")

#define GLOBAL_SERVICES_LIST_BUFFER_SIZE 10000
#define GLOBAL_SERVICES_LIST_BUFFER_START_POS 4
// тайм-аут при ожидании что список изменился
#define GLOBAL_SERVICES_LIST_TIMEOUT 1000
#define GLOBAL_SERVICES_LIST_RELOAD_INTERVAL 1000


#define TEST_DISCONNECT( var ) (var==WSAENOTSOCK || var==WSAEOPNOTSUPP || var== WSAENETUNREACH ||  \
				var==WSAENETRESET || var==WSAECONNABORTED || var==WSAECONNRESET || var==WSAENOTCONN ||\
				var==WSAESHUTDOWN || var==WSAECONNREFUSED || var==WSAEHOSTDOWN)

#define LOG_ERROR(lpszFormat, ...)		    if(MainModuleLog!=0){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); \
		MainModuleLog->LogMessage(csInternText,false,true,true,true,__APL_FUNC__,(LPCTSTR)m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}

#define LOG_ERROR_ED(error)		    if(MainModuleLog!=0){MainModuleLog->LogMessage(error.m_err_descr,false,true,true,true,error.m_funct_name,error.m_cls_info,0,error.m_filename,error.m_datecompile,error.m_err_line);}
#define LOG_ERROR_P(pointer,text)		if(pointer!=0 && MainModuleLog!=0){MainModuleLog->LogMessage(text,false,true,true,true,__APL_FUNC__,(LPCTSTR)pointer->m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}
#define _LOG_WARN(lpszFormat, ...)		    if(MainModuleLog!=0){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); MainModuleLog->LogMessage(csInternText,true,true,true,true ,__APL_FUNC__,0,0,_T(__FILE__),_T(__DATE__),__LINE__);}
#define LOG_WARN(lpszFormat, ...)		    if(MainModuleLog!=0){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); MainModuleLog->LogMessage(csInternText,true,true,true,true ,__APL_FUNC__,(LPCTSTR)m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}
#define LOG_WARN_P(pointer,text)	if(pointer!=0 && MainModuleLog!=0){MainModuleLog->LogMessage(text,true,true,true,true,__APL_FUNC__,(LPCTSTR)pointer->m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}

#define LOG_WARN_C(lpszFormat, ...)	if(MainModuleLog!=0 && MainModuleLog->m_LogInfoLevel>=LogLevelFunctionInfo){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); MainModuleLog->LogMessage(csInternText,true,true,true,true,__APL_FUNC__,(LPCTSTR)m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}
#define LOG_WARN_B(lpszFormat, ...)	if(MainModuleLog!=0 && MainModuleLog->m_LogInfoLevel>=LogLevelFunctionInfo){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); MainModuleLog->LogMessage(csInternText,true,true,false,true,__APL_FUNC__,(LPCTSTR)m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}
#define LOG_WARN_C_P(pointer,lpszFormat, ...)	if(pointer!=0 && MainModuleLog!=0 && MainModuleLog->m_LogInfoLevel>=LogLevelFunctionInfo){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); MainModuleLog->LogMessage(csInternText,true,true,true,true,__APL_FUNC__,(LPCTSTR)(pointer->m_class_info),0,_T(__FILE__),_T(__DATE__),__LINE__);}

#define LOG_INFO(lpszFormat, ...)	if(MainModuleLog!=0 && MainModuleLog->m_LogInfoLevel>=LL_info){CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__); MainModuleLog->LogMessage(csInternText,true,true,false,true,__APL_FUNC__,(LPCTSTR)m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__);}

#define PRINT_ERROR_VIRTUAL \
	LOG_ERROR(APL_T("Вызвана виртуальная функция %s базового класса! \nНеобходимо правильно перегрузить ее в классе %s"), \
	__APL_FUNC__, (LPCTSTR)m_class_info); \



// Макросы для вывода в стандартный лог/стандартное окно DEBUG_OUTPUT отладчика 
// отладочных сообщений
// определения переменной типа long с именем ИМЯ_СЕКЦИИ+"_COUNTER"
// для переключения в отдладочный режим в настройках проекта вкладка C++
// должен быть определен макрос _DEBUG_LOG_MESSAGE
#ifdef _DEBUG_LOG_MESSAGE

#define LogMessageConditionFC(par1, mess)
#define LogDebugMessageIfDefG(message) _LOG_WARN(message);
#define LogDebugMessageIfDef(message) LOG_WARN(message);
#define LogDebugMessageIfDefFormat1(lpszFormat, ...) {CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__);LOG_WARN(csInternText);}
#define LogDebugMessageIfDefFormat2(lpszFormat, ...) {CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__);LOG_WARN(csInternText);}
#define LogDebugMessageIfDefFormat3(lpszFormat, ...) {CString csInternText(_T("")); csInternText.Format(lpszFormat, ##__VA_ARGS__);LOG_WARN(csInternText);}

#else // #ifdef _DEBUG_LOG_MESSAGE

#define LogMessageConditionFC(par1, mess)
#define LogDebugMessageIfDefG(message) 
#define LogDebugMessageIfDef(message) ;
#define LogDebugMessageIfDefFormat1(lpszFormat, ...) ;
#define LogDebugMessageIfDefFormat2(lpszFormat, ...) ;
#define LogDebugMessageIfDefFormat3(lpszFormat, ...) ;

//////// БЛЯЯЯ! Использовать только в дебаге - в релизе OutputDebugString меняет GetLastError на 2!!!!!
// #define LogDebugMessageIfDefG(message) OutputDebugString(message);
// #define LogDebugMessageIfDef(message) OutputDebugString(message);
// #define LogDebugMessageIfDefFormat1(text,par1) {CString cur_state;cur_state.Format(text,par1);OutputDebugString(cur_state);}
// #define LogDebugMessageIfDefFormat2(text,par1,par2) {CString cur_state;cur_state.Format(text,par1,par2);OutputDebugString(cur_state);}
// #define LogDebugMessageIfDefFormat3(text,par1,par2,par3) {CString cur_state;cur_state.Format(text,par1,par2,par3);OutputDebugString(cur_state);}

#endif //#ifdef _DEBUG_LOG_MESSAGE


// Макросы или просто выполняют работу с критическими секциями, или 
// выводят в стандартный лог сообщения о работе с секциями
// в отладочном режиме требует рядом с определением критической секции 
// определения переменной типа long с именем ИМЯ_СЕКЦИИ+"_COUNTER"
// для переключения в отдладочный режим в настройках проекта вкладка C++
// должен быть определен макрос _DEBUG_LOG_CRTITICAL_SECTION

#ifdef _DEBUG_LOG_CRTITICAL_SECTION 

#define EnterLogCriticalSection(par) {CString str;bool flag=true;\
	str.Format(_T("EnterCriticalSection(") _T(#par) _T("=%x) counter before %i .."),par,InterlockedExchangeAdd( par##_COUNTER,0));\
	LogDebugMessageReal(str,__APL_FUNC__,0,_T(__FILE__),_T(__DATE__),__LINE__);InterlockedExchangeAdd( par##_COUNTER,1);\
	EnterCriticalSectionODS(par);\
	str.Format(_T("							after  %i"),InterlockedExchangeAdd( par##_COUNTER,0));\
LogDebugMessageReal(str,__APL_FUNC__,0,_T(__FILE__),_T(__DATE__),__LINE__,false);}

#define LeaveLogCriticalSection(par) {CString str;\
	str.Format(_T("LeaveCriticalSection(") _T(#par) _T("=%x) counter before %i .."),par,InterlockedExchangeAdd( par##_COUNTER,0));\
	LogDebugMessageReal(str,__APL_FUNC__,0,_T(__FILE__),_T(__DATE__),__LINE__);InterlockedExchangeAdd( par##_COUNTER,-1);LeaveCriticalSection(par);\
	str.Format(_T("							after  %i"),InterlockedExchangeAdd( par##_COUNTER,0));\
LogDebugMessageReal(str,__APL_FUNC__,0,_T(__FILE__),_T(__DATE__),__LINE__);}

#define DeleteLogCriticalSection(par){CString str;\
	str.Format(_T("DeleteCriticalSection(") _T(#par) _T("=%x)"),par);\
	LogDebugMessageReal(str,__APL_FUNC__,0,_T(__FILE__),_T(__DATE__),__LINE__);\
DeleteCriticalSection(par);}

#define InitializeLogCriticalSection(par){CString str;\
	str.Format(_T("InitializeCriticalSection(") _T(#par) _T("=%x)"),par);\
	LogDebugMessageReal(str,__APL_FUNC__,0,_T(__FILE__),_T(__DATE__),__LINE__);\
InitializeCriticalSection(par);}

#else //#ifdef _DEBUG_LOG_CRTITICAL_SECTION 


#define EnterLogCriticalSection(par) EnterCriticalSectionODS(par)
#define LeaveLogCriticalSection(par) LeaveCriticalSectionODS(par)
#define DeleteLogCriticalSection(par) DeleteCriticalSection(par)
#define InitializeLogCriticalSection(par) InitializeCriticalSection(par)

#endif









#endif // #define AFX_COMMANDS_H__INCLUDED_
