class_name BallPoint extends Node3D
## Ball spawn point & origin. I.E. the "tee".

## Emitted when a new ball is placed.
signal ball_changed(ball: GameBall)

## Scenes for each type of ball.
const SCENE_MAP: Dictionary = {
	GameBall.Type.BASIC: preload("res://src/equipment/balls/physics_ball/physics_ball.tscn"),
	GameBall.Type.PLASMA: preload("res://src/equipment/balls/plasma_ball/plasma_ball.tscn"),
	GameBall.Type.BRICK: preload("res://src/equipment/balls/brick/brick.tscn"),
	GameBall.Type.BEACH: preload("res://src/equipment/balls/beach_ball/beach_ball.tscn"),
	GameBall.Type.POWER: preload("res://src/equipment/balls/power_ball/power_ball.tscn"),
}

@export var ball: GameBall:
	set(value):
		ball = value
		ball_changed.emit(ball)

@export var height_offset := 0.08

@onready var shot_setup: ShotSetup = $".."


## Get a new instance of a ball of the given type.
## Returns null if the type can't be instantiated (e.g. NONE type)
func get_instance(type: GameBall.Type) -> GameBall:
	if type in SCENE_MAP:
		var scene: PackedScene = SCENE_MAP.get(type)
		var instance: GameBall = scene.instantiate()
		instance.player = shot_setup.player
		return instance
	return null


## Clear any existing ball, instantiate a new one of the given type, and place it at the ball point.
func spawn_ball(type: GameBall.Type) -> void:
	# Clear existing ball
	if is_instance_valid(ball):
		ball.queue_free()

	ball = get_instance(type)
	if is_instance_valid(ball):
		add_child(ball)
		position.y = height_offset + ball.radius
		snap()


## Snap the ball back to the ball point.
func snap() -> void:
	ball.global_transform = global_transform
