class_name FileWatcher

signal file_changed

var file_name: String setget set_file_name
var scan_delay_s: float = 1.0 setget set_scan_delay_s

var _file := File.new()
var _last_modified: int = 0
var _timer := Timer.new()


func _init() -> void:
	# warning-ignore:return_value_discarded
	_timer.connect("timeout", self, "check")
	_timer.wait_time = scan_delay_s


func set_file_name(new_file_name: String) -> void:
	if file_name == new_file_name:
		return
	file_name = new_file_name
	if file_name.begins_with("res://") or file_name.begins_with("user://"):
		file_name = ProjectSettings.globalize_path(file_name)
	_last_modified = _file.get_modified_time(file_name)
	_timer.name = "__file_watcher_%s"%[file_name]


func set_scan_delay_s(new_scan_delay_s: float) -> void:
	scan_delay_s = new_scan_delay_s
	_timer.wait_time = scan_delay_s


func check() -> void:
	if file_name == "":
		return
	var new_modified := _file.get_modified_time(file_name)
	if new_modified != _last_modified:
		_last_modified = new_modified
		emit_signal("file_changed")


func start() -> void:
	if not _timer.is_inside_tree():
		var main_loop: SceneTree = Engine.get_main_loop()
		var root := main_loop.root
		if root == null:
			printerr("Called start before any scene is loaded")
			return
		if not root.is_inside_tree():
			yield(root, "ready")
		root.call_deferred("add_child", _timer, true)
		yield(_timer, "ready")
	_timer.start()


func stop() -> void:
	_timer.stop()


