extends Node2D

@export var binded_rock: Rock
@export var binded_volumn: PlayerTriggerVolumn

var _rock : Rock
var _volumn : PlayerTriggerVolumn

func _ready() -> void:
	_rock = binded_rock if binded_rock != null else _find_first_rock(self)
	_volumn = binded_volumn if binded_volumn != null else _find_first_volumn(self)

	if not _volumn or not _rock: return
	
	_volumn.player_entered.connect(_on_rock_start_shake,CONNECT_ONE_SHOT)

func _on_rock_start_shake(player: Player) -> void:
	if not _rock: return
	
	_rock.start_shaking()
	$Timer.start()
	$Timer.timeout.connect(_on_rock_falling)

func _on_rock_falling() -> void:
	_rock.stop_shaking()
	_rock.start_falling()


## ================================
## 查找工具函数（强类型）
## ================================

func _find_first_rock(root: Node) -> Rock:
	var found: Node = _find_first_child_matching(root, func(n: Node) -> bool: return n is Rock)
	return found as Rock


func _find_first_volumn(root: Node) -> PlayerTriggerVolumn:
	var found: Node = _find_first_child_matching(root, func(n: Node) -> bool: return n is PlayerTriggerVolumn)
	return found as PlayerTriggerVolumn


func _find_first_child_matching(root: Node, predicate: Callable) -> Node:
	for child: Node in root.get_children():
		# predicate.call() 返回值在类型系统里可能是 Variant，所以别用 := 推断
		var ok: bool = bool(predicate.call(child))
		if ok:
			return child

		var deeper: Node = _find_first_child_matching(child, predicate)
		if deeper != null:
			return deeper

	return null
