PyuTestCore.make_node_sounds = function(tbl)
  local t = tbl or {}
  t.footstep = t.footstep or {name = "block_walk", gain = 1}
  t.dig = t.dig or {name = "block_dig", gain = 0.50}
  t.dug = t.dug or {name = "block_break", gain = 0.50}
  t.place = t.place or {name = "block_place", gain = 0.50}
  return t
end

PyuTestCore.make_node = function(name, desc, groups, tiles, extra_conf)
  local conf = {
    description = Translate(desc),
    tiles = tiles,
    groups = groups,
    sounds = PyuTestCore.make_node_sounds()
  }

  if extra_conf ~= nil then
    for k, v in pairs(extra_conf) do
      conf[k] = v
    end
  end

  minetest.register_node(name, conf)
end

PyuTestCore.node_boxes = {
  CARPET = {
    type = "fixed",
    fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5}
  },
  SLAB = {
    type = "fixed",
    fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}
  },
  PILLAR = {
    type = "fixed",
    fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}
  },
  STAIRS = {
    type = "fixed",
    fixed = {
      {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
      {-0.5, 0, 0, 0.5, 0.5, 0.5},
    },
  },
}
PyuTestCore.building_blocks = {}

PyuTestCore.make_building_blocks = function (name, desc, tex, colortint, cgroups, extra_conf)
  local groups = PyuTestCore.util.tablecopy(cgroups) or {
    block = PyuTestCore.BLOCK_BREAKABLE_NORMAL
  }
  groups["block"] = groups["block"] or PyuTestCore.BLOCK_BREAKABLE_NORMAL

  local econf = extra_conf or {}
  econf["is_ground_content"] = econf["is_ground_content"] or true
  econf["color"] = colortint

  local id_block = name.."_block"
  local id_carpet = name.."_carpet"
  local id_slab = name.."_slab"
  local id_pillar = name.."_pillar"
  local id_stairs = name.."_stairs"
  local id_fence = name.."_fence"

  table.insert(PyuTestCore.building_blocks, {
    name = name,
    desc = desc,
    tiles = tex,
    groups = groups,
    econf = econf
  })

  minetest.register_node(id_block, PyuTestCore.util.tableconcat({
    description = Translate(desc.." Block"),
    tiles = tex,
    groups = PyuTestCore.util.tableconcat(groups, {
        solid = 1
    }),
    sounds = PyuTestCore.make_node_sounds(),
  }, econf))

  minetest.register_node(id_carpet, PyuTestCore.util.tableconcat({
    description = Translate(desc .. " Carpet"),
    tiles = tex,
    groups = PyuTestCore.util.tableconcat(PyuTestCore.util.tablecopy(groups), {
      attached_node = 3
    }),
    drawtype = "nodebox",
    paramtype = "light",
    paramtype2 = "facedir",
    node_box = PyuTestCore.node_boxes.CARPET,
    sounds = PyuTestCore.make_node_sounds(),
  }, econf))

  minetest.register_node(id_slab, PyuTestCore.util.tableconcat({
    description = Translate(desc.." Slab"),
    tiles = tex,
    groups = groups,
    drawtype = "nodebox",
    paramtype = "light",
    node_box = PyuTestCore.node_boxes.SLAB,
    sounds = PyuTestCore.make_node_sounds(),
  }, econf))

  minetest.register_node(id_pillar, PyuTestCore.util.tableconcat({
    description = Translate(desc.." Pillar"),
    tiles = tex,
    groups = groups,
    drawtype = "nodebox",
    paramtype = "light",
    node_box = PyuTestCore.node_boxes.PILLAR,
    sounds = PyuTestCore.make_node_sounds(),
  }, econf))

  minetest.register_node(id_stairs, PyuTestCore.util.tableconcat({
    description = Translate(desc.." Stairs"),
    tiles = tex,
    groups = groups,
    drawtype = "nodebox",
    paramtype = "light",
    paramtype2 = "facedir",
    node_box = PyuTestCore.node_boxes.STAIRS,
    sounds = PyuTestCore.make_node_sounds(),
  }, econf))

  minetest.register_node(id_fence, PyuTestCore.util.tableconcat({
    description = Translate(desc.." Fence"),
    tiles = tex,
    groups = groups,
    drawtype = "fencelike",
    paramtype = "light",
    collision_box = {
      type = "fixed",
      fixed = {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}
    },
    sounds = PyuTestCore.make_node_sounds(),
  }, econf))

  minetest.register_craft({
    output = id_carpet .. " 2",
    recipe = {
      {id_block, id_block}
    }
  })

  minetest.register_craft({
    output = id_slab .. " 3",
    recipe = {
      {id_block, id_block, id_block}
    }
  })

  minetest.register_craft({
    output = id_pillar .. " 3",
    recipe = {
      {id_block},
      {id_block},
      {id_block}
    }
  })

  minetest.register_craft({
    output = id_stairs .. " 4",
    recipe = {
      {id_block, "", ""},
      {id_block, id_block, ""},
      {id_block, id_block, id_block}
    }
  })

   minetest.register_craft({
    output = id_fence .. " 4",
    recipe = {
      {id_block, "pyutest_core:stick", id_block},
      {id_block, "pyutest_core:stick", id_block}
    }
  })
