#include <windows.h>
#include <detours.h>
#include <math.h>
#include <stdio.h>
/*
#include "Core.h"
#include "Engine.h"

typedef void(WINAPI *t_void)(struct FFrame& Stack, void* Result);

// Core hooks

t_void orgAllObjects			= NULL;
t_void orgGetReferencers		= NULL;

void WINAPI AllObjects					(struct FFrame& Stack, void* Result);
void WINAPI GetReferencers				(struct FFrame& Stack, void* Result);

// Engine hooks
t_void orgActorCommand			= NULL;
t_void orgConsoleCommand		= NULL;
t_void orgPlayerCommand			= NULL;
t_void orgGetDirectoryContents	= NULL;
t_void orgLocalPerform			= NULL;
t_void orgNativePerform			= NULL;

void WINAPI ActorCommand				(struct FFrame& Stack, void* Result);
void WINAPI ConsoleCommand				(struct FFrame& Stack, void* Result);
void WINAPI PlayerCommand				(struct FFrame& Stack, void* Result);
void WINAPI GetDirectoryContents		(struct FFrame& Stack, void* Result);
void WINAPI LocalPerform				(struct FFrame& Stack, void* Result);
void WINAPI NativePerform				(struct FFrame& Stack, void* Result);	

// UWeb hooks
t_void orgIncludeBinaryFile		= NULL;

void WINAPI IncludeBinaryFile			(struct FFrame& Stack, void* Result);

void* HookFunction (HMODULE hDll, char* Procname, DWORD dwOffset)
{
	GLog->Logf(L"[INFO] Attempting to hook %ls", ANSI_TO_TCHAR(Procname));

	if (hDll)
	{
		void* pAddress = (void*)GetProcAddress(hDll, Procname);

		if (pAddress)
		{
			void* pResult = (void*)DetourFunction((BYTE*)pAddress, (BYTE*)dwOffset);

			if (pResult)
			{
				GLog->Logf(L" - Done : Function was detoured");

				return pResult;
			}
			else
			{
				GLog->Logf(L" - Failed : Function was not detoured");
			}
		}
		else
		{
			GLog->Logf(L" - Failed : Function was not found");
		}
	}
	else
	{
		GLog->Logf(L" - Failed : Module was not found");
	}

	return 0;
}

class UEngine* CachedEngine = NULL;

UEngine* FindEngine ()
{
	if (CachedEngine)
	{
		return CachedEngine;
	}
	else
	{
		for (TObjectIterator<UEngine> pEngine; pEngine; ++pEngine)
		{
			if (pEngine)
			{
				CachedEngine = *pEngine;

				return CachedEngine;
			}
		}
	}

	return NULL;
}

/*
	if (Param1 == L"../System/Engine.u")
	{
		Param1 = Param1.Left(10);

		Param1 = L"../System/Engine-ORG.u"; //FString::Printf(L"%lsEngine-ORG.u", Param1); //appSprintf(*Param1, L"%lsEngine-ORG.u", Param1);

		GLog->Logf(L" - Redirecting file to %ls", Param1);

		struct str {
			int SecType;
			FString Param1;
			FString Param2;
			TArray<FString> Results;

		} LocalPerform_Parms;

		LocalPerform_Parms.SecType = SecType;
		LocalPerform_Parms.Param1  = Param1;
	
		pObject->ProcessEvent(pObject->FindFunctionChecked(L"LocalPerform"), &LocalPerform_Parms);

		return;
	}*/

#define LogPath "D:/Games/UT2004/System/URedirection.log"

void Log (const char *fmt, ...)
{
	va_list va_alist;
	static char logbuf[1024];

	if (fmt==NULL) return;
	
	FILE *fp;
	
	va_start (va_alist, fmt);
	_vsnprintf(logbuf, sizeof(logbuf), fmt, va_alist);
	va_end (va_alist);
	
	if ((fp=fopen (LogPath, "a+"))!=NULL)
	{
		fprintf(fp, "%s\n", logbuf);
		fclose (fp);
	}
}