@tool
extends PanelContainer
class_name StateDropArea

signal node_dropped(node: Node)

@export var icon_path: NodePath = NodePath("TextureRect")

const COLOR_IDLE: Color = Color(1, 1, 1, 1.0)
const COLOR_CAN_DROP: Color = Color(0.4, 0.7, 1.0, 1.0)
const COLOR_CANNOT_DROP: Color = Color(1.0, 0.35, 0.35, 1.0)
const COLOR_CHECKED: Color = Color.GREEN

## 設置Locker的時候自更新一次State
var vaild: bool = false:
	set(value):
		vaild = value
		_set_state(0)

var _icon: TextureRect
var _state := 0 # 0 idle, 1 can, 2 cannot
var _current_drag_data: Variant = null

signal node_path_dropped(node_path: NodePath)
signal state_change(state: int)

# =====================================================
# Life cycle
# =====================================================
func _ready() -> void:
	_icon = get_node_or_null(icon_path) as TextureRect

	mouse_filter = Control.MOUSE_FILTER_PASS
	_ignore_mouse_recursive(self)

	if _icon:
		_icon.modulate = COLOR_IDLE

	if custom_minimum_size == Vector2.ZERO:
		custom_minimum_size = Vector2(32, 32)

	#mouse_entered.connect(_on_mouse_entered)
	mouse_exited.connect(_on_mouse_exited)

# =====================================================
# Drag & Drop
# =====================================================
func _can_drop_data(_pos: Vector2, data) -> bool:
	_current_drag_data = data
	var r = StateResolveUtils.is_valid_state_drag(data)
	_set_state(1 if r else 2)
	return r


func _drop_data(_pos: Vector2, data) -> void:
	var path := StateResolveUtils.get_state_path_from_drag(data)
	if path.is_empty():
		return
	node_path_dropped.emit(path)


func _notification(what: int) -> void:
	if what == NOTIFICATION_DRAG_END:
		_current_drag_data = null
		_set_state(0)


# =====================================================
# Mouse events
# =====================================================
func _on_mouse_exited() -> void:
	_set_state(0)

func _ignore_mouse_recursive(n: Node) -> void:
	for c in n.get_children():
		if c is Control:
			(c as Control).mouse_filter = Control.MOUSE_FILTER_IGNORE
		_ignore_mouse_recursive(c)


func _set_state(s: int) -> void:
	if s == _state:
		return
	_state = s

	if _icon == null:
		return

	match _state:
		0:
			if vaild:
				_set_state(3)
				return
			_icon.modulate = COLOR_IDLE
		1:
			_icon.modulate = COLOR_CAN_DROP
		2:
			_icon.modulate = COLOR_CANNOT_DROP
		3:
			_icon.modulate = COLOR_CHECKED
	
	state_change.emit(_state)
