#pragma once
#include "Utils/MemoryUtils.h"
#include "Utils/FileUtils.h"

namespace Hooks {
	class Options {
	private:
		typedef auto(__thiscall* option_getviewperspective_)(uintptr_t* a1) -> int;
		typedef auto(__thiscall* option_getgamma_)(void*, void*) -> float;
		typedef auto(__thiscall* option_getfov_)(void*, float, void*, void*) -> float;

		inline static option_getviewperspective_ option_getviewperspective;
		inline static option_getgamma_ option_getgamma;
		inline static option_getfov_ option_getfov;

		static auto callback_getviewperspective(uintptr_t* a1) -> int;
		static auto callback_getgamma(void*, void*) -> float;
		static auto callback_getfov(void*, float, void*, void*) -> float;
	public:
		inline static int state = -1;
		static void Init() {
			std::thread([&] {
				void* getviewperspective_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 48 8B 01 48 8D 54 24 30 41 B8 03 00"));
				
				state = Utils::Memory::CreateHook(getviewperspective_pattern, (void*)&callback_getviewperspective, &option_getviewperspective);
	
				void* getgamma_pattern = nullptr;
				if (Utils::File::getVersion() == _("1.21.80"))
					getgamma_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 80 B9 00 19 00 00 00 48 8D 54 24 30 48 8B 01 48 8B 40 60 74 38 41 B8 1A"));
				else if (Utils::File::getVersion() == _("1.21.73"))
					getgamma_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 80 B9 C8 18 00 00 00 48 8D 54 24 30 48 8B 01 48 8B 40 60 74 38 41 B8 1A"));
				else if (Utils::File::getVersion() == _("1.21.72"))
					getgamma_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 80 B9 C8 18 00 00 00 48 8D 54 24 30 48 8B 01 48 8B 40 60 74 38 41 B8 1A"));
				else if (Utils::File::getVersion() == _("1.21.71"))
					getgamma_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 80 B9 C8 18 00 00 00 48 8D 54 24 30 48 8B 01 48 8B 40 60 74 38 41 B8 1A"));
				else if (Utils::File::getVersion() == _("1.21.70"))
					getgamma_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 80 B9 C8 18 00 00 00 48 8D 54 24 30 48 8B 01 48 8B 40 60 74 38 41 B8 1A"));
				else
					getgamma_pattern = Utils::Memory::FindPattern(_("48 83 EC 28 80 B9 A0 18 00 00 00 48 8D 54 24 30 48 8B 01 48 8B 40 60 74 38 41 B8 19"));

				state = Utils::Memory::CreateHook(getgamma_pattern, (void*)&callback_getgamma, &option_getgamma);

				void* getfov_pattern = Utils::Memory::FindPattern(_("48 8B C4 48 89 58 18 48 89 70 20 57 48 81 EC 90 00 00 00 0F 29 70 E8 0F"));

				state = Utils::Memory::CreateHook(getfov_pattern, (void*)&callback_getfov, &option_getfov);

				if (state == 0)
					MessageBoxA(0, _("The program was terminated due to an error.\nError code: 1-8"), _("Valkyrie"), MB_ICONERROR);
				else
					std::cout << _("Test 1-8... OK\n");
				}).detach();
		}
	};
}
