class_name ProgressTracker
extends Object

## Signal emitted when there is a progress update
signal progress_update
## Signal emitted when the current step changes
signal step_change(step: int)
## Signal emitted when the all steps are completed
signal complete
## Signal emitted when a step is completed
signal step_complete

var _current_step: ProgressStepTracker = null
var _current_step_index: int = -1
var _steps_count: int


func _init(step_count: int = 0) -> void:
	_steps_count = step_count


## Progresses to the next step
func next_step(step_name: String = "") -> ProgressStepTracker:
	_current_step_index += 1
	if _current_step_index > _steps_count:
		push_error("Number of steps tracked is larger than number of steps used!")
	step_change.emit(_current_step_index)

	self._current_step = ProgressStepTracker.new(self, step_name)
	self.progress_update.emit()

	return self._current_step


## Returns the progress of the current step
func get_step_progress() -> float:
	return float(_current_step_index) / float(_steps_count)


## Returns the progress of the current step
func get_total_progress_percentage() -> float:
	var progress: float = self.get_step_progress()
	if self._current_step:
		return progress + (self._current_step.get_progress() / self._steps_count)
	return progress


## Returns a dictionary with the following keys:
## - step_name: the name of the current step
## - message: the message of the current step
## - substeps: the number of substeps in the current step
## - current_substep: the index of the current substep
## - total_progress: the progress of all steps and substeps
func get_progress_data() -> Dictionary:
	if not _current_step:
		return {
			"step_name": "", "message": "", "substeps": 0, "current_substep": 0, "total_progress": 0
		}
	return {
		"step_name": self._current_step.get_step_name(),
		"message": self._current_step.get_message(),
		"substeps": self._current_step.get_substep_count(),
		"current_substep": self._current_step.get_substep_index(),
		"total_progress": self.get_total_progress_percentage()
	}
