extends Node
class_name MapGenerator

# Map constants
var GRID_WIDTH = Global.GRID_WIDTH
var GRID_HEIGHT = Global.GRID_HEIGHT
var EMPTY = Global.MAP_EMPTY
var PATH = Global.MAP_PATH
var START = Global.MAP_START
var FINISH = Global.MAP_FINISH
var UP_CELL = Global.MAP_UP_CELL

# Map generation parameters
var up_probability_base = 0.1 # Base probability to move up
var up_probability_increase = 0.2 # How much the probability increases each time we stay on the same row

# The map grid
var map = []

func generate_map():
	# Initialize map with empty cells
	map = []
	for y in range(GRID_HEIGHT):
		var row = []
		for x in range(GRID_WIDTH):
			row.append(EMPTY)
		map.append(row)
	
	# Pick a starting location in the bottom row
	var current_x = RNG.randi() % GRID_WIDTH
	var current_y = GRID_HEIGHT - 1
	
	# Mark as start
	map[current_y][current_x] = START
	
	# Track visited cells to avoid loops
	var visited = {}
	visited[Vector2(current_x, current_y)] = true
	
	# Path generation
	var final_position = generate_path(current_x, current_y, visited)
	
	# Set finish cell in top row and connect path to it
	connect_to_finish(final_position.x, final_position.y, visited)

# Generate path from start to top row, return final position
func generate_path(current_x, current_y, visited):
	var up_probability = up_probability_base
	
	while current_y > 0: # Continue until we reach the top row
		# Try to move left or right until we can't proceed further
		var can_move_horizontal = true
		
		while can_move_horizontal:
			# Decide whether to try moving up
			if RNG.randf() < up_probability:
				# We'll try moving up
				break
				
			# Increase probability for next time
			up_probability += up_probability_increase
			
			# Choose direction randomly (left or right)
			var direction = 1 if RNG.randf() > 0.5 else -1
			var new_x = current_x + direction
			
			# Check if we can move in that direction
			if new_x >= 0 and new_x < GRID_WIDTH and not Vector2(new_x, current_y) in visited:
				current_x = new_x
				map[current_y][current_x] = PATH
				visited[Vector2(current_x, current_y)] = true
			else:
				# Try the other direction
				direction = - direction
				new_x = current_x + direction
				
				if new_x >= 0 and new_x < GRID_WIDTH and not Vector2(new_x, current_y) in visited:
					current_x = new_x
					map[current_y][current_x] = PATH
					visited[Vector2(current_x, current_y)] = true
				else:
					# Can't move horizontally anymore
					can_move_horizontal = false
		
		# Mark current cell as an UP_CELL before moving up
		map[current_y][current_x] = UP_CELL
		
		# Move up
		current_y -= 1
		map[current_y][current_x] = PATH
		visited[Vector2(current_x, current_y)] = true
		
		# Reset up probability since we've moved up
		up_probability = up_probability_base
	
	# Return the final position (on the top row)
	return Vector2(current_x, current_y)

# Connect the path to a finish point in the top row
func connect_to_finish(current_x, current_y, visited):
	# Choose a finish position
	var finish_x = RNG.randi() % GRID_WIDTH
	
	# If we randomly picked the current position, we're done
	if finish_x == current_x:
		map[current_y][current_x] = FINISH
		return
	
	# Otherwise, create a path to the finish
	var direction = 1 if finish_x > current_x else -1
	
	# Move horizontally toward the finish position
	while current_x != finish_x:
		current_x += direction
		
		# If we've already visited this cell, we have a loop - break and place finish here
		if Vector2(current_x, current_y) in visited:
			break
			
		map[current_y][current_x] = PATH
		visited[Vector2(current_x, current_y)] = true
	
	# Place finish at the final position
	map[current_y][current_x] = FINISH

func print_map():
	print("Generated Map:")
	print("- Legend: 0=Empty, 1=Path, 2=Start, 4=Finish, 3=MoveUp")
	print("")
	
	var visual_map = ""
	
	for y in range(GRID_HEIGHT):
		var row_str = ""
		for x in range(GRID_WIDTH):
			var cell_value = map[y][x]
			match cell_value:
				EMPTY: row_str += "[ ] "
				PATH: row_str += "[•] "
				START: row_str += "[S] "
				FINISH: row_str += "[F] "
				UP_CELL: row_str += "[↑] "
		visual_map += row_str + "\n"
	
	print(visual_map)
	
	# Also print as numerical grid
	visual_map = ""
	for y in range(GRID_HEIGHT):
		var row_str = ""
		for x in range(GRID_WIDTH):
			row_str += str(map[y][x]) + " "
		visual_map += row_str + "\n"
	
	print(visual_map)

func get_map():
	return map
