class_name QuestProgressBar extends Control

const waypoint_template = preload("res://templates/waypoint.tscn")
var length : float
var waypoints : Array[Waypoint] = []
@onready var hero_offset : Vector2 = %Hero.position
@onready var hero : HeroIcon = %Hero
@onready var heroLabel : Label = %HeroLabel
@onready var startpoint : Endpoint = %Start
@onready var endpoint : Endpoint = %End
@onready var bar : TextureProgressBar = $ProgressBar
@onready var path : Control = %Path
@onready var speech_bubble = %SpeechBubble
var quest : Quest = null
var current_event : Quest.Event = null
var time_elapsed : float = 0
var next_waypoint = 0
var failed : bool = false
#signal value_changed(value : float)
#var min_value
#var max_value
#var step
#var page
#var value
#var exp_edit
#var rounded
#var allow_greater
func _ready() -> void:
	length = path.size.x
	hero.position = hero_offset + Vector2(length * bar.value / bar.max_value, 0)

func _process(delta: float) -> void:
	if failed:
		return
	if time_elapsed < quest.length:
		if current_event != null:
			current_event.process(delta)
		else:
			time_elapsed += delta
			progress_quest()

func generate_waypoints():
	if len(waypoints) > 0:
		for wp in waypoints:
			wp.queue_free()
	waypoints = []
	
	#Include the "end" in the count
	var num = quest.num_events()
	#add_waypoint(0, Quest.Event.new())
	#waypoints[0].
	for evt : Quest.Event in quest.events:
		add_waypoint( evt.progress_point, evt)
	#add_waypoint(1, Quest.Event.new())
	
func add_waypoint(pct : float, event : Quest.Event):
		var wp = waypoint_template.instantiate()

		waypoints.append(wp)
		wp.percent = pct
		#TODO: Make events matter
		wp.event = event
		%Waypoints.add_child(wp)
		if event.hidden:
			wp.visible = false
		wp.global_position = %Waypoints.global_position + Vector2(pct * length - 16, -9)
		if bar.value / bar.max_value >= pct:
			wp.fill = true

func update_waypoints(value : float) -> void:
	startpoint.fill = (bar.value / bar.max_value >= startpoint.percent)
	for wp : Waypoint in waypoints:
		wp.fill = (bar.value / bar.max_value >= wp.percent)
	endpoint.fill = (bar.value / bar.max_value >= endpoint.percent)

func start_event(event : Quest.Event, offset : float) -> void:
	current_event = event
	current_event.completed.connect(_on_event_complete)
	current_event.failed.connect(_on_event_failed)
	current_event.start(quest)
	event.time_elapsed = offset

func setup(quest : Quest) -> void:
	self.quest = quest
	heroLabel.text = quest.questor.full_name()
	time_elapsed = 0
	#Generate the waypoints
	generate_waypoints()
	#TODO: Change the hero's portrait
	bar.value = quest.progress

func progress_quest() -> void:
	var pct = time_elapsed / quest.length
	quest.progress = pct
	if next_waypoint < len(waypoints) and pct >= waypoints[next_waypoint].percent:
		if waypoints[next_waypoint].visible == false: 
			waypoints[next_waypoint].visible = true
		start_event(waypoints[next_waypoint].event, (pct - waypoints[next_waypoint].percent) * quest.length)
		pct = waypoints[next_waypoint].percent
		waypoints[next_waypoint].blink(true)
	bar.value = clampf(pct, 0, bar.max_value)
	hero.position = hero_offset + Vector2(length * bar.value / bar.max_value, 0)
	if time_elapsed >= quest.length:
		quest.complete()
	update_waypoints(bar.value)

func set_fill_color(color : Color) -> void:
	%Start/Fill.self_modulate = color
	%End/Fill.self_modulate = color
	$ProgressBar.tint_progress = color
	for wp : Waypoint in waypoints:
		wp.fill_color = color

func _on_event_complete() -> void:
	#TODO: Show event message!
	speech_bubble.show_message("Event complete!")
	if current_event.type == Quest.Event.Type.COMBAT:
		quest.questview.unpause_setting()
		for p : QuestorSprite in current_event.participants:
			p.set_animation("running")
	waypoints[next_waypoint].blink(false)
	next_waypoint += 1
	current_event = null

func _on_event_failed() -> void:
	failed = true
	set_fill_color(Color.RED)
	quest.fail()
	
