#pragma once

#include <fstream>
#include "detours.h"

#define NewLog(file) \
{ \
	std::wstring LogPath = file; \
	std::wfstream logFs; \
	logFs.open(LogPath.c_str(),std::ios::out); \
	logFs.close(); \
}


#define PrintLog(file, xLog) \
{ \
	std::wstring LogPath = file; \
	std::wfstream logFs; \
	logFs.open(LogPath.c_str(),std::ios::out | std::ios::app); \
	logFs << xLog; \
	logFs.close(); \
}

#define HIJACKCLASSFUNCTION(file, dllname,baseclass,funcname,functype,funcparam,classname) \
	{ \
		functype (* pfTarget)##funcparam##= \
			((##functype##(*)##funcparam##)(##baseclass##)->lpVtbl->##funcname); \
			functype (##classname##::* pfDetour)##funcparam##=&classname##::funcname##Replace; \
			functype (##classname##::* pfTrampoline)##funcparam##=&classname##::Real_##funcname; \
	    bool bDone = DetourFunctionWithEmptyTrampoline(*(PBYTE*)&pfTrampoline, \
										*(PBYTE*)&pfTarget, \
										*(PBYTE*)&pfDetour); \
		PrintLog(file, dllname << L" (register): " << #funcname << L" "); \
		if (bDone) \
		{ \
			PrintLog(file, L"Success\n"); \
		} \
		else \
		{ \
			PrintLog(file, L"Failed\n"); \
		} \
	}


#define HIJACKVTABLEFUNCTION(file, dllname,typedesc,funcname,classname,wrapperclassname) \
	{ \
		if (Real_##funcname == NULL) \
		{ \
			Real_##funcname = (##typedesc##)DetourFunction((unsigned char*)(##classname##)->lpVtbl->##funcname, \
			(unsigned char*)&wrapperclassname::funcname##Replace); \
			PrintLog(file, dllname << L" (register): ~::" << #funcname << L" "); \
			if (Real_##funcname) \
			{ \
				PrintLog(file,"Success\n"); \
			} \
			else \
			{ \
				PrintLog(file ,"Failed\n"); \
			} \
		} \
	}


#define HIJACKTRAMPOLINE(funcname,functype,funcparam,classname) DETOUR_TRAMPOLINE_EMPTY(functype classname##::Real_##funcname##funcparam##);
