minetest.register_alias("mapgen_stone", "pyutest_blocks:stone_block")
minetest.register_alias("mapgen_water_source", "pyutest_blocks:water_source")
minetest.register_alias("mapgen_river_water_source", "pyutest_blocks:water_source")
minetest.register_alias("mapgen_lava_source", "pyutest_blocks:lava_source")
minetest.register_alias("mapgen_singlenode", "air")

local mg_flags = minetest.settings:get_flags("mg_flags")
local mg_name = minetest.get_mapgen_setting("mg_name")
minetest.set_mapgen_setting(string.format("mg%s_cavern_threshold", mg_name), "0.20", true)

mg_flags.caverns = true
mg_flags.dungeons = false

-- https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/mods/MAPGEN/mcl_mapgen_core/init.lua#L127
local mg_flags_str = ""
for k,v in pairs(mg_flags) do
  if v == false then
    k = "no" .. k
  end
  mg_flags_str = mg_flags_str .. k .. ","
end
if string.len(mg_flags_str) > 0 then
  mg_flags_str = string.sub(mg_flags_str, 1, string.len(mg_flags_str)-1)
end
minetest.set_mapgen_setting("mg_flags", mg_flags_str, true)

-- Biomes

PyuTest.BIOME_TOPS = {
  grassland = 30,
  forest = 35,
  desert = 70,
  frozen_plains = 30,
  mountains = 300,
  mushroom_fields = 30,
  ice_spikes = 250,
  swamp = 10
}

-- Overworld biome types
PyuTest.BIOME_TYPES = {
  -- Normal biomes (Forests for example)
  NORMAL = 1,

  -- Chilly biomes, but not snowy (Taigas for example)
  CHILLY = 2,

  -- Snowy biomes (Frozen Plains for example)
  COLD = 3,

  -- Warm biomes (Savannas for example)
  WARM = 4,

  -- Hot biomes (Deserts for example)
  DESERT = 5,

  -- Wasteland biomes (Wastelands and Volcano for example)
  WASTELAND = 6,

  -- Wetland biomes (Swamps for example)
  WETLAND = 7,

  -- Ocean biomes (What example do you want?)
  OCEAN = 8,

  -- Cave biomes (What example do you want?)
  CAVE = 9
}

PyuTest.get_biomes_from_type = function(type)
  local biomes = {}

  for k, v in pairs(minetest.registered_biomes) do
    if v._pyutest_biome_type == type then
      biomes[k] = v
    end
  end

  return biomes
end

PyuTest.get_flowering_biomes = function ()
  local biomes = {}

  for k, v in pairs(minetest.registered_biomes) do
    if v._pyutest_biome_flowering == true and v._pyutest_biome_flowering_extra == false then
      table.insert(biomes, k)
    end
  end

  return biomes
end

PyuTest.get_extra_flowering_biomes = function ()
  local biomes = {}

  for k, v in pairs(minetest.registered_biomes) do
    if v._pyutest_biome_flowering == true and v._pyutest_biome_flowering_extra == true then
      table.insert(biomes, k)
    end
  end

  return biomes
end

