/*
Sauf mention contraire, la documentation et les binaires inclus dans la librairie WinLog
sont protégés par Phoenix Team.

Copyright © 2007-2011 Phoenix Team. Tous droits réservés.

Ce logiciel est fournit "en l'état", sans aucune garantie ni implicite ni explicite.
En aucune manière, les auteurs ne pourraient être tenus pour responsables des dommages
causés par l'usage de ce logiciel.

Tout le monde a la permission d'utiliser ce logiciel pour quelque usage que ce soit
même commercial, de le modifier et de le redistribuer pourvu que les conditions
suivantes soient remplies :

	Toute redistribution des codes sources doit conserver sans modification la mention
	de copyright présente.

	Toute redistribution sous forme binaire doit conserver sans modification la mention
	de copyright actuelle ainsi que les adresses de sites web déjà en place (dans la boîte
	de dialogue " A propos de... " par exemple).

	L'origine de ce logiciel ne doit pas être cachée; vous ne pouvez pas dire que vous avez
	écrit ce logiciel. Si vous utilisez ce logiciel pour distribuer un produit, un
	remerciement dans la documentation du produit serait apprécié mais n'est pas obligatoire.

	Toute version modifiée des sources ou des binaires doit être clairement identifiée et ne
	doit pas être présentée comme étant le logiciel original. 

*/

/*
Historique des versions

	Version 1.2 : 13 juin 2011
		Les champs date et heure des messages peuvent être en heure UTC ou bien en heure locale.
		Ajout des fonction WinLogSetUtcTime() et WinLogSetLocalTime()

	Version 1.1 : 6 décembre 2010
		Le champs DateTime de la structure WinLogCallBack_Info_t est maintenant un long long (64 bits) et plus un long (32 bits)
		Passage de la bibliothèque en 32 bits et en 64 bits

	Version 1.0 : 9 février 2009
*/

#ifndef WINLOG_INCLUDED
#define WINLOG_INCLUDED

#pragma comment ( lib , "Ws2_32.lib")
#pragma comment ( lib , "Iphlpapi.lib")

#ifdef GENERATE_WINLOG
#define EXPORT_WINLOG __declspec(dllexport)
#else
#define EXPORT_WINLOG __declspec(dllimport)

#ifdef _DEBUG
	#ifdef WIN64
		#pragma comment ( lib , "../../temp/Exe/Debug/x64/WinLog.lib")
	#else
		#pragma comment ( lib , "../../temp/Exe/Debug/x32/WinLog.lib")
	#endif
#else
	#ifdef WIN64
		#pragma comment ( lib , "../../temp/Exe/Release/x64/WinLog.lib")
	#else
		#pragma comment ( lib , "../../temp/Exe/Release/x32/WinLog.lib")
	#endif
#endif /* #ifdef _DEBUG */

#endif /* #ifdef GENERATE_WINLOG */

/* convention d'appel des fonctions */
#define CALL_CONVENTION __cdecl

/* utilisation des paramètres */
/* PARAM_IN, c'est un paramètre en entrée seulement */
/* PARAM_OUT, c'est un paramètre en sortie seulement */
/* PARAM_IN_OUT, c'est un paramètre en entrée et sortie */
#define PARAM_IN
#define PARAM_OUT
#define PARAM_IN_OUT

typedef enum WinLogRet_t
{	WINLOG_OK,
	WINLOG_NULLPTR,
	WINLOG_ALREADY_REGISTER,
	WINLOG_NOT_REGISTER,
	WINLOG_TRANSLATE_UTF8,
	WINLOG_BAD_FOLDER_NAME,
	WINLOG_REENTRANCY,
} WinLogRet_t;

typedef enum WinLogType_t
{	WinLog_Info,
	WinLog_User,
	WinLog_Warning,
	WinLog_Error,
	WinLog_Fatal,
	WinLog_Dump,
} WinLogType_t;

