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

local function do_effects(pos)
    for i=0, 4 do
        minetest.add_particle({
            pos = vector.offset(pos, math.random()-0.5, math.random(), math.random()-0.5),
            velocity = vector.new(0,math.random(),0),
            expirationtime = math.random() * 4,
            size = math.random() * 8,
            collisiondetection = false,
            vertical = false,
            texture = "pmb_cooking_particle_finished_cooking.png^[colorize:#44444400:100",
            glow = 14,
        })
        minetest.add_particle({
            pos = vector.offset(pos, math.random()-0.5, math.random(), math.random()-0.5),
            velocity = vector.new(0,math.random()*3,0),
            expirationtime = math.random() * 1,
            size = math.random()+0.1,
            collisiondetection = false,
            vertical = false,
            texture = "pmb_cooking_particle_finished_cooking.png^[colorize:#ffee8855:200",
            glow = 14,
        })
    end
end

local function update_lights(pos, turn_off)
    local node = minetest.get_node(pos)
    local dir = minetest.facedir_to_dir(node.param2)
    dir = vector.multiply(dir, -1)
    local dirpos = vector.add(dir, pos)
    local nt = minetest.get_node_timer(dirpos)
    if not turn_off then
        if not nt:is_started() then
            local dirnode = minetest.get_node(dirpos)
            if dirnode.name == "air" then
                minetest.set_node(dirpos, {name="pmb_util:light_node_14"})
                nt:start(10)
            end
        else
            local dirnode = minetest.get_node(dirpos)
            if dirnode.name == "pmb_util:light_node_14" then
                nt:start(10)
            end
        end
    else
        local dirnode = minetest.get_node(dirpos)
        if dirnode.name == "pmb_util:light_node_14" then
            minetest.set_node(dirpos, {name="air"})
            nt:stop()
        end
    end
end

local function nodedef(pos)
    return minetest.registered_nodes[minetest.get_node(pos).name]
end

local function valid_location_to_place_two_high(pos)
    local ab_def = nodedef(pos)
    if ab_def and ab_def.buildable_to then
        local above_pos = vector.offset(pos, 0, 1, 0)
        local above_def = nodedef(above_pos)
        if above_def.buildable_to then
            return pos
        end
    end
end

minetest.register_node('pmb_cooking:oven', {
    description = pmb_util.desc(S("Oven"), "grey"),
    _tt_long_desc = S(""),
    groups = { item_oven = 1, solid = 1, suffocates = 1, oddly_breakable_by_hand = 2, cracky = 2, },
    use_texture_alpha = "opaque",
    tiles = {
        -- top
        "pmb_cooking_oven_top.png",
        -- bottom
        "pmb_cooking_oven_top.png",
        -- right / east
        "pmb_cooking_oven_side.png",
        -- left / west
        "pmb_cooking_oven_side.png",
        -- behind / north (facedir)
        "pmb_cooking_oven_side.png",
        -- front / south (pointing at player)
        "pmb_cooking_oven_front.png",
    },
    sounds = (pmb_sounds and pmb_sounds.default_stone()) or {},
    on_rightclick = pmb_cooking.activate_burner,
    paramtype2 = "facedir",
    -- on_timer = do_effects,
    on_place = function(itemstack, placer, pointed_thing)
        local place_pos = valid_location_to_place_two_high(pointed_thing.under)
        if not place_pos then place_pos = valid_location_to_place_two_high(pointed_thing.above) end
        if not place_pos then return itemstack end

        local above_pos = vector.offset(place_pos, 0, 1, 0)
        minetest.dig_node(place_pos)
        minetest.dig_node(above_pos)
        local facedir = minetest.dir_to_facedir(vector.direction(placer:get_pos(), place_pos))
        minetest.set_node(place_pos, {name="pmb_cooking:oven", param2 = facedir})
        minetest.set_node(above_pos, {name="pmb_cooking:oven_top", param2 = facedir})
        return pmb_util.take_if_not_creative_player(itemstack, placer)
    end,
    after_place_node = function(pos, placer, itemstack, pointed_thing)
        return pmb_util.rotate_and_place_from(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = false})
    end,
    _on_input_item = function(pos, itemstack)
        local ret =  pmb_cooking.activate_burner(pos, nil, nil, itemstack, nil)
        return ret
    end,
    _on_node_update = function(pos, cause, user, count, payload)
        -- set air if no oven part above
        local above = vector.offset(pos, 0, 1, 0)
        local node = minetest.get_node(above)
        if node.name ~= "pmb_cooking:oven" and node.name ~= "pmb_cooking:oven_top" then
            if minetest.node_dig(pos, minetest.get_node(pos), user) then
                return true
            else
                minetest.dig_node(pos)
            end
        end
    end,
})


