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



function pmb_doors.open_door(pos, node, clicker, itemstack, pointed_thing)
    local def = minetest.registered_nodes[node.name]
    node.name = def and def._pmb_doors_alt_state or node.name
    minetest.set_node(pos, node)

    if def and def._pmb_door_sounds then
        local sounddef = (def._pmb_door_sounds)
        sounddef.pos = pos
        minetest.sound_play(sounddef.name, sounddef)
    end
end
function pmb_doors._on_wire_input(pos, user, source)
    local node = minetest.get_node_or_nil(pos)
    if not node then return end
    pmb_doors.open_door(pos, node)
end
function pmb_doors.on_update(pos, cause, user)
    if cause ~= "dig" then return end
    local node = minetest.get_node(pos)
    if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, -1, 0)).name, "full_solid") == 0 then
        minetest.dig_node(pos)
    end
end
function pmb_doors.on_place(itemstack, placer, pointed_thing)
    local name = itemstack:get_name()
    local retstack = minetest.rotate_and_place(ItemStack(itemstack), placer, pointed_thing, nil, {force_floor = true})
    if (not retstack) or retstack:get_count() == itemstack:get_count() then return itemstack end

    local abovenode = minetest.get_node(pointed_thing.above)
    local belownode = minetest.get_node(pointed_thing.under)
    local p
    local node
    if name == belownode.name then
        p = pointed_thing.under
        node = belownode
    elseif name == abovenode.name then
        p = pointed_thing.above
        node = abovenode
    else
        return retstack
    end
    if (not (minetest.registered_nodes[minetest.get_node(vector.offset(p, 0, 1, 0)).name] or {}).buildable_to)
    or (not (minetest.registered_nodes[minetest.get_node(vector.offset(p, 0, 2, 0)).name] or {}).buildable_to) then
        minetest.set_node(p, {name="air"})
        return itemstack
    end
    p = vector.offset(p, 0, 1, 0)
    local p2 = vector.offset(p, 0, 1, 0)
    node.name = "pmb_doors:blocking_node"
    minetest.set_node(p, node)
    minetest.set_node(p2, node)
    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 = "pmb_door_opening_wood",
    gain = 0.8,
    max_hear_distance = 20,
    pitch = (math.random()*0.1) + 1
}
local wood_door_sound_close = {
    name = "pmb_door_closing_wood",
    gain = 0.8,
    max_hear_distance = 30,
    pitch = (math.random()*0.1) + 1
}
minetest.register_node('pmb_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)
        if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, -1, 0)).name, "door") == 0
        and minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, -2, 0)).name, "door") == 0 then
            minetest.set_node(pos, {name="air"})
            return true
        end
    end,
})

function pmb_doors.register_standard_door(name, options)
    if options == nil then options = {} end
    local node_name = options.node_name or string.lower(name)
    minetest.register_node('pmb_doors:' .. node_name .. '_door', {
        description = S(name.." Door"),
        groups = options.groups or { oddly_breakable_by_hand = 1, choppy = 1, solid = 1, furniture = 1,
            wood = 1, ["item_"..name.."_plank"] = 1, flammable = 1, no_paint = 1, wire = 1, door = 1},
        drawtype = "mesh",
        paramtype = "light",
        sunlight_propagates = true,
        paramtype2 = "facedir",
        drop = options.drop or ('pmb_doors:' .. node_name .. '_door'),
        selection_box = {
            type = "fixed",
            fixed = door_box,
        },
        collision_box = {
            type = "fixed",
            fixed = door_box,
        },
        mesh = "pmb_doors_closed.b3d",
        use_texture_alpha = "clip",
        tiles = {
            {
                name = "pmb_doors_" .. node_name .. ".png",
                backface_culling = not (options.no_backface_culling ~= nil and false),
            }
        },
        sounds = options.sounds or pmb_sounds and pmb_sounds.default_wood(),
        on_place = options.on_place or pmb_doors.on_place,
        on_rightclick = options.on_rightclick or pmb_doors.open_door,
        _on_wire_input = pmb_doors._on_wire_input,
        _pmb_doors_alt_state = 'pmb_doors:' .. node_name .. '_door_open',
        _pmb_door_sounds = options._pmb_door_sounds and options._pmb_door_sounds.close or wood_door_sound_close,
        _on_node_update = options._on_node_update or pmb_doors.on_update,
    })
    minetest.register_node('pmb_doors:' .. node_name .. '_door_open', {
        description = S(name.." Door"),
        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 ('pmb_doors:' .. node_name .. '_door'),
        selection_box = {
            type = "fixed",
            fixed = door_box_open,
        },
        collision_box = {
            type = "fixed",
            fixed = door_box_open,
        },
        mesh = "pmb_doors_open.b3d",
        use_texture_alpha = "clip",
        tiles = {
            {
                name = "pmb_doors_" .. node_name .. ".png",
                backface_culling = not (options.no_backface_culling ~= nil and false),
            }
        },
        sounds = options.sounds or pmb_sounds and pmb_sounds.default_wood(),
        on_place = options.on_place or pmb_doors.on_place,
        on_rightclick = options.on_rightclick or pmb_doors.open_door,
        _on_wire_input = pmb_doors._on_wire_input,
        _pmb_doors_alt_state = 'pmb_doors:' .. node_name .. '_door',
        _pmb_door_sounds = options._pmb_door_sounds and options._pmb_door_sounds.open or wood_door_sound_open,
        _on_node_update = options._on_node_update or pmb_doors.on_update,
    })
    local c = 'pmb_wood:' .. node_name .. '_planks'
    minetest.register_craft({
        output = 'pmb_doors:' .. node_name .. '_door',
        recipe = {
            {c, c},
            {c, c},
            {c, c},
        },
    })
end


pmb_doors.register_standard_door("Oak")
pmb_doors.register_standard_door("Ash")
pmb_doors.register_standard_door("Spruce")