end

PyuTestCore.make_building_blocks("pyutest_core:grass", "Grass", {"pyutest-grass.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  grass = 1
})

PyuTestCore.make_building_blocks("pyutest_core:dark_grass", "Dark Grass", {"pyutest-dark-grass.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  grass = 1
})

PyuTestCore.make_building_blocks("pyutest_core:swampy_grass", "Swampy Grass", {"pyutest-swampy-grass.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  sugarcane_spawn_on = 1,
  grass = 1
})

PyuTestCore.make_building_blocks("pyutest_core:savanna_grass", "Savanna Grass", {"pyutest-savanna-grass.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  sugarcane_spawn_on = 1,
  grass = 1
})

PyuTestCore.make_building_blocks("pyutest_core:aspen_grass", "Aspen Grass", {"pyutest-aspen-grass.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  grass = 1
})

PyuTestCore.make_building_blocks("pyutest_core:jungle_grass", "Jungle Grass", {"pyutest-jungle-grass.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  grass = 1
})

PyuTestCore.make_building_blocks("pyutest_core:dirt", "Dirt", {"pyutest-dirt.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1
})

PyuTestCore.make_building_blocks("pyutest_core:podzol", "Podzol", {"pyutest-podzol.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1
})

PyuTestCore.make_building_blocks("pyutest_core:stone", "Stone", {"pyutest-stone.png"}, nil, {
  ground = 1,
  stone = 1,
  block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE,
}, {is_ground_content = false})

PyuTestCore.make_building_blocks("pyutest_core:snow", "Snow", {"pyutest-snow.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1
})

PyuTestCore.make_building_blocks("pyutest_core:sand", "Sand", {"pyutest-sand.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  falling_node = 1,
  sugarcane_spawn_on = 1
})

PyuTestCore.make_building_blocks("pyutest_core:sandstone", "Sandstone", {"pyutest-sandstone.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1
}, {is_ground_content = false})

PyuTestCore.make_building_blocks("pyutest_core:ice", "Ice", {"pyutest-ice.png"}, nil, {
  ground = 1,
  acid_vulnerable = 1,
  slippery = 4
})

PyuTestCore.make_building_blocks("pyutest_core:mushroom", "Mushroom", {"pyutest-mushroom.png"}, nil, {
  flammable = 1
}, {is_ground_content = false})
PyuTestCore.make_building_blocks("pyutest_core:mushroom_stem", "Mushroom Stem", {"pyutest-mushroom-stem.png"}, nil, {
  flammable = 1
}, {is_ground_content = false})
PyuTestCore.make_building_blocks("pyutest_core:mycelium", "Mycelium", {"pyutest-mycelium.png"}, nil, {ground = 1})
PyuTestCore.make_building_blocks("pyutest_core:molten_rock", "Molten Rock", {"pyutest-molten-rock.png"}, nil, {
  ground = 1,
  block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE
}, {is_ground_content = false})

PyuTestCore.make_building_blocks("pyutest_core:basalt", "Basalt", {"pyutest-basalt.png"}, nil, {
  ground = 1,
  block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE
}, {is_ground_content = false})

PyuTestCore.make_building_blocks("pyutest_core:obsidian", "Obsidian", {"pyutest-obsidian.png"}, nil, {
  block = PyuTestCore.BLOCK_BREAKABLE_VERYLONG
}, {is_ground_content = false})

