@tool
extends Node

const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")

var _screen_size : Vector2i

var _camera_points : Array[CameraPointer]
var _current_camera_point : CameraPointer


signal anchors_changed

var _anchors : Array[CameraAnchor]

#region 相機指針
func request_register_pointer(ptr: CameraPointer) -> bool:
	if not is_instance_valid(ptr):
		return false

	var cam := ptr.get_camera()
	if not is_instance_valid(cam):
		return false  # System 决定：无效 camera 不接受注册

	# 去重
	if ptr in _camera_points:
		_current_camera_point = ptr
		return true

	_camera_points.append(ptr)

	# 你可以在这里做选择策略：比如最新优先/priority
	_current_camera_point = ptr
	return true

func request_unregister_pointer(ptr: CameraPointer) -> void:
	_camera_points.erase(ptr)
	if _current_camera_point == ptr:
		_current_camera_point = _camera_points.back() if _camera_points.size() > 0 else null

func get_current_camera_pointer() -> CameraPointer:
	return _current_camera_point

func get_camera() -> Camera2D:
	return _current_camera_point.get_camera() if _current_camera_point else null
#endregion

#region 相機錨點
func register_anchor(anchor: CameraAnchor) -> void:
	if anchor in _anchors:
		return

	_anchors.append(anchor)

	# 监听 anchor 内部变化
	anchor.on_priority_change.connect(_on_anchor_priority_changed)

	anchors_changed.emit()

func unregister_anchor(anchor: CameraAnchor) -> void:
	if anchor in _anchors:
		_anchors.erase(anchor)

	if anchor.on_priority_change.is_connected(_on_anchor_priority_changed):
		anchor.on_priority_change.disconnect(_on_anchor_priority_changed)

	anchors_changed.emit()

func _on_anchor_priority_changed(_p: int, _a: CameraAnchor) -> void:
	anchors_changed.emit()

func get_all_anchors() -> Array[CameraAnchor]:
	return _anchors.duplicate()

func clear_camera_anchors() -> void:
	_anchors.clear()
	anchors_changed.emit()
#endregion

func _enter_tree() -> void:
	if not Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME):
		Engine.register_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME, self)

func _ready() -> void:
	# Setting default screensize
	_screen_size = Vector2i(
		ProjectSettings.get_setting("display/window/size/viewport_width"),
		ProjectSettings.get_setting("display/window/size/viewport_height")
	)

	# For editor
	if Engine.is_editor_hint():
		ProjectSettings.settings_changed.connect(func():
			_screen_size = Vector2i(
				ProjectSettings.get_setting("display/window/size/viewport_width"),
				ProjectSettings.get_setting("display/window/size/viewport_height")
			)
		)
	# For runtime
	else:
		get_tree().get_root().size_changed.connect(func():
			_screen_size = get_viewport().get_visible_rect().size
		)

func get_screen_size() -> Vector2i:
	return _screen_size
