#include "CharacterEditor.hpp"
#include <imgui.h>
#include <cstring>

bool CharacterEditor::renderComponent(flecs::entity entity,
				      CharacterComponent &cc)
{
	(void)entity;
	bool modified = false;

	if (ImGui::Checkbox("Enabled##Character", &cc.enabled))
		modified = true;

	ImGui::Separator();
	ImGui::Text("Capsule");

	if (ImGui::SliderFloat("Radius##Character", &cc.radius, 0.05f, 2.0f,
				"%.2f")) {
		modified = true;
	}
	if (ImGui::SliderFloat("Height##Character", &cc.height, 0.1f, 5.0f,
				"%.2f")) {
		modified = true;
	}

	ImGui::TextDisabled("Total: %.2f m",
			    cc.getTotalHeight());

	ImGui::Separator();
	ImGui::Text("Head Collider");
	if (ImGui::DragFloat("Head Radius##Character",
			     &cc.headRadius, 0.01f, 0.0f, 2.0f,
			     "%.2f")) {
		modified = true;
	}
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip("0 = default (0.13)");
	if (ImGui::DragFloat("Head Offset Y##Character",
			     &cc.headOffsetY, 0.01f, 0.0f, 5.0f,
			     "%.2f")) {
		modified = true;
	}
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip("0 = default (totalHeight - headRadius)");

	char headBoneBuf[64];
	std::strncpy(headBoneBuf, cc.headBoneName.c_str(), sizeof(headBoneBuf));
	headBoneBuf[sizeof(headBoneBuf) - 1] = '\0';
	if (ImGui::InputText("Head Bone##Character", headBoneBuf,
			     sizeof(headBoneBuf))) {
		cc.headBoneName = headBoneBuf;
		modified = true;
	}

	ImGui::Separator();
	ImGui::Text("Chest Collider");
	float che[3] = { cc.chestHalfExtents.x, cc.chestHalfExtents.y,
			 cc.chestHalfExtents.z };
	if (ImGui::InputFloat3("Chest Half Extents##Character", che,
			       "%.2f")) {
		cc.chestHalfExtents = Ogre::Vector3(che[0], che[1], che[2]);
		modified = true;
	}
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip("Set any axis to 0 to disable");
	if (ImGui::DragFloat("Chest Offset Y##Character",
			     &cc.chestOffsetY, 0.01f, -2.0f, 2.0f,
			     "%.2f")) {
		modified = true;
	}
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip("Vertical offset along world Y");

	char chestBoneBuf[64];
	std::strncpy(chestBoneBuf, cc.chestBoneName.c_str(),
		     sizeof(chestBoneBuf));
	chestBoneBuf[sizeof(chestBoneBuf) - 1] = '\0';
	if (ImGui::InputText("Chest Bone##Character", chestBoneBuf,
			     sizeof(chestBoneBuf))) {
		cc.chestBoneName = chestBoneBuf;
		modified = true;
	}

	ImGui::Separator();
	ImGui::Text("Offset");
	float off[3] = { cc.offset.x, cc.offset.y, cc.offset.z };
	if (ImGui::InputFloat3("Position##Character", off, "%.2f")) {
		cc.offset = Ogre::Vector3(off[0], off[1], off[2]);
		modified = true;
	}

	ImGui::Separator();
	ImGui::Text("Velocity");
	float vel[3] = { cc.linearVelocity.x, cc.linearVelocity.y,
			 cc.linearVelocity.z };
	if (ImGui::InputFloat3("Linear (m/s)##Character", vel, "%.2f")) {
		cc.linearVelocity = Ogre::Vector3(vel[0], vel[1],
						  vel[2]);
		modified = true;
	}

	ImGui::Separator();
	ImGui::Text("Floor Detection");
	if (ImGui::Checkbox("Use Gravity##Character", &cc.useGravity)) {
		modified = true;
	}
	if (ImGui::Checkbox("Has Floor##Character", &cc.hasFloor)) {
		modified = true;
	}
	if (ImGui::SliderFloat("Check Distance##Character",
			       &cc.floorCheckDistance, 0.1f, 10.0f,
			       "%.2f")) {
		modified = true;
	}

	if (modified)
		cc.dirty = true;

	return modified;
}
