PyuTestCore.util = {
  tablecopy = function(t)
    if t == nil then return nil end
    local t2 = {}
    for k,v in pairs(t) do
      t2[k] = v
    end
    return t2
  end,

  tableconcat = function (t1, t2)
    local nt = PyuTestCore.util.tablecopy(t1)
    for k, v in pairs(t2) do
      nt[k] = v
    end
    return nt
  end,

  tableconcat2 = function(t1, t2)
    local nt = PyuTestCore.util.tablecopy(t1)
    for i = 1, #t2 do
      nt[#nt+i] = t2[i]
    end
    return nt
  end,
}

PyuTestCore.dorange = function(origin, range, action)
  for dx = -range, range do
    for dz = -range, range do
      for dy = -range, range do
        action(vector.new(origin.x + dx, origin.y + dy, origin.z + dz))
      end
    end
  end
end

PyuTestCore.create_explosion = function (pos, range, rm_pos, dmg, creator, dmg_creator)
  if rm_pos then
    minetest.remove_node(pos)
  end

  PyuTestCore.dorange(pos, range, function(p)
      if minetest.get_node(p).name == "pyutest_core:tnt" then
	minetest.after(0.8, function()
	    minetest.remove_node(p)
	    PyuTestCore.create_explosion(p, range, rm_pos, dmg, creator, dmg_creator)
	end)
      else
	minetest.dig_node(p)
      end
  end)

  for _, v in pairs(minetest.get_objects_inside_radius(pos, range)) do
    if creator ~= nil then
      if v ~= creator then
        v:punch(creator, nil, {
	    damage_groups = {fleshy = dmg}
        }, nil)
      end

      if dmg_creator and v == creator then
        v:punch(creator, nil, {
	    damage_groups = {fleshy = dmg}
        }, nil)
      end
    end
  end

  local r = range
  local minpos = {x = pos.x - r, y = pos.y - r, z = pos.z - r}
  local maxpos = {x = pos.x + r, y = pos.y + r, z = pos.z + r}

  minetest.add_particlespawner({
      amount = range * 3,
      time = 0.1,
      minexptime = 0.4,
      maxexptime = 1.4,
      minsize = 32,
      maxsize = 64,

      collisiondetection = false,
      texture = "pyutest-blast.png",

      minpos = minpos,
      maxpos = maxpos,
  })

  minetest.sound_play("block_break", {
      pos = pos,
      gain = 2.5
  })
end

PyuTestCore.tool_caps = function(options)
  local default_uses = 100
  local groupcaps = {}

  for k, v in pairs(options.groupcaps or {}) do
    groupcaps[k] = {
      maxlevel = v.maxlevel or options.maxlevel,
      times = v.times or {
	[PyuTestCore.BLOCK_FAST] = options.time or 3,
	[PyuTestCore.BLOCK_NORMAL] = options.time or 3,
	[PyuTestCore.BLOCK_SLOW] = options.time or 3
      },
      uses = v.uses or options.uses or default_uses
    }
  end

  return {
    groupcaps = groupcaps,
    punch_attack_uses = options.attack_uses,
    damage_groups = options.damage_groups or {fleshy=3},
    full_punch_interval = options.full_punch_interval
  }
end
