#ifndef EDITSCENE_ANIMATIONTREENODEEDITOR_HPP
#define EDITSCENE_ANIMATIONTREENODEEDITOR_HPP
#pragma once

#include "../components/AnimationTree.hpp"
#include <Ogre.h>
#include <vector>

/**
 * Reusable editor for an AnimationTreeNode hierarchy.
 *
 * This editor does not know about registries or components; it simply
 * edits the provided root node in place.  It is used by the Animation Tree
 * Registry editor and can be used anywhere a tree needs to be authored.
 */
class AnimationTreeNodeEditor {
public:
	AnimationTreeNodeEditor();

	/**
	 * Render the tree editor.
	 *
	 * @param root Root node to edit.
	 * @param animNames Optional list of animation names for dropdowns.
	 * @return true if the tree was modified.
	 */
	bool render(AnimationTreeNode &root,
		    const std::vector<Ogre::String> &animNames);

	/** Clear selection and pending edit operations. */
	void reset();

private:
	struct TreeEditOp {
		enum OpType { AddChild, RemoveNode, MoveNode } type;
		AnimationTreeNode *targetNode = nullptr;
		size_t childIndex = 0;
		Ogre::String childType;
		int moveDelta = 0;
	};

	void queueAddChild(AnimationTreeNode *parent,
			   const Ogre::String &type);
	void queueRemoveNode(AnimationTreeNode *parent, size_t childIndex);
	void queueMoveNode(AnimationTreeNode *parent, size_t childIndex,
			   int delta);
	void applyEditOps(AnimationTreeNode &root);

	void renderTree(AnimationTreeNode &node,
			AnimationTreeNode *parent,
			AnimationTreeNode *&selectedNode,
			AnimationTreeNode *&selectedParent,
			int &id);
	void renderProperties(AnimationTreeNode *node,
			      const std::vector<Ogre::String> &animNames);
	void renderStatePreview(AnimationTreeNode &root);

	std::vector<TreeEditOp> m_editOps;
	AnimationTreeNode *m_selectedNode = nullptr;
	AnimationTreeNode *m_selectedParent = nullptr;
	int m_treeId = 0;
	bool m_modified = false;
};

#endif // EDITSCENE_ANIMATIONTREENODEEDITOR_HPP