-- wrapper around minetest.register_biome but with defaults and caves
PyuTest.register_overworld_biome = function(name, type, opts)
  local nopts = PyuTest.util.tablecopy(opts) or {}
  nopts["name"] = name
  nopts["depth_top"] = nopts["depth_top"] or 1
  nopts["depth_filler"] = nopts["depth_filler"] or 3
  nopts["depth_riverbed"] = nopts["depth_riverbed"] or 2
  nopts["depth_water_top"] = nopts["depth_water_top"] or nil -- cant think of a sane default..

  nopts["node_water"] = nopts["node_water"] or "pyutest_blocks:water_source"
  nopts["node_river_water"] = nopts["node_river_water"] or "pyutest_blocks:water_source"
  nopts["node_riverbed"] = nopts["node_riverbed"] or "pyutest_blocks:gravel_block"

  minetest.register_biome(PyuTest.util.tableconcat(nopts, {
    _pyutest_biome_type = type,
  }))

  minetest.register_biome(PyuTest.util.tableconcat({
    name = name.."_ocean",
    node_top = nopts["node_riverbed"],
    depth_top = 2,
    node_filler = nopts["node_riverbed"],
    depth_filler = 3,
    depth_riverbed = 2,

    node_water = nopts["node_water"],
    node_river_water = nopts["node_river_water"],

    heat_point = nopts["heat_point"],
    humidity_point = nopts["humidity_point"],

    y_max = 0,
    y_min = PyuTest.OVERWORLD_OCEAN_MIN
  }, {
    _pyutest_biome_type = PyuTest.BIOME_TYPES.OCEAN,
    _pyutest_ocean_type = type
  }))

  minetest.register_biome(PyuTest.util.tableconcat({
    name = name.."_deep_ocean",

    node_top = nopts["node_riverbed"],
    depth_top = 2,
    node_filler = nopts["node_riverbed"],
    depth_filler = 3,
    depth_riverbed = 2,

    node_water = nopts["node_water"],
    node_river_water = nopts["node_river_water"],

    heat_point = nopts["heat_point"],
    humidity_point = nopts["humidity_point"],

    y_max = PyuTest.OVERWORLD_DEEP_OCEAN_MAX,
    y_min = PyuTest.OVERWORLD_DEEP_OCEAN_MIN,
    vertical_blend = 5
  }, {
    _pyutest_biome_type = PyuTest.BIOME_TYPES.OCEAN,
    _pyutest_ocean_type = type
  }))

  minetest.register_biome(PyuTest.util.tableconcat({
    name = name.."_cave",
    heat_point = nopts["heat_point"],
    humidity_point = nopts["humidity_point"],
    y_max = PyuTest.OVERWORLD_DEEP_OCEAN_MIN - 1,
    y_min = PyuTest.OVERWORLD_BOTTOM,
  }, {
    _pyutest_biome_type = PyuTest.BIOME_TYPES.CAVE,
    _pyutest_cave_type = type
  }))
end

if PyuTest.is_flat() then
  PyuTest.register_overworld_biome("flat", PyuTest.BIOME_TYPES.NORMAL, {
    node_top = "pyutest_blocks:dark_grass_block",
    node_filler = "pyutest_blocks:dirt_block",

    y_max = PyuTest.BIOME_TOPS.grassland,
    y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

    heat_point = 50,
    humidity_point = 50,
  })

  return
end

PyuTest.register_overworld_biome("grassland", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.grassland,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 53,
  humidity_point = 57,

  _pyutest_biome_flowering = true
})

PyuTest.register_overworld_biome("forest", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:dark_grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 50,
  humidity_point = 65,
  _pyutest_biome_flowering = true
})

PyuTest.register_overworld_biome("stony_mountains", PyuTest.BIOME_TYPES.WARM, {
  node_top = "pyutest_blocks:stone_block",
  node_filler = "pyutest_blocks:stone_block",

  y_max = PyuTest.BIOME_TOPS.mountains,
  y_min = PyuTest.BIOME_TOPS.grassland,

  heat_point = 65,
  humidity_point = 8
})

PyuTest.register_overworld_biome("desert", PyuTest.BIOME_TYPES.DESERT, {
  node_top = "pyutest_blocks:sand_block",
  node_filler = "pyutest_blocks:sandstone_block",
  node_riverbed = "pyutest_blocks:sand_block",

  y_max = PyuTest.BIOME_TOPS.desert,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 84,
  humidity_point = 4
})

PyuTest.register_overworld_biome("desert_mountains", PyuTest.BIOME_TYPES.DESERT, {
  node_top = "pyutest_blocks:sand_block",
  node_filler = "pyutest_blocks:sandstone_block",

  y_max = PyuTest.BIOME_TOPS.mountains,
  y_min = PyuTest.BIOME_TOPS.desert,

  heat_point = 83,
  humidity_point = 6
})

PyuTest.register_overworld_biome("snowy_mountains", PyuTest.BIOME_TYPES.COLD, {
  node_dust = "pyutest_blocks:snow_carpet",
  node_top = "pyutest_blocks:snow_block",
  node_filler = "pyutest_blocks:snow_block",

  y_max = PyuTest.BIOME_TOPS.mountains,
  y_min = PyuTest.BIOME_TOPS.frozen_plains,

  heat_point = 6,
  humidity_point = 72
})