PyuTestCore.make_building_blocks("pyutest_core:haybale", "Haybale", {
    "pyutest-haybale-top-bottom.png",
    "pyutest-haybale-top-bottom.png",
    "pyutest-haybale.png"
}, nil)

                            -- keeping old ID for backwards compatibility
PyuTestCore.make_building_blocks("pyutest_core:crying_obsidian", "Enchanted Obsidian", {
    "pyutest-enchanted-obsidian.png"
}, nil, {
    block = PyuTestCore.BLOCK_BREAKABLE_VERYLONG
}, {
    is_ground_content = false
})

PyuTestCore.make_building_blocks("pyutest_core:brick", "Brick", {"pyutest-bricks.png"}, nil, {
    block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE
}, {
    is_ground_content = false
})

PyuTestCore.make_building_blocks("pyutest_core:stone_bricks", "Stone Bricks", {"pyutest-stone-bricks.png"}, nil, {
    block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE
}, {
    is_ground_content = false
})

PyuTestCore.make_building_blocks("pyutest_core:slime", "Slime", {"pyutest-slime.png"}, nil, {bouncy = 85})

PyuTestCore.make_building_blocks("pyutest_core:clay", "Clay", {"pyutest-clay-block.png"}, nil, {
  acid_vulnerable = 1
})

PyuTestCore.make_building_blocks("pyutest_core:gravel", "Gravel", {"pyutest-gravel.png"}, nil, {
  falling_node = 1,
  acid_vulnerable = 1
})

PyuTestCore.make_building_blocks("pyutest_core:crystal_lantern", "Crystal Lantern", {"pyutest-crystal-lantern.png"}, nil, {
  block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE
}, {
  light_source = minetest.LIGHT_MAX
})

PyuTestCore.make_building_blocks("pyutest_core:bone", "Bone", {
    "pyutest-bone-block-top-bottom.png",
    "pyutest-bone-block-top-bottom.png",
    "pyutest-bone-block.png"
}, nil, {
  block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE
})

PyuTestCore.make_node("pyutest_core:light", "Light", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT,
  light = 1
}, {
  "pyutest-light.png"
}, {
  drawtype = "torchlike",
  walkable = false,
  paramtype = "light",
  sunlight_propagates = true,
  light_source = minetest.LIGHT_MAX
})

PyuTestCore.make_node("pyutest_core:torch", "Torch", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT,
  light = 1,
  attached_node = 1
}, {
  "pyutest-torch.png",
  "pyutest-torch.png^[transform6",
  "pyutest-torch.png^[transform1"
}, {
  light_source = minetest.LIGHT_MAX,
  walkable = false,
  drawtype = "torchlike",
  paramtype = "light",
  inventory_image = "torch.png",
  paramtype2 = "wallmounted",
})

PyuTestCore.make_node("pyutest_core:sponge", "Sponge", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT
}, {"pyutest-sponge.png"})

PyuTestCore.make_node("pyutest_core:glass", "Glass", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT
}, {"pyutest-glass.png"}, {
  drawtype = "glasslike_framed",
  paramtype = "light",
  sunlight_propagates = true
})

PyuTestCore.make_node("pyutest_core:tree_sapling", "Tree Sapling", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT,
  flammable = 1
}, {
    "pyutest-sapling.png"
}, {
  drawtype = "plantlike",
  walkable = false,
  waving = 1,
  buildable_to = true,
  paramtype = "light",
  sunlight_propagates = true,
  inventory_image = "pyutest-sapling.png",

  on_timer = function (pos)

    -- FIXME: Update to new tree schematic names
    local trees = {
      "tree",
      "tree2",
      "tree3",
      "tree4",
      "tree5",
      "tree6",
      "tree7",
      "tree8",
      "stree"
    }

    math.randomseed(os.time())
    local selected_tree = trees[math.random(#trees)]

    minetest.remove_node(pos)
    pos.y = pos.y - 1
    minetest.place_schematic(pos, PyuTestCore.get_schem_path(selected_tree), "random", nil, false, "place_center_x, place_center_z")
  end,

  on_rightclick = function (pos)
    local timer = minetest.get_node_timer(pos)
    timer:start(6)
  end
})

-- FIXME: This has been in the game for a month, implement it already!
PyuTestCore.make_node("pyutest_core:trapdoor", "Trapdoor", {
  block = PyuTestCore.BLOCK_BREAKABLE_CHOPPY,
  flammable = 1
}, {"pyutest-trapdoor.png"}, {
  drawtype = "nodebox",
  paramtype = "light",
  sunlight_propagates = true,
  node_box = {
    type = "fixed",
    fixed = {-0.5, -0.5, -0.5, 0.5, -0.15, 0.5}
  }
})

PyuTestCore.make_node("pyutest_core:contagious_acid", "Contagious Acid", {
  block = PyuTestCore.BLOCK_BREAKABLE_MIDDLE,
}, {"pyutest-acid.png"}, {})

PyuTestCore.make_node("pyutest_core:barrier", "Barrier", {
  block = PyuTestCore.BLOCK_BREAKABLE_FOREVER
}, {}, {
  drawtype = "airlike",
  walkable = true,
  paramtype = "light",
  sunlight_propagates = true,
  inventory_image = "pyutest-barrier.png",
  wield_image = "pyutest-barrier.png"
})

PyuTestCore.make_node("pyutest_core:fire", "Fire", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT
}, {"pyutest-fire.png"}, {
  drawtype = "firelike",
  walkable = false,
  buildable_to = true,
  paramtype = "light",
  sunlight_propagates = true,
  damage_per_second = 2,
  light_source = 8,
  drop = "pyutest_core:ash 4"
})