typedef struct WinLogCallBack_Info_t
{	unsigned long MesgIdentifier;
	const wchar_t *ProcessName;
	WinLogType_t Type;
	unsigned long Level;
	long long DateTime;
	unsigned long ProcessIdentifier;
	unsigned long ThreadIdentifier;
	wchar_t *Header;
	wchar_t *Message;
} WinLogCallBack_Info_t;

typedef EXPORT_WINLOG void (*WinLogCallBack_t)(WinLogCallBack_Info_t * CallbackInfo);

#define WINLOG_LEVEL_00 0x00000000
#define WINLOG_LEVEL_01 0x00000001
#define WINLOG_LEVEL_02 0x00000002
#define WINLOG_LEVEL_03 0x00000004
#define WINLOG_LEVEL_04 0x00000008
#define WINLOG_LEVEL_05 0x00000010
#define WINLOG_LEVEL_06 0x00000020
#define WINLOG_LEVEL_07 0x00000040
#define WINLOG_LEVEL_08 0x00000080
#define WINLOG_LEVEL_09 0x00000100
#define WINLOG_LEVEL_10 0x00000200
#define WINLOG_LEVEL_11 0x00000400
#define WINLOG_LEVEL_12 0x00000800
#define WINLOG_LEVEL_13 0x00001000
#define WINLOG_LEVEL_14 0x00002000
#define WINLOG_LEVEL_15 0x00004000
#define WINLOG_LEVEL_16 0x00008000
#define WINLOG_LEVEL_17 0x00010000
#define WINLOG_LEVEL_18 0x00020000
#define WINLOG_LEVEL_19 0x00040000
#define WINLOG_LEVEL_20 0x00080000
#define WINLOG_LEVEL_21 0x00100000
#define WINLOG_LEVEL_22 0x00200000
#define WINLOG_LEVEL_23 0x00400000
#define WINLOG_LEVEL_24 0x00800000
#define WINLOG_LEVEL_25 0x01000000
#define WINLOG_LEVEL_26 0x02000000
#define WINLOG_LEVEL_27 0x04000000
#define WINLOG_LEVEL_28 0x08000000
#define WINLOG_LEVEL_29 0x10000000
#define WINLOG_LEVEL_30 0x20000000
#define WINLOG_LEVEL_31 0x40000000
#define WINLOG_LEVEL_32 0x80000000

/* environment variable */
#define ENV_WINLOG_FILE_ENABLED		L"WINLOG_FILE_ENABLED"
#define ENV_WINLOG_FILE_FOLDER		L"WINLOG_FILE_FOLDER"
#define ENV_WINLOG_FILE_SIZEMAX		L"WINLOG_FILE_SIZEMAX"
#define ENV_WINLOG_FILE_HISTORYSIZE	L"WINLOG_FILE_HISTORYSIZE"

#define ENV_WINLOG_OUTPUT_ENABLED	L"WINLOG_OUTPUT_ENABLED"
#define ENV_WINLOG_PIPE_ENABLED		L"WINLOG_PIPE_ENABLED"
#define ENV_WINLOG_PIPE_NAME			L"WINLOG_PIPE_NAME"

#define ENV_WINLOG_FEATURE_LEVEL		L"WINLOG_FEATURE_LEVEL"

#define ENV_WINLOG_SYSLOG_ENABLED	L"WINLOG_SYSLOG_ENABLE"
#define ENV_WINLOG_SYSLOG_SERVER		L"WINLOG_SYSLOG_SERVER"
#define ENV_WINLOG_SYSLOG_PORT		L"WINLOG_SYSLOG_PORT"
#define ENV_WINLOG_SYSLOG_FACILITY	L"WINLOG_SYSLOG_FACILITY"

