local modpath = minetest.get_modpath("pyutest_electricity")

PyuTest.ELECTRICITY_TICK = 1 / 1000

PyuTest.electricity_activate = function(pos, node, sender_pos)
  local def = minetest.registered_nodes[node.name]

  if def.__on_electricity_activated then
    def.__on_electricity_activated(pos, node, sender_pos)
  end
end

PyuTest.make_button = function(id, desc, groups, tiles)
  PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, {
    electric = 1
  }), tiles, {
    is_ground_content = false,
    on_rightclick = function(pos, node, clicker)
      minetest.sound_play("button", {
        pos = pos,
        gain = 1
      })

      for _, v in pairs(PyuTest.get_neighbours(pos)) do
        local n = minetest.get_node(v)
        minetest.after(PyuTest.ELECTRICITY_TICK, function()
          PyuTest.electricity_activate(v, n, pos)
        end)
      end
    end
  })
end

PyuTest.make_wire = function(id, desc, groups, color, opts, texture, delay)
  local del = PyuTest.ELECTRICITY_TICK * delay

  PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, {
    electric = 1
  }), {
    texture or "pyutest-wire.png",
    texture or "pyutest-wire.png",
    texture or "pyutest-wire.png",
    texture or "pyutest-wire.png"
  }, PyuTest.util.tableconcat(opts or {}, {
    drawtype = "raillike",
    color = color,
    paramtype = "light",
    sunlight_propagates = true,
    walkable = false,
    inventory_image = texture or "pyutest-wire.png",

    __on_electricity_activated = function(pos, node, sender_pos)
      for _, v in pairs(PyuTest.get_neighbours(pos)) do
        local n = minetest.get_node(v)

        -- To prevent infinite loops
        if v == sender_pos then
          goto continue
        end

        minetest.after(del, function()
          PyuTest.electricity_activate(v, n, pos)
        end)

        ::continue::
      end
    end
  }))
end

PyuTest.make_electricity_device = function(id, desc, groups, tiles, craftitem, opts, afn)
  PyuTest.make_node(id, desc, PyuTest.util.tableconcat(groups, {
    electric = 1
  }), tiles, PyuTest.util.tableconcat(opts or {}, {
    __on_electricity_activated = afn,
  }))

  -- Dont create a recipe if it is nil
  if craftitem ~= nil then
    minetest.register_craft({
      output = id,
      recipe = {
        { "pyutest_blocks:stone_block", "pyutest_blocks:stone_block", "pyutest_blocks:stone_block" },
        { "pyutest_blocks:stone_block", craftitem,   "pyutest_blocks:stone_block" },
        { "pyutest_blocks:stone_block", "pyutest_blocks:stone_block", "pyutest_blocks:stone_block" }
      },
    })
  end
end

PyuTest.make_button("pyutest_electricity:button", "Button", {
  cracky = PyuTest.BLOCK_NORMAL,
}, { "pyutest-button.png" })

PyuTest.make_wire("pyutest_electricity:copper_wire", "Copper Wire", {
  snappy = PyuTest.BLOCK_NORMAL
}, "darkgoldenrod", nil, nil, 1)


minetest.register_craft({
  output = "pyutest_electricity:copper_wire 4",
  recipe = {
    "pyutest_ores:copper_ingot"
  },
  type = "shapeless"
})

minetest.register_craft({
  output = "pyutest_electricity:button",
  recipe = {
    { "pyutest_blocks:stone_block", "pyutest_blocks:stone_block",  "pyutest_blocks:stone_block" },
    { "pyutest_blocks:stone_block", "pyutest_ores:copper_ingot", "pyutest_blocks:stone_block" },
    { "pyutest_blocks:stone_block", "pyutest_blocks:stone_block",  "pyutest_blocks:stone_block" }
  },
})

dofile(modpath.."/devices.lua")
dofile(modpath.."/delayer.lua")
dofile(modpath.."/components.lua")
