#include "AnimationTreeEditor.hpp"
#include "../systems/AnimationTreeSystem.hpp"
#include "../systems/AnimationTreeRegistry.hpp"
#include <imgui.h>

AnimationTreeEditor::AnimationTreeEditor(Ogre::SceneManager *sceneMgr)
	: m_sceneMgr(sceneMgr)
{
}

static void renderStatePreview(AnimationTreeComponent &at,
			       const AnimationTreeNode &root)
{
	std::vector<const AnimationTreeNode *> stateMachines;
	root.collectStateMachines(stateMachines);
	if (stateMachines.empty())
		return;

	ImGui::Separator();
	ImGui::Text("State Preview");

	for (auto *sm : stateMachines) {
		if (!sm)
			continue;

		auto itCurrent = at.currentStates.find(sm->name);
		Ogre::String currentState =
			(itCurrent != at.currentStates.end()) ?
				itCurrent->second :
				"";

		Ogre::String label = sm->name + "##" + sm->name;
		Ogre::String preview = currentState.empty() ?
					       "(none)" :
					       currentState;

		if (ImGui::BeginCombo(label.c_str(), preview.c_str())) {
			for (const auto &child : sm->children) {
				if (child.type != "state")
					continue;
				bool sel = (currentState == child.name);
				if (ImGui::Selectable(child.name.c_str(),
						      sel)) {
					at.currentStates[sm->name] =
						child.name;
					at.dirty = true;
				}
			}
			ImGui::EndCombo();
		}
	}
}

bool AnimationTreeEditor::renderComponent(flecs::entity entity,
					  AnimationTreeComponent &at)
{
	ImGui::PushID("AnimTree");
	bool modified = false;

	if (ImGui::CollapsingHeader("Animation Tree",
				    ImGuiTreeNodeFlags_DefaultOpen)) {
		ImGui::Indent();

		AnimationTreeRegistry &reg =
			AnimationTreeRegistry::getSingleton();
		std::vector<Ogre::String> names = reg.getTreeNames();

		Ogre::String current = at.treeName;
		Ogre::String preview = current.empty() ? "(none)" : current;
		if (ImGui::BeginCombo("Tree", preview.c_str())) {
			bool noneSel = current.empty();
			if (ImGui::Selectable("(none)", noneSel)) {
				at.treeName = "";
				modified = true;
				at.dirty = true;
			}
			for (const auto &name : names) {
				bool sel = (current == name);
				if (ImGui::Selectable(name.c_str(), sel)) {
					at.treeName = name;
					modified = true;
					at.dirty = true;
				}
			}
			ImGui::EndCombo();
		}

		if (!at.treeName.empty() &&
		    ImGui::Button("Edit in Registry")) {
			/* TODO: signal EditorUISystem to open the registry
			 * editor on this tree.  For now the user can open
			 * Tools -> Animation Tree Registry manually. */
		}

		ImGui::Separator();

		/* Global toggles */
		if (ImGui::Checkbox("Enabled", &at.enabled))
			modified = true;
		if (ImGui::Checkbox("Use Root Motion", &at.useRootMotion)) {
			modified = true;
			at.dirty = true;
		}

		/* State preview from registry tree */
		const AnimationTreeRegistry::AnimationTreeDefinition *def =
			reg.findTree(at.treeName);
		if (def)
			renderStatePreview(at, def->root);

		ImGui::Unindent();
	}

	ImGui::PopID();
	return modified;
}