minetest.register_node('pmb_cooking:oven_active', {
    description = 'A pit for fires. Wait how are you carrying around a burning fireplace in your pocket?',
    groups = { item_oven = 1, solid = 1, suffocates = 1, oddly_breakable_by_hand = 2, cooker_roast = 1, cooker_sound = 1, cooker_oven = 1, cracky = 2, },
    use_texture_alpha = "opaque",
    tiles = {
        -- top
        "pmb_cooking_oven_top.png",
        -- bottom
        "pmb_cooking_oven_top.png",
        -- right / east
        "pmb_cooking_oven_side.png",
        -- left / west
        "pmb_cooking_oven_side.png",
        -- behind / north (facedir)
        "pmb_cooking_oven_side.png",
        -- front / south (pointing at player)
        {
            name = "pmb_cooking_oven_front_on.png", -- this is the flame texture
            animation = {
                type = "vertical_frames",
                aspect_w = 16,
                aspect_h = 16,
                length = 1,
            },
        },
    },
    drop = "pmb_cooking:oven",
    -- light_source = 12,
    sounds = (pmb_sounds and pmb_sounds.default_stone()) or {},
    _fuel_use = 1,
    _custom_sounds = {
        passive = {
            name = "pmb_furnace_fire_cc0",
            max_hear_distance = 5,
            gain = 0.7,
        },
    },
    paramtype2 = "facedir",
    on_timer = function(pos, elapsed)
        do_effects(pos)
        pmb_cooking.do_node_sound(pos, "passive")
        local ret = pmb_cooking.burner_on_timer(pos, elapsed)

        update_lights(pos, not ret)

        return ret or true
    end,
    on_construct = function(pos)
        minetest.get_node_timer(pos):start(1)
        update_lights(pos)
    end,
    after_place_node = function(pos, placer, itemstack, pointed_thing)
        pmb_cooking.do_node_sound(pos, "passive")
        return pmb_util.rotate_and_place_from(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = false})
    end,
    on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
        local ret = pmb_cooking.activate_burner(pos, node, clicker, itemstack, pointed_thing)
        node = minetest.get_node(pos)
        return ret
    end,
    on_destruct = function(pos)
        pmb_cooking.stop_node_sound(pos)

        local node = minetest.get_node(pos)
        local dir = minetest.facedir_to_dir(node.param2)
        dir = vector.multiply(dir, -1)
        local dirpos = vector.add(dir, pos)
        local nt = minetest.get_node_timer(dirpos)
        local dirnode = minetest.get_node(dirpos)
        if dirnode.name == "pmb_util:light_node_14" then
            minetest.set_node(dirpos, {name="air"})
        end
    end,
    _on_input_item = function(pos, itemstack)
        return pmb_cooking.activate_burner(pos, nil, nil, itemstack, nil)
    end,
    _on_node_update = function(pos, cause, user, count, payload)
        -- set air if no oven part above
        local above = vector.offset(pos, 0, 1, 0)
        local node = minetest.get_node(above)
        if node.name ~= "pmb_cooking:oven" and node.name ~= "pmb_cooking:oven_top" then
            minetest.set_node(pos, {name="air"})
            return true
        end
    end,
})


