
local w = 3/16
local h = 2/16

local node_box_button = {
    type = "fixed",
    fixed = {-w,-0.5, -h, w, -0.5+w, h},
}
local node_box_button_pushed = {
    type = "fixed",
    fixed = {-w,-0.5, -h, w, -0.5+(1/16), h},
}

aom_wire.button = {}


function aom_wire.button.do_activation_sound(pos, event_type)
    local node = minetest.get_node(pos)
    local ndef = minetest.registered_nodes[node.name]
    local spec
    if not ndef._aom_wire_activation_sound then
        spec = {name = "pmb_wrench_plip", gain = 0.1, pitch = 0.5}
    else
        spec = ndef._aom_wire_activation_sound[event_type]
    end
    if not spec then return end
    minetest.sound_play(spec.name, {
        gain = spec.gain or 0.1,
        pitch = spec.pitch or 0.5,
        pos = pos,
        start_time = spec.start_time,
        max_hear_distance = spec.max_hear_distance or 10,
    })
end

function aom_wire.button.apply_defaults(def)
    if def._aom_wire_button_no_defaults then return end
    def.paramtype = def.paramtype or "light"
    def.groups = table.copy(def.groups)
    def.groups.wire_output = 1
    def.sunlight_propagates = ((def.sunlight_propagates ~= nil) and def.sunlight_propagates) or true
    def.paramtype2 = def.paramtype2 or "wallmounted"
    def.drawtype = def.drawtype or "nodebox"
    def.node_box = def.node_box or node_box_button
    def.on_rightclick = aom_wire.button.on_rightclick
end

function aom_wire.button.apply_defaults_pushed(def)
    if def._aom_wire_button_no_defaults then return end
    def.paramtype = def.paramtype or "light"
    def.drop = def._original_name
    def.groups = table.copy(def.groups)
    def.groups.not_in_creative_inventory = 1
    def.sunlight_propagates = ((def.sunlight_propagates ~= nil) and def.sunlight_propagates) or true
    def.paramtype2 = def.paramtype2 or "wallmounted"
    def.drawtype = def.drawtype or "nodebox"
    def.node_box = def.node_box or node_box_button_pushed
    def.on_timer = aom_wire.button.on_timer_unpush
end

function aom_wire.button.on_timer_unpush(pos, elapsed)
    aom_wire.button.do_activation_sound(pos, "unpress")
    local node = minetest.get_node(pos)
    local ndef = minetest.registered_nodes[node.name]
    node.name = (ndef._original_name or node.name)
    minetest.swap_node(pos, node)
end

function aom_wire.button.on_rightclick(pos, node, clicker, itemstack, pointed_thing)
    if minetest.is_player(clicker) then
        aom_wire.button.do_activation_sound(pos, "press")
    end
    local mydef = minetest.registered_nodes[node.name]
    if mydef._on_wire_activated then
        mydef._on_wire_activated(pos, clicker)
    end
    -- go through each output
    local outputs = aom_wire.get_outputs(pos)
    for i, target in ipairs(outputs or {}) do repeat
        local n = minetest.get_node_or_nil(target)
        aom_wire.debug("dump", dump(target))
        if not n then break end
        local ndef = minetest.registered_nodes[n.name]
        if ndef._on_wire_input ~= nil then
            ndef._on_wire_input(target, clicker, pos)
        end
    until true end
    -- set to pushed node
    node.name = (mydef._original_name or node.name).."_pushed"
    minetest.swap_node(pos, node)
    minetest.get_node_timer(pos):start(mydef._aom_wire_unpress_time or 1)
end

function aom_wire.register_button(name, _def)
    local def = table.copy(_def)
    def._original_name = name
    def.name = name
    aom_wire.button.apply_defaults(def)

    minetest.register_node(def.name, def)


    def = table.copy(_def)
    def._original_name = name
    def.name = name.."_pushed"
    def.drop = def.drop or name
    aom_wire.button.apply_defaults_pushed(def)

    minetest.register_node(def.name, def)
end
