#include "BlockESP.h"
#include "Client.h"

#include "Utils/MoveUtils.h"
#include "Utils/ImGuiRenderUtils.h"

auto BlockESP::onWorldTick(Player* _this) -> void {
	if (!enabled) return;

	auto clientinstance = Client::clientinstance;
	if (!clientinstance) return;

	auto blocksource = clientinstance->getBlockSource();
	if (!blocksource) return;

	auto localplayer = clientinstance->getLocalPlayer();
	if (!localplayer) return;

	glm::vec3 position = Utils::Move::getPosition(localplayer);

	std::vector<RenderData> renderdatas_;
	for (int x = -(int)range; x < (int)range; x++) {
		for (int y = -(int)range; y < (int)range; y++) {
			for (int z = -(int)range; z < (int)range; z++) {
				glm::ivec3 blockpos = glm::ivec3(position.x + x, position.y + y, position.z + z);
				std::string name = blocksource->getBlock(&blockpos)->getBlockLegacy()->getName();

				bool skip = false;
				if (nocovered) {
					std::vector<glm::ivec3> checklist = {
						glm::ivec3(0, 1, 0),
						glm::ivec3(0, -1, 0),


						glm::ivec3(1, 0, 0),
						glm::ivec3(-1, 0, 0),

						glm::ivec3(0, 0, 1),
						glm::ivec3(0, 0, -1),
					};

					for (glm::ivec3 check : checklist) {
						glm::ivec3 checkpos = glm::ivec3(
							blockpos.x + check.x,
							blockpos.y + check.y,
							blockpos.z + check.z
						);

						if (blocksource->getBlock(&checkpos)->getBlockLegacy()->getName() == _("tile.air")) {
							skip = false;
							break;
						}
						else
							skip = true;
					}
				}

				if (skip)
					continue;

				if (name == _("tile.coal_ore") && coal) renderdatas_.push_back({ glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 0 });
				if (name == _("tile.iron_ore") && iron) renderdatas_.push_back({ glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 1 });
				if (name == _("tile.gold_ore") && gold) renderdatas_.push_back({ glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 2 });
				if (name == _("tile.diamond_ore") && diamond) renderdatas_.push_back({ glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 3 });
				if (name == _("tile.lapis_ore") && lapis) renderdatas_.push_back({ glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 4 });
				if ((name == _("tile.redstone_ore") || name == _("tile.lit_redstone_ore")) && redstone) renderdatas_.push_back({glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 5});
				if (name == _("tile.emerald_ore") && emerald) renderdatas_.push_back({ glm::ivec3(position.x + (x + 1), position.y + (y + 1), position.z + (z + 1)), blockpos, 6 });
			}
		}
	}
	renderdatas = renderdatas_;
}

auto BlockESP::onImGuiRender() -> void {
	if (Client::screenName != _("hud_screen")) return;

	Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());

	for (RenderData renderdata : renderdatas) {
		switch (renderdata.blocktype) {
		case 0:
			Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(0.f, 0.f, 0.f, 1.f));
			break;
		case 1:
			Utils::ImGuiRender::setColor(ImColor(1.f, 0.9f, 0.7f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(1.f, 0.9f, 0.7f, 1.f));
			break;
		case 2:
			Utils::ImGuiRender::setColor(ImColor(1.f, 0.8f, 0.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(1.f, 0.8f, 0.f, 1.f));
			break;
		case 3:
			Utils::ImGuiRender::setColor(ImColor(0.f, 0.85f, 1.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(0.f, 0.85f, 1.f, 1.f));
			break;
		case 4:
			Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 1.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(0.f, 0.f, 1.f, 1.f));
			break;
		case 5:
			Utils::ImGuiRender::setColor(ImColor(1.f, 0.f, 0.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(1.f, 0.f, 0.f, 1.f));
			break;
		case 6:
			Utils::ImGuiRender::setColor(ImColor(0.f, 1.f, 0.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(0.f, 1.f, 0.f, 1.f));
			break;
		default:
			Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f));
			Utils::ImGuiRender::setSecondColor(ImColor(1.f, 1.f, 1.f, 1.f));
			break;
		}
	
		Utils::ImGuiRender::setThickness(1.f);

		if (fill)
			Utils::ImGuiRender::fillBox(renderdata.lower, renderdata.upper);
		else
			Utils::ImGuiRender::drawBox(renderdata.lower, renderdata.upper);
	}
}