PyuTestCore.make_node("pyutest_core:tnt", "TNT", {
  block = PyuTestCore.BLOCK_BREAKABLE_INSTANT
}, {
  "pyutest-tnt-top-bottom.png",
  "pyutest-tnt-top-bottom.png",
  "pyutest-tnt-side.png" -- Affects all other sides
}, {
  on_rightclick = function (pos, _, clicker)
    local timer = minetest.get_node_timer(pos)
    minetest.after(3, function()
      PyuTestCore.create_explosion(pos, 3, true, 3, clicker, true)
    end)
  end,

  on_timer = function (pos)
    PyuTestCore.create_explosion(pos, 3, true, 3)
  end
})

PyuTestCore.make_node("pyutest_core:crate", "Crate", {
  block = PyuTestCore.BLOCK_BREAKABLE_CHOPPY
}, {"pyutest-crate.png"}, {
  on_construct = function (pos)
    local meta = minetest.get_meta(pos)
    local inventory = meta:get_inventory()
    inventory:set_size("main", 8 * 4)
  end,

  can_dig = function (pos, player)
    local meta = minetest.get_meta(pos)
    local inventory = meta:get_inventory()
    local empty = inventory:is_empty("main")

    if not empty then
      minetest.chat_send_player(player:get_player_name(), "Cannot destroy crate, it's not empty!")
    end

    return empty
  end,

  on_rightclick = function (pos, node, clicker)
    local spos = string.format("%d,%d,%d", pos.x, pos.y, pos.z)
    local formspec =
      "size[8,9]" ..
      "list[nodemeta:"..spos..";main;0,0;8,4;]" ..
      "list[current_player;main;0,5;8,4;]" ..
      "listring[nodemeta:"..spos..";main]" ..
      "listring[current_player;main]"
    minetest.show_formspec(clicker:get_player_name(), string.format("pyutest_core:crate_%d_%d_%d", pos.x, pos.y, pos.z), formspec)
    minetest.sound_play({name = "crate_open", gain = 1}, {pos = pos})
  end
})

PyuTestCore.make_node("pyutest_core:workbench", "Workbench", {
  block = PyuTestCore.BLOCK_BREAKABLE_CHOPPY
}, {
    "pyutest-workbench-top.png",
    "pyutest-workbench-bottom.png",
    "pyutest-workbench-sides.png"
}, {
  on_rightclick = function(pos, node, clicker)
    minetest.show_formspec(clicker:get_player_name(), "pyutest_core:workbench", table.concat({
      "size[8,9]",
      "list[current_player;craft;2.5,1;3,3;]",
      "list[current_player;main;0,5;8,4;]"
    }))
  end
})

PyuTestCore.make_node("pyutest_core:ladder", "Ladder", {
  block = PyuTestCore.BLOCK_BREAKABLE_CHOPPY
}, {"pyutest-ladder.png"}, {
  drawtype = "signlike",
  paramtype = "light",
  walkable = false,
  climbable = true,
  buildable_to = true,
  sunlight_propagates = true,
  paramtype2 = "wallmounted",
  selection_box = {
    type = "wallmounted"
  },
  inventory_image = "pyutest-ladder.png"
})
