local internal_api = ...

local mod_path = internal_api.mod_path
local mod_name = internal_api.mod_name
local S = internal_api.translate_single

local schem_path = mod_path .. "/schematics/"

local village_in_a_box = world_settings.get(mod_name, "village_in_a_box")
local graveyard = world_settings.get(mod_name, "graveyard")

local buildings = {}

buildings["graveyard"] = {
	name = "graveyard",
	mts = schem_path .. "graveyard.mts",
	num_others = 20,
	yadjust = -2,
}

buildings["village_in_a_box"] = {
	name = "village_in_a_box",
	mts = schem_path .. "village_in_a_box.mts",
	num_others = 20,
	yadjust = 1,
}

local function graveyard_zombie_spawn(settlement_info, blockseed)
	if world_settings.get(mod_name, "graveyard") then
		for _, def in pairs(settlement_info) do
			if def.name == "graveyard" then
				local pos = def.pos
				local nn = core.find_nodes_in_area(vector.offset(pos, -10, -5, -10),
				                                   vector.offset(pos, 10, 5, 10),
				                                   "mcl_mobspawners:spawner")
				for _, n in pairs(nn) do
					mcl_mobspawners.setup_spawner(n, "mobs_mc:zombie", 0, 11, 5, 10, 1)
				end
			end
		end
	end
end

function indexOf(array, value)
	for i, v in ipairs(array) do if v.name == value then return i end end
	return nil
end

local function switch_building(enabled, name, type)
	local village_table = "schematic_jobs"
	if type and type == "house" then village_table = "schematic_houses" end

	local i = indexOf(mcl_villages[village_table], name)

	if enabled then
		if i == nil then mcl_villages.register_building(buildings[name]) end
	else
		if i then table.remove(mcl_villages[village_table], i) end
	end
end

switch_building(village_in_a_box, "village_in_a_box")
switch_building(graveyard, "graveyard", "house")

local E1 = {"mcl_core:emerald", 1, 1}

local novice_trades = {{E1, {"mcl_potions:glass_bottle", 3, 3}}}

for name, def in pairs(core.registered_nodes) do
	if def.groups["flower"] and not def.groups["double_plant"] and name ~=
		"mcl_flowers:wither_rose" then table.insert(novice_trades, {{def.name, 10, 10}, E1}) end
end

if world_settings.get(mod_name, "bee_farm") then
	-- NOTE: The API for adding professions was removed so bee_keeper has been disabled.
	--[[
	local bee_keeper = {
		name = S("Apiarist"),
		texture = "mobs_mc_villager_leatherworker.png",
		jobsite = "group:beehive",
		trades = {
			novice_trades,
			{
				{ { "mcl_honey:honey_bottle", 2, 2 }, E1 },
				{ { "mcl_campfires:campfire_lit", 1, 1 }, E1 },
				{ E1, { "mcl_honey:honeycomb", 3, 3 } },
			},
			{
				{ { "mcl_core:emerald", 5, 5 }, { "mcl_honey:honey_bottle", 2, 2 } },
				{ { "mcl_beehives:beehive", 1, 1 }, { "mcl_core:emerald", 5, 5 } },
			},

			{
				{ { "mcl_core:emerald", 5, 5 }, { "mcl_honey:honeycomb_block", 1, 1 } },
			},

			{
				{ { "mcl_core:emerald", 2, 2 }, { "mcl_honey:honey_block", 1, 1 } },
				{ { "mcl_core:emerald", 6, 6 }, { "mcl_beehives:beehive", 1, 1 } },
			},
		},
	}

	mobs_mc.register_villager_profession("apiarist", bee_keeper)
	]]

	mcl_villages.register_building({
		name = "bee_farm",
		mts = schem_path .. "bee_farm.mts",
		num_others = 20,
	})
end

