#include "kiero.h"
#include <cstdio>

#if KIERO_INCLUDE_D3D9

#include "d3d9_impl.h"
#include <d3d9.h>
#include <assert.h>

#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_dx9.h"
#include "dx_shared.h"
#ifdef _MSC_VER
        #include <intrin.h>
#endif

typedef long(__stdcall* Reset)(LPDIRECT3DDEVICE9, D3DPRESENT_PARAMETERS*);
static Reset oReset = NULL;

typedef long(__stdcall* EndScene)(LPDIRECT3DDEVICE9);
static EndScene oEndScene = NULL;

long __stdcall hkReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
	ImGui_ImplDX9_InvalidateDeviceObjects();
	long result = oReset(pDevice, pPresentationParameters);
	ImGui_ImplDX9_CreateDeviceObjects();

	return result;
}

long __stdcall hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
	static bool init = false;

	auto prev_ctx = ImGui::GetCurrentContext();

	if (!init)
	{
		D3DDEVICE_CREATION_PARAMETERS params;
		pDevice->GetCreationParameters(&params);

		imgui_create(pDevice, nullptr);
		ImGui::SetCurrentContext(state.imgui_ctx);
		ImGui_ImplWin32_Init(params.hFocusWindow);
		ImGui_ImplDX9_Init(pDevice);
		init = true;
	}

	ImGui::SetCurrentContext(state.imgui_ctx);
#ifdef _MSC_VER
        static auto addr = _ReturnAddress();
        if(addr == _ReturnAddress()){
#else
        static auto addr = __builtin_return_address(0);
        if(addr == __builtin_return_address(0)){
#endif
		check_keybinds(params);
		update_hud_info(sw_stats, params, vendorID);
		ImGui_ImplDX9_NewFrame();
		ImGui_ImplWin32_NewFrame();
		ImGui::NewFrame();
		position_layer(sw_stats, params, window_size);
		render_imgui(sw_stats, params, window_size, "D3D9");
		ImGui::EndFrame();
		ImGui::Render();
		ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
	}

	ImGui::SetCurrentContext(prev_ctx);

	return oEndScene(pDevice);
}

void impl::d3d9::init()
{
	auto ret = kiero::bind(16, (void**)&oReset, reinterpret_cast<void *>(hkReset));
	assert(ret == kiero::Status::Success);
	ret = kiero::bind(42, (void**)&oEndScene, reinterpret_cast<void *>(hkEndScene));
	assert(ret == kiero::Status::Success);
}

#endif // KIERO_INCLUDE_D3D9