# Utility class for parsing and hacking the editor

## Find menu button to add option to
static func find_animation_menu_button(node: Node) -> MenuButton:
	var animation_editor := find_editor_control_with_class(node, "AnimationPlayerEditor")
	if animation_editor:
		return find_editor_control_with_class(
			animation_editor, 
			"MenuButton", 
			func(node): return node.text == "Animation"
		)

	return null


## General utility to find a control in the editor using an iterative search
static func find_editor_control_with_class(
		base: Control, 
		p_class_name: StringName,
		condition := func(node: Node): return true
	) -> Node:
	if base.get_class() == p_class_name and condition.call(base):
		return base
		
	for child in base.get_children():
		if not child is Control:
			continue
			
		var found = find_editor_control_with_class(child, p_class_name)
		if found:
			return found
		
	return null



# Finds the active animation player (either pinned or selected)
static func find_active_anim_player(base_control: Control, scene_tree: Tree) -> AnimationPlayer:
	var find_anim_player_recursive: Callable
	
	var pin_icon := scene_tree.get_theme_icon("Pin", "EditorIcons")
	
	var stack: Array[TreeItem] = []
	stack.append(scene_tree.get_root())
	
	while not stack.is_empty():
		var current := stack.pop_back() as TreeItem
		
		# Check for pin icon
		for i in current.get_button_count(0):
			if current.get_button(0, i) == pin_icon:
				var node := base_control.get_node_or_null(current.get_metadata(0))
				if node is AnimationPlayer:
					return node
		
		if current.is_selected(0):
			var node := base_control.get_node_or_null(current.get_metadata(0))
			if node is AnimationPlayer:
				return node
		
		for i in range(current.get_child_count() - 1, -1, -1):
			stack.push_back(current.get_child(i))
		
	return null