-- Add village names and waypoints
local function update_waypoint_def(discovery_distance, waypoint_distance)
	if internal_api.has_named_waypoints then
		local village_waypoint_def = {
			default_name = S("A village"),
			default_color = 0x49A0F6,
			discovery_volume_radius = discovery_distance,
			on_discovery = named_waypoints.default_discovery_popup,
			visibility_volume_radius = waypoint_distance,
		}

		named_waypoints.register_named_waypoints("mingos towns", village_waypoint_def)
	end
end

update_waypoint_def(world_settings.get(mod_name, "village_discovery_distance"),
                    world_settings.get(mod_name, "village_waypoint_distance"))

if internal_api.has_name_generator then
	local name_generator_mod_path = core.get_modpath("name_generator")
	name_generator.parse_lines(io.lines(name_generator_mod_path .. "/data/towns.cfg"))
	name_generator.parse_lines(io.lines(name_generator_mod_path .. "/data/creatures.cfg"))
end

local function name_village(settlement_info, blockseed)
	if internal_api.has_name_generator and internal_api.has_named_waypoints and
		world_settings.get(mod_name, "name_villages") then
		local name = name_generator.generate("mingos towns")
		local bell_info = table.copy(settlement_info[1])
		named_waypoints.add_waypoint("mingos towns", vector.offset(bell_info["pos"], 0, 2, 0),
		                             {name = name})
	end
end

-- Add villager names
local races = {"dwarf", "elf", "gnome", "halfling", "human"}

local genders = {"female", "male"}

local function name_villager(villager_ent, blockseed)
	if internal_api.has_name_generator and world_settings.get(mod_name, "name_villagers") then
		local pr = PseudoRandom(blockseed)
		local l = villager_ent:get_luaentity()
		local name_type = races[pr:next(1, #races)] .. " " .. genders[pr:next(1, #genders)]
		l.nametag = name_generator.generate(name_type)
		l.object:set_nametag_attributes({text = l.nametag})
	end
end

local function add_tpad(settlement_info, blockseed)
	if internal_api.has_tpad and world_settings.get(mod_name, "tpads_for_villages") then
		local bell_info = table.copy(settlement_info[1])

		local flag_pos = vector.offset(bell_info["pos"], 0, 2, 0)

		local pad_name = "Town Pad"

		if internal_api.has_name_generator and internal_api.has_named_waypoints and
			world_settings.get(mod_name, "name_villages") then
			local data = named_waypoints.get_waypoint("mingos towns", flag_pos)
			if data and data.name then pad_name = data.name end
		end

		local pos = vector.offset(bell_info["pos"], -1, 2, 0)
		core.set_node(pos, {name = "tpad:tpad"})

		local meta = core.get_meta(pos)
		meta:set_string("owner", "Villages")
		meta:set_string("infotext", S("TPAD Village Station - right click to interact"))
		tpad.set_pad_data(pos, pad_name, "Global (any network)")
	end
end

if mcl_villages.on_village_placed ~= nil then
	mcl_villages.register_on_village_placed(name_village)
	mcl_villages.register_on_villager_spawned(name_villager)
	mcl_villages.register_on_village_placed(graveyard_zombie_spawn)
	mcl_villages.register_on_village_placed(add_tpad)
end

core.register_on_chatcommand(function(name, command, params)
	if command ~= "wset" or params == "" or core.check_player_privs(name, {server = false}) then
		return
	end

	local sparam = params:split(" ")
	local key = sparam[1]
	local value = sparam[2]

	if key == mod_name .. ".village_in_a_box" then
		switch_building(value == "true", "village_in_a_box")
	elseif key == mod_name .. ".graveyard" then
		switch_building(value == "true", "graveyard", "house")
	elseif key == mod_name .. ".village_discovery_distance" then
		update_waypoint_def(value, world_settings.get(mod_name, "village_waypoint_distance"))
	elseif key == mod_name .. ".village_waypoint_distance" then
		update_waypoint_def(world_settings.get(mod_name, "village_discovery_distance"), value)
	end
end)
