
function aom_gates.switch_gate(pos, dir, to_node)
    local node = minetest.get_node_or_nil(pos)
    if not node then return end
    if minetest.get_item_group(node.name, "aom_gates") == 0 then return end
    local ndef = minetest.registered_nodes[node.name]
    if ndef._gate_alt then
        if to_node == nil then
            to_node = ndef._gate_alt
        end
        --- stop if reaching opposite node
        if ndef._gate_alt ~= to_node then return end
        node.name = ndef._gate_alt
        minetest.swap_node(pos, node)
        local time = (aom_gates.has_aom_settings and aom_settings.get_setting(nil, "gameplay_gate_move_time", 0.2)) or 0.2
        minetest.after(time, aom_gates.switch_gate, pos + dir, dir, to_node)
    end
    -- aom_gates.switch_gate(pos + dir, dir)
end

function aom_gates.on_destruct_buildable_to_drop_fix(pos)
    local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
    if ndef._drop then
        minetest.add_item(pos, ItemStack(ndef._drop))
    end
end

local empty_func = function(...) end

function aom_gates.get_defaults_gate(host)
    local def = {}
    def._gate_width = host._gate_width or (2/16)
    local nodebox = aom_gates.get_collisionbox(def._gate_width, 8/16)
    def.drawtype = host.drawtype or "nodebox"
    if def.drawtype == "nodebox" then
        def.node_box = nodebox
        def.collision_box = nodebox
        def.selection_box = nodebox
    end

    host.groups = table.copy(host.groups)
    host.groups.aom_gates = 1

    def.paramtype = "light"
    def.sunlight_propagates = true
    def.drop = host._original_name
    def.connects_to = { "group:full_solid", "group:aom_gates", "group:aom_gates_controller" }
    def._gate_alt = host._original_name.."_open"

    for k, v in pairs(def) do
        if host[k] == nil then
            host[k] = v
        end
    end
    return host
end

function aom_gates.get_defaults_open(host)
    local def = {}
    def._gate_width = host._gate_width or (2/16)
    local nullbox = {
        type = "fixed",
        fixed = { { 0,0,0,0,0,0 } },
    }
    local nodebox = aom_gates.get_collisionbox(def._gate_width, 8/16)
    host.drawtype = "nodebox"
    host.node_box = nullbox
    def.selection_box = def.selection_box or nodebox

    def.walkable = false
    def.paramtype = "light"
    def.sunlight_propagates = true
    def.pointable = not (host._gate_open_pointable == false)

    def.buildable_to = true
    def.drop = ""
    def._drop = host._original_name
    def.on_destruct = aom_gates.on_destruct_buildable_to_drop_fix
    def.on_rightclick = empty_func

    host.groups = table.copy(host.groups)
    host.groups.aom_gates_open = 1
    host.groups.aom_gates = 1
    host.groups.not_in_creative_inventory = 1

    def.connects_to = { "group:full_solid", "group:aom_gates" }
    def._gate_alt = host._original_name

    for k, v in pairs(def) do
        if host[k] == nil then
            host[k] = v
        end
    end
    return host
end

function aom_gates.register_gate(name, _def)
    local def
    def = table.copy(_def)
    def._original_name = name
    def.name = name
    def = aom_gates.get_defaults_gate(def)
    minetest.register_node(def.name, def)

    def = table.copy(_def)
    def._original_name = name
    def.name = name.."_open"
    def = aom_gates.get_defaults_open(def)
    minetest.register_node(def.name, def)
end