local pot_size = {
    type = "fixed",
    fixed = {-4/16, -8/16, -4/16, 4/16, -2/16, 4/16},
}

minetest.register_node('pmb_cooking:oven_top', {
    description = pmb_util.desc(S("Cooking Pot"), "grey"),
    _tt_long_desc = S("Cooks food when placed above a lit fire.")..
        S("Cooks ores when placed above a lit furnace."),
    groups = { item_cooking_pot = 1, solid = 1, oddly_breakable_by_hand = 2, cracky = 1, iron = 1, cooker = 1, cooker_boil = 1 },
    drawtype = "mesh",
    use_texture_alpha = "opaque",
    paramtype = "light",
    paramtype2 = "facedir",
    tiles = {"pmb_cooking_oven_mesh.png"},
    mesh = "pmb_cooking_oven_top.b3d",
    drop = "",
    sounds = (pmb_sounds and pmb_sounds.default_stone()) or {},
    -- collision_box = pot_size,
    -- selection_box = pot_size,
    _on_node_update = function(pos, cause, user, count)
        local timer = minetest.get_node_timer(pos)
        if not timer:is_started() then
            timer:start(1.0)
        end

        -- drop everything and set air if no oven below
        local below = vector.offset(pos, 0, -1, 0)
        local node = minetest.get_node(below)
        if node.name ~= "pmb_cooking:oven" and node.name ~= "pmb_cooking:oven_active" then
            local meta = minetest.get_meta(pos)
            local inv = meta:get_inventory()
            pmb_inventory.drop_inventory_at_pos(inv, pos)
            minetest.set_node(pos, {name="air"})
            return true
        end
    end,
    _on_cook = function(pos, node, cooked_item)
        local meta = minetest.get_meta(pos)
        local itemstack = meta:get_inventory():get_stack("input", 1)
        if itemstack:get_count() == 0 then
                minetest.sound_play("pmb_cooking_finished_all", {
                gain = 0.5,
                pos = pos,
                max_hear_distance = 5,
                })
        end
        minetest.sound_play("pmb_cooking_finished_boil", {
            gain = 0.9,
            pos = pos,
            max_hear_distance = 10,
        })
        for x=0, 3 do
            minetest.add_particle({
                pos = vector.offset(pos, math.random()-0.5, math.random()-0.5, math.random()-0.5),
                velocity = vector.new(0,math.random(),0),
                expirationtime = math.random() * 4,
                size = math.random() * 4,
                collisiondetection = false,
                vertical = false,
                texture = "pmb_cooking_particle_finished_cooking.png^[colorize:#ffffff55:200",
                glow = 14,
            })
        end
    end,
    _cook_group = function(pos)
        local below = minetest.get_node(vector.offset(pos, 0, -1, 0))
        if minetest.get_item_group(below.name, "cooker_oven") ~= 0 then
            return "cooker_boil"
        else
            return nil
        end
    end,
    on_timer = pmb_cooking.cooker_node_timer,
    on_construct = pmb_cooking.cooker_on_construct,
    on_punch = function(pos, node, clicker, itemstack, pointed_thing)
        pmb_cooking.cooker_take_item(pos, node, clicker, itemstack, pointed_thing)
    end,
    on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
        return pmb_cooking.cooker_give_item(pos, node, clicker, itemstack, pointed_thing)
    end,
    after_place_node = function(pos, placer, itemstack, pointed_thing)
        return pmb_util.rotate_and_place_from(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = false})
    end,
    _on_input_item = function(pos, itemstack)
        return pmb_cooking.cooker_offer_item(pos, itemstack)
    end,
})




pmb_tcraft.register_craft({
    output = "pmb_cooking:oven",
    items = {
        ["pmb_stone:cobble"] = 16,
    }
})