#define INFO1(p1)						WinLog(WinLog_Info, WINLOG_LEVEL_00, p1)
#define INFO2(p1,p2)					WinLog(WinLog_Info, WINLOG_LEVEL_00, p1, p2)
#define INFO3(p1,p2,p3)				WinLog(WinLog_Info, WINLOG_LEVEL_00, p1, p2, p3)
#define INFO4(p1,p2,p3,p4)			WinLog(WinLog_Info, WINLOG_LEVEL_00, p1, p2, p3, p4)
#define INFO5(p1,p2,p3,p4,p5)		WinLog(WinLog_Info, WINLOG_LEVEL_00, p1, p2, p3, p4, p5)

#define USER1(p1)						WinLog(WinLog_User, WINLOG_LEVEL_00, p1)
#define USER2(p1,p2)					WinLog(WinLog_User, WINLOG_LEVEL_00, p1, p2)
#define USER3(p1,p2,p3)				WinLog(WinLog_User, WINLOG_LEVEL_00, p1, p2, p3)
#define USER4(p1,p2,p3,p4)			WinLog(WinLog_User, WINLOG_LEVEL_00, p1, p2, p3, p4)
#define USER5(p1,p2,p3,p4,p5)		WinLog(WinLog_User, WINLOG_LEVEL_00, p1, p2, p3, p4, p5)

#define WARNING1(p1)					WinLog(WinLog_Warning, WINLOG_LEVEL_00, p1)
#define WARNING2(p1,p2)				WinLog(WinLog_Warning, WINLOG_LEVEL_00, p1, p2)
#define WARNING3(p1,p2,p3)			WinLog(WinLog_Warning, WINLOG_LEVEL_00, p1, p2, p3)
#define WARNING4(p1,p2,p3,p4)		WinLog(WinLog_Warning, WINLOG_LEVEL_00, p1, p2, p3, p4)
#define WARNING5(p1,p2,p3,p4,p5)	WinLog(WinLog_Warning, WINLOG_LEVEL_00, p1, p2, p3, p4, p5)

#define ERROR1(p1)					WinLog(WinLog_Error, WINLOG_LEVEL_00, p1)
#define ERROR2(p1,p2)				WinLog(WinLog_Error, WINLOG_LEVEL_00, p1, p2)
#define ERROR3(p1,p2,p3)			WinLog(WinLog_Error, WINLOG_LEVEL_00, p1, p2, p3)
#define ERROR4(p1,p2,p3,p4)		WinLog(WinLog_Error, WINLOG_LEVEL_00, p1, p2, p3, p4)
#define ERROR5(p1,p2,p3,p4,p5)	WinLog(WinLog_Error, WINLOG_LEVEL_00, p1, p2, p3, p4, p5)

#define FATAL1(p1)					WinLog(WinLog_Fatal, WINLOG_LEVEL_00, p1)
#define FATAL2(p1,p2)				WinLog(WinLog_Fatal, WINLOG_LEVEL_00, p1, p2)
#define FATAL3(p1,p2,p3)			WinLog(WinLog_Fatal, WINLOG_LEVEL_00, p1, p2, p3)
#define FATAL4(p1,p2,p3,p4)		WinLog(WinLog_Fatal, WINLOG_LEVEL_00, p1, p2, p3, p4)
#define FATAL5(p1,p2,p3,p4,p5)	WinLog(WinLog_Fatal, WINLOG_LEVEL_00, p1, p2, p3, p4, p5)

#define DUMP2(name,buf)				WinLogDump(WINLOG_LEVEL_00, name, buf, sizeof(buf))
#define DUMP3(name,buf,size)		WinLogDump(WINLOG_LEVEL_00, name, buf, size)

