local mod_name = core.get_current_modname()
local mod_path = core.get_modpath(mod_name)
local S = core.get_translator(mod_name)



function aom_doors.open_door(pos, node, clicker, itemstack, pointed_thing)
    local def = core.registered_nodes[node.name]
    node.name = def and def._aom_doors_alt_state or node.name
    core.set_node(pos, node)

    if def and def._aom_door_sounds then
        local sounddef = (def._aom_door_sounds)
        sounddef.pos = pos
        core.sound_play(sounddef.name, sounddef)
    end
end
function aom_doors._on_wire_input(pos, user, source)
    local node = core.get_node_or_nil(pos)
    if not node then return end
    aom_doors.open_door(pos, node)
end
function aom_doors.on_update(pos, cause, user)
    if not aom_doors.check_barriers(pos) then
        return true, true
    end
    if core.get_item_group(core.get_node(vector.offset(pos, 0, -1, 0)).name, "full_solid") == 0 then
        core.dig_node(pos)
    end
end

function aom_doors.check_barriers(pos)
    local node = {name = "aom_doors:blocking_node"}
    for i = 1, 2 do
        local p = vector.offset(pos, 0, i, 0)
        local n = core.get_node_or_nil(p)
        if n and n.name ~= node.name then
            if core.registered_nodes[n.name].buildable_to then
                core.set_node(p, node)
            else
                core.dig_node(pos)
                return false
            end
        end
    end
    return true
end

function aom_doors.on_place(itemstack, placer, pointed_thing)
    local p = aom_util.get_place_position_from_pointed_thing(pointed_thing)
    if not p then return end
    if core.get_item_group(core.get_node(vector.offset(p, 0, -1, 0)).name, "full_solid") == 0 then
        return
    end
    if (not (core.registered_nodes[core.get_node(vector.offset(p, 0, 1, 0)).name] or {}).buildable_to)
    or (not (core.registered_nodes[core.get_node(vector.offset(p, 0, 2, 0)).name] or {}).buildable_to) then
        return
    end
    local retstack = core.rotate_and_place(ItemStack(itemstack), placer, pointed_thing, nil, {force_floor = true})
    if (not retstack) then return itemstack end
    aom_doors.check_barriers(p)
    return retstack
end


local door_box = {
    -8/16,   -8/16,  -8/16,
     8/16,   (24+16)/16,  -6/16
}
local door_box_open = {
    -8/16,   -8/16,  -8/16,
    -6/16,   (24+16)/16,   8/16
}
local wood_door_sound_open = {
    name = "aom_door_opening_wood",
    gain = 0.8,
    max_hear_distance = 20,
    pitch = (math.random()*0.1) + 1
}
local wood_door_sound_close = {
    name = "aom_door_closing_wood",
    gain = 0.8,
    max_hear_distance = 30,
    pitch = (math.random()*0.1) + 1
}
core.register_node('aom_doors:blocking_node', {
    description = S("Door Blocking Node"),
    groups = { not_in_creative_inventory = 1, no_paint = 1, },
    drawtype = "airlike",
    paramtype = "light",
    sunlight_propagates = true,
    tiles = {"blank.png"},
    pointable = false,
    buildable_to = false,
    walkable = false,
    _on_node_update = function(pos, cause)
        local has_door = false
        for i = 1, 2 do
            local p = vector.offset(pos, 0, -i, 0)
            local n = core.get_node_or_nil(p)
            if n and core.get_item_group(n.name, "door") > 0 then
                has_door = aom_doors.check_barriers(p)
            end
        end
        if not has_door then
            core.set_node(pos, {name="air"})
            return true
        end
    end,
})

function aom_doors.register_standard_door(sname, name, options)
    if options == nil then options = {} end
    local node_name = options.node_name or string.lower(name)
    core.register_node('aom_doors:' .. node_name .. '_door', {
        -- TL: @1 is a variant of wood ("Oak")
        description = S("@1 Door", sname),
        groups = options.groups or { oddly_breakable_by_hand = 1, choppy = 1, solid = 1, furniture = 1,
            wood = 1, flammable = 1, no_paint = 1, wire = 1, door = 1},
        drawtype = "mesh",
        paramtype = "light",
        sunlight_propagates = true,
        paramtype2 = "facedir",
        drop = options.drop or ('aom_doors:' .. node_name .. '_door'),
        selection_box = {
            type = "fixed",
            fixed = door_box,
        },
        collision_box = {
            type = "fixed",
            fixed = door_box,
        },
        mesh = "aom_doors_closed.b3d",
        use_texture_alpha = "clip",
        tiles = {
            {
                name = "aom_doors_" .. node_name .. ".png",
                backface_culling = not (options.no_backface_culling ~= nil and false),
            }
        },
        sounds = options.sounds or aom_sounds and aom_sounds.default_wood(),
        on_place = options.on_place or aom_doors.on_place,
        on_rightclick = options.on_rightclick or aom_doors.open_door,
        _on_wire_input = aom_doors._on_wire_input,
        _aom_doors_alt_state = 'aom_doors:' .. node_name .. '_door_open',
        _aom_door_sounds = options._aom_door_sounds and options._aom_door_sounds.close or wood_door_sound_close,
        _on_node_update = options._on_node_update or aom_doors.on_update,
    })
    core.register_node('aom_doors:' .. node_name .. '_door_open', {
        -- TL: @1 is a variant of wood ("Oak")
        description = S("@1 Door", sname),
        groups = options.groups or { oddly_breakable_by_hand = 1, choppy = 1, solid = 1,
        wood = 1, ["item_"..name.."_plank"] = 1, flammable = 1, wire = 1, player_place_only = 1, not_in_creative_inventory = 1, door = 1},
        drawtype = "mesh",
        paramtype = "light",
        sunlight_propagates = true,
        paramtype2 = "facedir",
        drop = options.drop or ('aom_doors:' .. node_name .. '_door'),
        selection_box = {
            type = "fixed",
            fixed = door_box_open,
        },
        collision_box = {
            type = "fixed",
            fixed = door_box_open,
        },
        mesh = "aom_doors_open.b3d",
        use_texture_alpha = "clip",
        tiles = {
            {
                name = "aom_doors_" .. node_name .. ".png",
                backface_culling = not (options.no_backface_culling ~= nil and false),
            }
        },
        sounds = options.sounds or aom_sounds and aom_sounds.default_wood(),
        on_place = options.on_place or aom_doors.on_place,
        on_rightclick = options.on_rightclick or aom_doors.open_door,
        _on_wire_input = aom_doors._on_wire_input,
        _aom_doors_alt_state = 'aom_doors:' .. node_name .. '_door',
        _aom_door_sounds = options._aom_door_sounds and options._aom_door_sounds.open or wood_door_sound_open,
        _on_node_update = options._on_node_update or aom_doors.on_update,
    })
    local c = 'aom_wood:' .. node_name .. '_planks'
    core.register_craft({
        output = 'aom_doors:' .. node_name .. '_door',
        recipe = {
            {c, c},
            {c, c},
            {c, c},
        },
    })
end


aom_doors.register_standard_door(S("Oak"), "Oak")
aom_doors.register_standard_door(S("Ash"), "Ash")
aom_doors.register_standard_door(S("Spruce"), "Spruce")


