extends Spatial

var house_info_scene = preload("res://scenes/house_info.tscn")

onready var map = get_node("/root/Level/Map")
onready var characters = get_node("/root/Level/Map/Characters")
onready var utils = get_node("/root/Level/Map/Utils")
onready var buildings = get_node("/root/Level/Map/Buildings")

export var CHARACTER_COST = 10

# first is rogue, last upgrade is impossible
export var CHARACTER_UPGRADE_COSTS = [0, 10, 20, 40, 80]
export var CHARACTER_SALARIES = [0, 2, 6, 18, 54]

export var TOWER_SALARY = 2

export var HOUSE_STARTING_MONEY = 10
export var TILE_MONEY = 1
var houses_money = {}
var houses_info = {}

func pay_tower_salaries(player : int):
	for tower_position in buildings.get_used_cells():
		if map.TOWER_CELLS.has(map.get_building_cell(tower_position)) and \
		   map.get_tile_cell(tower_position) == map.player_tiles[player]:
			spend_connected_money(tower_position, map.player_tiles[player], TOWER_SALARY)
	
func pay_character_salaries(player : int):
	var alive_characters = []
	
	for character in characters.player_characters[player]:
		var character_position = utils.world_to_grid_position(character.translation)
		if spend_connected_money(character_position, map.player_tiles[player], CHARACTER_SALARIES[character.level]):
			alive_characters.append(character)
		else:
			character.became_rogue()
			characters.rogue_characters.append(character)
			
	characters.player_characters[player] = alive_characters

func count_connected_money(starting_position : Vector3, tile_cell : int):
	var connected_money = 0
	
	var visited = {}
	
	var to_visit = [starting_position]
	visited[utils.position_to_string(starting_position)] = null
	
	for current_position in to_visit:
		if map.HOUSE_CELLS.has(map.get_building_cell(current_position)):
			connected_money += houses_money[utils.position_to_string(current_position)]
		
		for direction in map.directions:
			if map.get_tile_cell(current_position + direction) == tile_cell and \
			   not visited.has(utils.position_to_string(current_position + direction)):
				visited[utils.position_to_string(current_position + direction)] = null
				to_visit.append(current_position + direction)
	
	return connected_money
	
func spend_connected_money(starting_position : Vector3, tile_cell : int, money_to_spend : int):
	if money_to_spend <= 0:
		return true
	
	var visited = {}
	
	var to_visit = [starting_position]
	visited[utils.position_to_string(starting_position)] = null
	
	for current_position in to_visit:
		if map.HOUSE_CELLS.has(map.get_building_cell(current_position)):
			var money_in_house = houses_money[utils.position_to_string(current_position)]
			houses_money[utils.position_to_string(current_position)] = max(0, money_in_house - money_to_spend)
			update_house_info(current_position)
			
			money_to_spend -= money_in_house
			if money_to_spend <= 0:
				return true
		
		for direction in map.directions:
			if map.get_tile_cell(current_position + direction) == tile_cell and \
			   not visited.has(utils.position_to_string(current_position + direction)):
				visited[utils.position_to_string(current_position + direction)] = null
				to_visit.append(current_position + direction)
				
	return money_to_spend <= 0

func update_house_info(position : Vector3):
	var position_string = utils.position_to_string(position)
	
	houses_info[position_string].money = houses_money[position_string]

func update_houses_money(player : int):
	var rogue_positions = {}
	for rogue in characters.rogue_characters:
		rogue_positions[utils.position_to_string(utils.world_to_grid_position(rogue.translation))] = null
	
	var visited = {}
	
	var to_visit = []
	
	for building_position in buildings.get_used_cells():
		if map.HOUSE_CELLS.has(map.get_building_cell(building_position)) and \
		   map.get_tile_cell(building_position) == map.player_tiles[player]:
			visited[utils.position_to_string(building_position)] = null
			to_visit.append([building_position, building_position])
	
	for current in to_visit:
		if not rogue_positions.has(utils.position_to_string(current[0])):
			houses_money[utils.position_to_string(current[1])] += TILE_MONEY
			update_house_info(current[1])
		
		for direction in map.directions:
			if map.get_tile_cell(current[0] + direction) == map.player_tiles[player] and \
			   not visited.has(utils.position_to_string(current[0] + direction)):
				visited[utils.position_to_string(current[0] + direction)] = null
				to_visit.append([current[0] + direction, current[1]])

func destroy_house(position : Vector3):
	var position_string = utils.position_to_string(position)

	houses_money.erase(position_string)
	
	houses_info[position_string].queue_free()
	houses_info.erase(position_string)

func init_houses():
	for building_position in buildings.get_used_cells():
		if map.HOUSE_CELLS.has(map.get_building_cell(building_position)):
			var building_position_string = utils.position_to_string(building_position)
			houses_money[building_position_string] = HOUSE_STARTING_MONEY
			houses_info[building_position_string] = utils.spawn_on_position(house_info_scene, building_position)
			update_house_info(building_position)
