@tool
extends Node2D
class_name TravelScreenContent

const SHIP_ICON = preload("res://common/icons/rocket.svg")
const START_ICON = preload("res://common/icons/device-floppy.svg")
const REGION_ICON = preload("res://common/icons/globe.svg")
const DESTINATION_ICON = preload("res://common/icons/flag-2.svg")
const DANGER_ICON = preload("res://common/icons/alert-triangle.svg")
const AND_MORE_ICON = preload("res://common/icons/dots.svg")

const PREVIOUS_COLOR = Color("2364AAAA")
const CURRENT_COLOR = Color("e29f32")
const NEXT_COLOR = Color("96B3DB")

const WIDTH = 800
const V_DIST = 50 
const ANIMATION_SPEED := 5.0
const MAX_STEP = 10

@export_tool_button("Update", "Callable") var update_action = update
@export_tool_button("Update recreate", "Callable") var update_recreate_action = func (): update(true, true)

@export var current_position : float = 0
@export var run_data : RunData
@export var story_step : StoryStep
@export var start : int = 0

func _ready():
    update(false, true)

var ship_icon : Sprite2D

func update(with_animation := true, recreate_map = false):

    if is_node_ready() and story_step and run_data:
        if recreate_map or not ship_icon:

            if story_step and get_step_number() < story_step.get_region_sequence_length(run_data.difficulty_setting):
                start = floori(current_position)
            else:
                start = 0

            for c in %Icons.get_children():
                c.queue_free()

            for i in range(get_step_number()):
                var level = i + start
                var icon = REGION_ICON
                if story_step and level == 0:
                    icon = START_ICON
                elif story_step and level == story_step.get_region_sequence_length(run_data.difficulty_setting) - 1:
                    icon = DESTINATION_ICON

                var color = NEXT_COLOR
                if level < current_position - start:
                    color = PREVIOUS_COLOR
                elif level == current_position - start:
                    color = CURRENT_COLOR

                if icon != START_ICON and icon != DESTINATION_ICON:
                    var modifiers := story_step.get_story_modifiers_for_region(level, run_data.difficulty_setting)
                    modifiers.append_array(story_step.get_gameplay_modifiers_for_region(level, run_data.difficulty_setting))
                    for m_i in range(len(modifiers)):
                        spawn_icon(modifiers[m_i].get_icon(), Vector2(i,-m_i - 1),color, 0.7) 

                    if story_step.is_run_point_dangerous(level, run_data.difficulty_setting):
                        spawn_icon(DANGER_ICON, Vector2(i,-len(modifiers) - 1),color, 0.7)

                spawn_icon(icon, Vector2(i,0),color) 
            
            ship_icon = spawn_icon(SHIP_ICON, Vector2(current_position - start, 1), CURRENT_COLOR, 1)

            if story_step and get_step_number() + start < story_step.get_region_sequence_length(run_data.difficulty_setting):
                spawn_icon(AND_MORE_ICON, Vector2(get_step_number(), 0), NEXT_COLOR)
    
        if ship_icon and with_animation:
            var tween = create_tween()
            tween.set_trans(Tween.TRANS_SPRING)
            tween.tween_property(ship_icon,"position",coord_to_pos(Vector2(current_position - start, 1)),ANIMATION_SPEED)
            
            await tween.finished

            for icon in %Icons.get_children():
                var color = NEXT_COLOR
                if icon.position.x < ship_icon.position.x:
                    color = PREVIOUS_COLOR
                elif icon.position.x == ship_icon.position.x:
                    color = CURRENT_COLOR
                icon.modulate = color


func spawn_icon(texture : Texture, coord := Vector2.ZERO, color := Color.WHITE, scaling := 1.) -> Sprite2D:
    var new_icon = Sprite2D.new()
    new_icon.texture = texture
    new_icon.modulate = color
    new_icon.scale = Vector2.ONE * scaling

    %Icons.add_child(new_icon)

    new_icon.position = coord_to_pos(coord)

    return new_icon

func get_step_number() -> int:
    if story_step and run_data:
        return min(story_step.get_region_sequence_length(run_data.difficulty_setting), MAX_STEP)
    return 0

func coord_to_pos(coord : Vector2) -> Vector2:
    var h_dist = WIDTH / (get_step_number() + 2.)

    return Vector2(
        coord.x * h_dist - float(get_step_number())/2 * h_dist + h_dist/2.,
        coord.y * V_DIST,
    )