#ifdef  __cplusplus
extern "C" {
#endif

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogRegisterA(PARAM_IN const char * ProcessName);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogRegisterW(PARAM_IN const wchar_t * ProcessName);

#if defined UNICODE || defined _UNICODE
#define WinLogRegister		WinLogRegisterW
#else
#define WinLogRegister		WinLogRegisterA
#endif /* #if defined UNICODE || defined _UNICODE */

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogUnregister(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogDumpParam(void);

EXPORT_WINLOG const wchar_t * CALL_CONVENTION WinLogDecodeError(PARAM_IN const WinLogRet_t Error);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSetFeatureLevel(PARAM_IN const unsigned long FeatureLevel);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogReleaseInfo(WinLogCallBack_Info_t * CallbackInfo);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogFileSetFolderNameA(PARAM_IN const char * FolderName);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogFileSetFolderNameW(PARAM_IN const wchar_t * FolderName);

#if defined UNICODE || defined _UNICODE
#define WinLogFileSetFolderName		WinLogFileSetFolderNameW
#else
#define WinLogSetFolderName		WinLogFileSetFolderNameA
#endif /* #if defined UNICODE || defined _UNICODE */

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogFileSetSizeMax(PARAM_IN const unsigned long MaxSize);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogFileSetHistorySize(PARAM_IN const unsigned long HistorySize);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogFileEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogFileDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogOutputEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogOutputDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogDebugEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogDebugDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogCallbackEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogCallbackDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogCallbackSet(PARAM_IN const WinLogCallBack_t Callback);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogCallbackClear(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPostSendMessageEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPostSendMessageDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPostSendMessageSet(	PARAM_IN const unsigned long long hWnd,
																							PARAM_IN const unsigned long long message,
																							PARAM_IN const unsigned long long wParam,
																							PARAM_IN const int UseSendMessage);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPostSendMessageClear(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPipeSetNameA(PARAM_IN const char * PipeName);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPipeSetNameW(PARAM_IN const wchar_t * PipeName);

#if defined UNICODE || defined _UNICODE
#define WinLogPipeSetName		WinLogPipeSetNameW
#else
#define WinLogSetPipeName		WinLogPipeSetNameA
#endif /* #if defined UNICODE || defined _UNICODE */

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPipeEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogPipeDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSyslogSetRemoteServerW(PARAM_IN const wchar_t * DottedRemoteIpAddress);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSyslogSetRemoteServerA(PARAM_IN const char * DottedRemoteIpAddress);

#if defined UNICODE || defined _UNICODE
#define WinLogSyslogSetRemoteServer		WinLogSyslogSetRemoteServerW
#else
#define WinLogSyslogSetRemoteServer		WinLogSyslogSetRemoteServerA
#endif /* #if defined UNICODE || defined _UNICODE */

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSyslogSetRemotePort(PARAM_IN const unsigned long RemotePort);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSyslogSetFacility(PARAM_IN const unsigned long Facility);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSyslogEnable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSyslogDisable(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogA(	PARAM_IN const WinLogType_t Event,
																	PARAM_IN const unsigned long FeatureLevel,
																	PARAM_IN const char * Format,
																	PARAM_IN ...);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogW(	PARAM_IN const WinLogType_t Event,
																	PARAM_IN const unsigned long FeatureLevel,
																	PARAM_IN const wchar_t * Format,
																	PARAM_IN ...);

#if defined UNICODE || defined _UNICODE
#define WinLog					WinLogW
#else
#define WinLog					WinLogA
#endif /* #if defined UNICODE || defined _UNICODE */

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogDumpA(PARAM_IN const unsigned long FeatureLevel,
																		PARAM_IN const char * Name,
																		PARAM_IN const void * Buffer,
																		PARAM_IN const unsigned long Size);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogDumpW(PARAM_IN const unsigned long FeatureLevel,
																		PARAM_IN const wchar_t * Name,
																		PARAM_IN const void * Buffer,
																		PARAM_IN const unsigned long Size);


EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSetUtcTime(void);

EXPORT_WINLOG WinLogRet_t CALL_CONVENTION WinLogSetLocalTime(void);

#if defined UNICODE || defined _UNICODE
#define WinLogDump		WinLogDumpW
#else
#define WinLogDump		WinLogDumpA
#endif /* #if defined UNICODE || defined _UNICODE */

#ifdef  __cplusplus
}
#endif

#endif /* #ifndef WINLOG_INCLUDED */