#include "memory.hpp"
#include <stb/stb.hh>
#include "../interfaces/interfaces.hpp"
#define MEMORY_VARIABLE(var) var, "memory::" #var

void memory::Initialize()
{
	CModule client(CLIENT_DLL);
	CModule schemasystem(SCHEMASYSTEM_DLL);
	CModule sdl3(SDL3_DLL);
	CModule tier0(TIER0_DLL);
	CModule particles(PARTICLES_DLL);
	CModule scenesystem(SCENESYSTEM_DLL);
	CModule materialsystem(MATERIALSYSTEM_DLL);

	client.FindPattern(GET_BASE_ENTITY)
		.Get(MEMORY_VARIABLE(fnGetBaseEntity));

	client.FindPattern(GET_HIGHEST_ENTITY_INDEX)
		.ToAbsolute(3, 0)
		.Get(MEMORY_VARIABLE(fnGetHighestEntityIndex));

	schemasystem.FindPattern(PRINT_SCHEMA_DETAILED_CLASS_LAYOUT)
		.Get(MEMORY_VARIABLE(schema_detailed_class_layout));

	client.FindPattern(MOUSE_INPUT_ENABLED)
		.Get(MEMORY_VARIABLE(fnMouseInputEnabled));


	client.FindPattern(GET_GC_CLIENT_SYSTEM)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(fnGetClientSystem));


	client.FindPattern(CREATE_BASE_TYPE_CACHE)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(fnCreateBaseTypeCache));

	client.FindPattern(FIND_SO_CACHE)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(fnFindSOCache));

	client.FindPattern(GET_LOCAL_PLAYER_CONTROLLER)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(fnGetLocalPlayerController));

	client.FindPattern(SET_DYNAMIC_ATTRIBUTE_VALUE_UINT)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(fnSetDynamicAttributeValueUint));


	client.FindPattern(COMPUTE_HITBOX_SURROUNDING_BOX)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(fnComputeHitboxSurroundingBox));

	client.FindPattern(GET_MATRICES_FOR_VIEW)
		.Get(MEMORY_VARIABLE(fnGetMatricesForView));

	//MEM::GetAbsoluteAddress(MEM::FindPattern(CLIENT_DLL, CS_XOR("E8 ? ? ? ? 48 85 C0 74 ? 44 38 60")), 0x1, 0x0)

	client.FindPattern(SDK_SIG("48 89 5C 24 20 48 89 4C 24 08 55 56 41")).Get(MEMORY_VARIABLE(fnTraceShape));
	client.FindPattern(SDK_SIG("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 54 41 56 41 57 48 81 EC ? ? ? ? 48 8B 9C 24")).Get(MEMORY_VARIABLE(fnClipRayToEntity));

	client.FindPattern(SDK_SIG("40 53 48 83 EC 30 48 8B 41 10 48 8B D9 8B 50 30")).Get(MEMORY_VARIABLE(fnGetPlayerPawn));

	client.FindPattern(SDK_SIG("48 63 41 ? 48 8B 0D")).Get(MEMORY_VARIABLE(fnGetSurfaceData));

	client.FindPattern(SDK_SIG("48 8B 05 ? ? ? ? F2 0F 11 45 ? 80 65 ? ? 89 7D")).ToAbsolute(0x3, 0).Dereference(1).Get(interfaces::pTraceMgr);


	client.FindPattern(CREATMOVE_SIG)
		.Get(MEMORY_VARIABLE(fnCreatMove));

	client.FindPattern(FRAMESTAGE_NOTIFY)
		.Get(MEMORY_VARIABLE(fnFrameStage));

	//client.FindPattern(UPDATE_3D_PARAMS)
	//	.Get(MEMORY_VARIABLE(hkUpdateSky3DParams));

	client.FindPattern(SDK_SIG("85 D2 75 3F 48 63 81 ? ? ? ? F2 41 0F 10 00 85 C0 74 1D 48 8B 89 ? ? ? ? 48 69 D0"))
		.Get(MEMORY_VARIABLE(m_CSGOInput_SetViewAngles));

	client.FindPattern(SDK_SIG("E8 ? ? ? ? EB ? 48 8B 01 48 8D 54 24"))
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(m_CSGOInput_GetViewAngles));

	client.FindPattern(SKYBOX_COLOR_UPDATE)
		.Get(MEMORY_VARIABLE(UpdateSkyboxColor));

	client.FindPattern(SDK_SIG("40 53 48 83 EC 20 48 8B 54"))
		.Get(MEMORY_VARIABLE(GlowFunction));

	client.FindPattern(SDK_SIG("40 53 48 83 EC 20 48 8B D9 4C 8B C2 48 8B 0D ? ? ? ? 48 8D 54 24"))
		.Get(MEMORY_VARIABLE(fnSetModel));

	tier0.GetProcAddress("RandomInt").Get(MEMORY_VARIABLE(fnRandomInt));
	tier0.GetProcAddress("RandomSeed").Get(MEMORY_VARIABLE(fnRandomSeed));
	tier0
		.GetProcAddress(
			"?LoadKV3@@YA_NPEAVKeyValues3@@PEAVCUtlString@@PEAVCUtlBuffer@@AEBUKV3ID_t@@PEBD@Z")
		.Get(MEMORY_VARIABLE(fnLoadKV3));

	client.FindPattern(SET_TYPE).ToAbsolute(1, 0).Get(
		MEMORY_VARIABLE(fnSetType));

	client.FindPattern(FREE_ALLOC_KV3).ToAbsolute(1, 0).Get(
		MEMORY_VARIABLE(pFnFreeAlloc));

	particles.FindPattern(SET_MATERIAL_SHADER)
		.ToAbsolute(32, 0)
		.Get(MEMORY_VARIABLE(fnSetMaterialShaderType));

	//particles.FindPattern(SET_MATERIAL).Get(MEMORY_VARIABLE(fnSetMaterial));

	particles.FindPattern(FIND_VAR).Get(MEMORY_VARIABLE(fnFindKeyVar));

	scenesystem.FindPattern(DRAW_OBJECT).Get(MEMORY_VARIABLE(fnDrawObject));

	scenesystem.FindPattern(UPDATE_COLOR_TO_SCENE)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(hkApplyColorToSceneObject));

	scenesystem.FindPattern(HK_SETUP_LIGHT)
		.ToAbsolute(1, 0)
		.Get(MEMORY_VARIABLE(hksetup_lighting));

	//materialsystem.FindPattern(CREATE_MATERIAL)
		//.Get(MEMORY_VARIABLE(fnCreateMaterial));

	tier0.GetProcAddress("??3KeyValues@@SAXPEAXHPEBDH@Z")
		.Get(MEMORY_VARIABLE(fnDelete));

	tier0.GetProcAddress("MemAlloc_AllocFunc")
		.Get(MEMORY_VARIABLE(fnAllocMem));

	tier0.GetProcAddress("MemAlloc_FreeFunc")
		.Get(MEMORY_VARIABLE(fnDeAllocMem));

	sdl3.GetProcAddress("SDL_SetWindowRelativeMouseMode").Get(fnSDL_SetRelativeMouseMode);
	sdl3.GetProcAddress("SDL_GetWindowRelativeMouseMode").Get(fnSDL_GetRelativeMouseMode);
	sdl3.GetProcAddress("SDL_GetGrabbedWindow").Get(fnSDL_GetGrabbedWindow);
	sdl3.GetProcAddress("SDL_SetWindowMouseGrab").Get(fnSDL_SetWindowGrab);
	sdl3.GetProcAddress("SDL_WarpMouseInWindow").Get(fnSDL_WarpMouseInWindow);

	UTILPtr ppHeapMemAlloc = tier0.GetProcAddress("g_pMemAlloc");
	if (ppHeapMemAlloc.IsValid())
		ppHeapMemAlloc.Dereference(1).Get(MEMORY_VARIABLE(g_pHeapMemAlloc));
}

void memory::Shutdown()
{}
