#include <metahook.h>
#include "exportfuncs.h"

cl_exportfuncs_t gExportfuncs;
mh_interface_t *g_pInterface;
metahook_api_t *g_pMetaHookAPI;
mh_enginesave_t *g_pMetaSave;
IFileSystem *g_pFileSystem;

DWORD g_dwEngineBase, g_dwEngineSize;
DWORD g_dwClientBase, g_dwClientSize;
DWORD g_dwEngineBuildnum;
DWORD g_iVideoMode;
int g_iVideoWidth, g_iVideoHeight, g_iBPP;
bool g_bWindowed;

void API_InstallHook(void);
void BaseUI_InstallHook(void);
void Engine_InstallHook(void);
void Client_InstallHook(void);

void IPlugins::Init(metahook_api_t *pAPI, mh_interface_t *pInterface, mh_enginesave_t *pSave)
{
	g_pInterface = pInterface;
	g_pMetaHookAPI = pAPI;
	g_pMetaSave = pSave;

	g_pInterface->CommandLine->RemoveParm("-d3d");
	g_pInterface->CommandLine->AppendParm("-gl", NULL);
	g_pInterface->CommandLine->AppendParm("-32bpp", NULL);
	g_pInterface->CommandLine->AppendParm("-nocdaudio", NULL);
	g_pInterface->CommandLine->AppendParm("-nomaster", NULL);
	g_pInterface->CommandLine->AppendParm("-insecure", NULL);
	g_pInterface->CommandLine->AppendParm("-forcevalve", NULL);
}

void IPlugins::Shutdown(void)
{
}

void IPlugins::LoadEngine(void)
{
	g_pFileSystem = g_pInterface->FileSystem;
	g_iVideoMode = g_pMetaHookAPI->GetVideoMode(&g_iVideoWidth, &g_iVideoHeight, &g_iBPP, &g_bWindowed);
	g_dwEngineBuildnum = g_pMetaHookAPI->GetEngineBuildnum();

	if (g_iVideoMode == VIDEOMODE_SOFTWARE)
		return;

	g_dwEngineBase = g_pMetaHookAPI->GetEngineBase();
	g_dwEngineSize = g_pMetaHookAPI->GetEngineSize();

	API_InstallHook();
	Engine_InstallHook();
	BaseUI_InstallHook();
}

void IPlugins::LoadClient(cl_exportfuncs_t *pExportFunc)
{
	HMODULE hClient = GetModuleHandle("client.dll");
	if(!hClient)
	{
		g_dwClientBase = 0x1901000;
		g_dwClientSize = 0xBC000;
	}
	else
	{
		g_dwClientBase = g_pMetaHookAPI->GetModuleBase(hClient);
		g_dwClientSize = g_pMetaHookAPI->GetModuleSize(hClient);
	}
	memcpy(&gExportfuncs, pExportFunc, sizeof(gExportfuncs));

	pExportFunc->Initialize = Initialize;
	pExportFunc->HUD_Init = HUD_Init;
	pExportFunc->HUD_Redraw = HUD_Redraw;
	pExportFunc->HUD_VidInit = HUD_VidInit;
	pExportFunc->IN_Accumulate = IN_Accumulate;
	pExportFunc->HUD_Key_Event = HUD_Key_Event;
	pExportFunc->IN_MouseEvent = IN_MouseEvent;
	pExportFunc->HUD_GetStudioModelInterface = HUD_GetStudioModelInterface;
	pExportFunc->V_CalcRefdef = V_CalcRefdef;
	pExportFunc->HUD_TempEntUpdate = HUD_TempEntUpdate;
	pExportFunc->HUD_DrawNormalTriangles = HUD_DrawNormalTriangles;
	pExportFunc->HUD_AddEntity = HUD_AddEntity;
	pExportFunc->HUD_UpdateClientData = HUD_UpdateClientData;
	pExportFunc->HUD_DrawTransparentTriangles = HUD_DrawTransparentTriangles;
	pExportFunc->HUD_PlayerMove = HUD_PlayerMove;
	pExportFunc->HUD_PlayerMoveInit = HUD_PlayerMoveInit;
	pExportFunc->HUD_PlayerMoveTexture = HUD_PlayerMoveTexture;
	pExportFunc->HUD_PostRunCmd = HUD_PostRunCmd;
	pExportFunc->HUD_ProcessPlayerState = HUD_ProcessPlayerState;
	pExportFunc->HUD_StudioEvent = HUD_StudioEvent;
	pExportFunc->CL_CreateMove = CL_CreateMove;
	Client_InstallHook();
}

void IPlugins::ExitGame(int iResult)
{
}

EXPOSE_SINGLE_INTERFACE(IPlugins, IPlugins, METAHOOK_PLUGIN_API_VERSION);