PyuTest.register_overworld_biome("frozen_plains", PyuTest.BIOME_TYPES.COLD, {
  node_dust = "pyutest_blocks:snow_carpet",
  node_top = "pyutest_blocks:snow_block",
  node_filler = "pyutest_blocks:snow_block",

  y_max = PyuTest.BIOME_TOPS.frozen_plains,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  node_water_top = "pyutest_blocks:ice_block",
  depth_water_top = 5,

  heat_point = 9,
  humidity_point = 67
})

PyuTest.register_overworld_biome("mushroom_fields", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:mycelium_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.mushroom_fields,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 53,
  humidity_point = 94
})

PyuTest.register_overworld_biome("ice_spikes", PyuTest.BIOME_TYPES.COLD, {
  node_top = "pyutest_blocks:ice_block",
  node_filler = "pyutest_blocks:ice_block",

  y_max = PyuTest.BIOME_TOPS.ice_spikes,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  node_water_top = "pyutest_blocks:ice_block",
  depth_water_top = 5,

  heat_point = 9,
  humidity_point = 70
})

PyuTest.register_overworld_biome("meadow", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:dark_grass_block",
  node_filler = "pyutest_blocks:dirt_block",
  depth_filler = 4,

  y_max = PyuTest.BIOME_TOPS.mountains,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 52,
  humidity_point = 83,

  _pyutest_biome_flowering = true,
  _pyutest_biome_flowering_extra = true
})

PyuTest.register_overworld_biome("snowy_forest", PyuTest.BIOME_TYPES.COLD, {
  node_dust = "pyutest_blocks:snow_carpet",
  node_top = "pyutest_blocks:snow_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  node_water_top = "pyutest_blocks:ice_block",
  depth_water_top = 5,

  heat_point = 8,
  humidity_point = 69
})

PyuTest.register_overworld_biome("savanna", PyuTest.BIOME_TYPES.WARM, {
  node_top = "pyutest_blocks:savanna_grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.grassland,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 72,
  humidity_point = 9
})

PyuTest.register_overworld_biome("taiga", PyuTest.BIOME_TYPES.CHILLY, {
  node_top = "pyutest_blocks:dark_grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 28,
  humidity_point = 72,

  _pyutest_biome_flowering = true
})

PyuTest.register_overworld_biome("birch_forest", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 48,
  humidity_point = 85,

  _pyutest_biome_flowering = true
})

PyuTest.register_overworld_biome("cherry_grove", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 52,
  humidity_point = 78,

  _pyutest_biome_flowering = true,
  _pyutest_biome_flowering_extra = true
})

PyuTest.register_overworld_biome("swamp", PyuTest.BIOME_TYPES.WETLAND, {
  node_top = "pyutest_blocks:swampy_grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.swamp,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 52,
  humidity_point = 88,
})

PyuTest.register_overworld_biome("old_growth_birch_forest", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 47,
  humidity_point = 73,

  _pyutest_biome_flowering = true,
  _pyutest_biome_flowering_extra = true
})

PyuTest.register_overworld_biome("aspen_forest", PyuTest.BIOME_TYPES.CHILLY, {
  node_top = "pyutest_blocks:aspen_grass_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 25,
  humidity_point = 63,

  _pyutest_biome_flowering = true
})

PyuTest.register_overworld_biome("redwood_forest", PyuTest.BIOME_TYPES.CHILLY, {
  node_top = "pyutest_blocks:podzol_block",
  node_filler = "pyutest_blocks:podzol_block",

  y_max = PyuTest.BIOME_TOPS.forest,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 21,
  humidity_point = 65,

  _pyutest_biome_flowering = true
})

PyuTest.register_overworld_biome("large_mushroom_forest", PyuTest.BIOME_TYPES.NORMAL, {
  node_top = "pyutest_blocks:mycelium_block",
  node_filler = "pyutest_blocks:dirt_block",

  y_max = PyuTest.BIOME_TOPS.mushroom_fields,
  y_min = PyuTest.OVERWORLD_SURFACE_BOTTOM,

  heat_point = 53,
  humidity_point = 98
})
