#ifndef __GLOBAL_22__
#define __GLOBAL_22__

#include <tlhelp32.h>
#include <vector>
#include <string>
using namespace std;
#include "PipeService.h"

#ifdef UNICODE
typedef wstring TString;
#else
typedef string TString;
#endif

#define WECHAT _T("WeChat.exe")
#define OGC_TOOL _T("Demo.exe")

namespace GLOBAL {
	// DeltaE76
	// DeltaE94
	// DeltaE00
	typedef enum {
		DeltaE00 = 0,
		DeltaE76 = 1,
		DeltaE94 = 2
	}DETYPE;

	// 进程信息;
	typedef struct __PROC_INFO__ {
		DWORD   dwProcId;        // 进程id;
		TString strProcName;     // 进程名称;
		TString strProcFile;     // 进程路径;
	}PROC_INFO, *LPPROC_INFO;

	// 窗口信息;
	typedef struct __WND_INFO__ {
		HWND    hWnd;
		DWORD	dwCtrlId;
		TCHAR   szClassName[MAX_PATH];
		TCHAR   szWndTitle[MAX_PATH];
		__WND_INFO__() {
			dwCtrlId = 0;
			memset(szClassName, 0, sizeof(TCHAR)*MAX_PATH);
			memset(szWndTitle, 0, sizeof(TCHAR)*MAX_PATH);
		}

		__WND_INFO__ &operator=(const __WND_INFO__ &that) {
			if ( this == &that )
				return *this;

			hWnd = that.hWnd;
			dwCtrlId = that.dwCtrlId;
			_stprintf(szWndTitle, _T("%s"), that.szWndTitle);
			_stprintf(szClassName, _T("%s"), that.szClassName);

			return *this;
		}
	}WND_INFO, *LPWND_INFO;

	// 进程内所有窗口信息;
	typedef struct __PROC_WND_INFO__ {
		DWORD   dwProcId;
		std::vector<WND_INFO> vtWndInfo;

		void AddWnd(WND_INFO &data) {
			if (!IsExistWnd(data.hWnd))
				vtWndInfo.push_back(data);
		}

		bool IsExistWnd(HWND hWnd) {
			bool bExist = false;
			for (std::vector<WND_INFO>::iterator it = vtWndInfo.begin(); it != vtWndInfo.end(); it++ ) {
				if ( it->hWnd == hWnd ) {
					bExist = true;
					break;
				}
			}

			return bExist;
		}
	}PROC_WND_INFO,*LPPROC_WND_INFO;

	// Config文件内的配置信息;
	typedef struct __CONFIG__{
		INT		nStdOut;
		INT		nOffline;
		INT		nDeltaEType;
		DOUBLE	dDeltaEValue;
		DWORD	dwOGCToolProcId;
		TCHAR	szLine[MAX_PATH];
		TCHAR	szAccount[MAX_PATH];			
		TCHAR	szPassword[MAX_PATH];		
		TCHAR	szBatchNumber[MAX_PATH];
		TCHAR	szOGCToolProgram[MAX_PATH];
		__CONFIG__() {
			nStdOut = 0;
			nOffline = 0;
			nDeltaEType = 0;
			dDeltaEValue = 0.0;
			dwOGCToolProcId = -1;
			memset(szLine, 0, sizeof(TCHAR)*MAX_PATH);
			memset(szAccount, 0, sizeof(TCHAR)*MAX_PATH);
			memset(szPassword, 0, sizeof(TCHAR)*MAX_PATH);
			memset(szBatchNumber, 0, sizeof(TCHAR)*MAX_PATH);
			memset(szOGCToolProgram, 0, sizeof(TCHAR)*MAX_PATH);
		}
	}CONFIG, *LPCONFIG;

	extern CIOCPPipe g_IOCP;
	extern BOOL g_bHijacted;
	// 配置信息;
	extern CONFIG g_config;
	// 全局路径;
	extern TCHAR g_szModulePath[MAX_PATH];			// 软件目录;
	extern TCHAR g_szModuleFileName[MAX_PATH];		// 软件名称;
	extern TCHAR g_szConfigFile[MAX_PATH];
	// 目标里程窗口信息;
	extern PROC_WND_INFO g_procWndInfo;

	BOOL GetConfigInfo(LPCTSTR lpIniDir = NULL, LPCTSTR lpConfigName = NULL);
	DWORD FindProcess(LPCTSTR lpProName);
	vector<DWORD> FindAllProcess(LPCTSTR lpProName);
	void FindAllProcess(std::vector<PROC_INFO> &vtProInfo);
	HANDLE FindModule(LPCTSTR lpModuleName, DWORD dwProcId);
	LPCTSTR GetModulePath(LPCTSTR lpModuleName, DWORD dwProcId);
	HANDLE FindModuleEx(LPCTSTR lpModuleName, DWORD dwProcId);
	BOOL GetDebugPriv();

	BOOL GetFileVersion( IN HMODULE hModule, IN DWORD (&dwArray)[4]);
	BOOL GetFileVersionEx( IN LPCTSTR lpFileName, IN DWORD (&dwArray)[4] );
	BOOL GetProductVersion( IN HMODULE hModule, IN DWORD (&dwArray)[4]);
	BOOL GetProductVersionEx( IN LPCTSTR lpFileName, IN DWORD (&dwArray)[4] );

	BOOL GetOSDisplayString(LPTSTR pszOS);
	void WriteTextLog(const TCHAR *format, ...);
	BOOL CopyFileEx(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, const BOOL &bFailIfExists=TRUE);
	void tSplitpath(const char *path, char *drive, char *dir, char *fname, char *ext);
	void tSplitpath(const char *path, char *drive, char *dir, const int &nTimes);
	BOOL IsDirectoryLegitimate(const CString &strDirectory);
	void ShowSystemErrorInfo(CString strDescription, const DWORD &dwError);
	BOOL MySystemShutdown(LPTSTR lpMsg);
	BOOL PreventSystemShutdown();
	BOOL MySystemShutdown();

	// 根据进程pid获取进程对应程序的窗口句柄;
	HWND GetProcessMainWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWndName);
	// 获取指定进程名的进程主窗口;
	HWND GetProcessMainWnd(LPCTSTR lpProcessName, LPCTSTR lpTagetWndName);
	BOOL EnumProcessAllWnd(LPPROC_WND_INFO lpProcWndInfo);
	BOOL StartProcess(LPCTSTR lpPath, BOOL bShowWnd = FALSE, BOOL bSuspend = FALSE);
};

#endif