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

local can_tree_fell = minetest.settings:get_bool("pmb_tree_fell") or false

local function test_for_break_me(pos, cause, user, count, payload)
  -- if not can_tree_fell then return false end
  if cause == "treefeller" and payload and payload.start_pos then
    local cpos = vector.new(pos.x,payload.start_pos.y,pos.z)
    if vector.distance(cpos, payload.start_pos) < 4.4 then
      local node = minetest.get_node(pos)
      local drops = minetest.get_node_drops(node, payload.tool_name)
      minetest.set_node(pos, {name="air"})
      for i, stack in pairs(drops) do
        local p = vector.offset(pos,
          (math.random()*2-1) * 0.5,
          (math.random()*2-1) * 0.5,
          (math.random()*2-1) * 0.5
        )
        minetest.add_item(p, stack)
      end
      return payload
    end
  elseif cause == "treefeller_start" and minetest.is_player(user) then
    local wieldstack = user:get_wielded_item()
    local wieldname = wieldstack:get_name()
    if minetest.get_item_group(wieldname, "treefeller") > 0 then
      pmb_node_update.update_node_propagate(pos, "treefeller", user, 30, 0.2, {
        start_pos = pos,
        tool_name = wieldname
      })
      return false
    end
  end
end



pmb_wood = {}

local log_fuel = 10

local planks_per_log = 4
function pmb_wood.register_planks(name, tiles)
  local node_name = string.lower(name)
  minetest.register_node('pmb_wood:' .. node_name .. '_planks', {
    description = pmb_util.desc(S(name.." Planks"), "grey"),
    groups = { full_solid = 1, oddly_breakable_by_hand = 1, choppy = 1, solid = 1, suffocates = 2, wood = 1, ["item_"..name.."_planks"] = 1, planks = 1, flammable = 1, fuel = log_fuel/2 },
    tiles = tiles,
    sounds = pmb_sounds.default_wood(),
  })
  minetest.register_craft({
    output = 'pmb_wood:' .. node_name .. '_planks ' .. planks_per_log,
    recipe = {
      {'pmb_wood:' .. node_name .. '_log'},
    },
  })
end


function pmb_wood.on_place_plank(pos, placer, itemstack, pointed_thing)
  local ct = player_info.get(placer)
  if ct and ct.ctrl.sneak then
    pmb_util.rotate_and_place_against(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = false, vflip = true})
  else
    pmb_util.rotate_and_place_against(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = true,})
  end
end

local plank_box = {
  -8/16,   -8/16, -8/16,
  8/16,   -4/16,  8/16
}
-- local plank_box = {
--   -0.5, -0.5,  4/16,
--   0.5,   0.5,  8/16,
-- }
local plank_per_planks = 2
function pmb_wood.register_plank(name, tiles)
  local node_name = string.lower(name)
  minetest.register_node('pmb_wood:' .. node_name .. '_plank', {
    description = pmb_util.desc(S("Single "..name.." Plank"), "grey"),
    groups = { oddly_breakable_by_hand = 1, choppy = 1, solid = 1, wood = 1, ["item_"..name.."_plank"] = 1, plank = 1, flammable = 1, fuel = log_fuel/4 },
    drawtype = "nodebox",
    paramtype = "light",
    sunlight_propagates = false,
    paramtype2 = "facedir",
    node_box = {
      type = "fixed",
      fixed = plank_box,
    },
    tiles = tiles,
    sounds = pmb_sounds.default_wood(),
    after_place_node = pmb_wood.on_place_plank,
  })
  minetest.register_craft({
    output = 'pmb_wood:' .. node_name .. '_plank ' .. plank_per_planks,
    recipe = {
      {'pmb_wood:' .. node_name .. '_planks'},
    },
  })
end



-- BEAMS
function pmb_wood.on_place_beam(pos, placer, itemstack, pointed_thing)
  local ct = player_info.get(placer)
  if ct and ct.ctrl.sneak then
    pmb_util.rotate_and_place_against(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = false, vflip = true})
  else
    pmb_util.rotate_and_place_against(pos, placer, itemstack, pointed_thing, {offset = 0, copy_same_node = true,})
  end
end

local beam_box = {
  -2/16, -8/16, 0,
   2/16,  8/16, 8/16,
}
local beam_per_post = 1
function pmb_wood.register_beam(name, tiles)
  local node_name = string.lower(name)
  minetest.register_node('pmb_wood:' .. node_name .. '_beam', {
    description = pmb_util.desc(S(name.." Beam"), "grey"),
    groups = { oddly_breakable_by_hand = 1, choppy = 1, solid = 1, wood = 1, ["item_"..name.."_beam"] = 1, beam = 1, flammable = 1, fuel = log_fuel/8 },
    drawtype = "nodebox",
    paramtype = "light",
    paramtype2 = "facedir",
    node_box = {
      type = "fixed",
      fixed = beam_box,
    },
    tiles = tiles,
    sounds = pmb_sounds.default_wood(),
    after_place_node = pmb_wood.on_place_beam,
  })
  minetest.register_craft({
    output = 'pmb_wood:' .. node_name .. '_beam ' .. beam_per_post * 2,
    recipe = {
      {'pmb_wood:' .. node_name .. '_post', 'pmb_wood:' .. node_name .. '_post'},
    },
  })
end


function pmb_wood.register_log(name, tiles)
  local node_name = string.lower(name)
  minetest.register_node('pmb_wood:' .. node_name .. '_log', {
    description = pmb_util.desc(S(name.." Log"), "grey"),
    groups = { full_solid = 1, nature = 1, oddly_breakable_by_hand = 2, choppy = 1, solid = 1, suffocates = 2, wood = 1, ["item_"..name.."_log"] = 1, wood_log = 1, flammable = 1, fuel = log_fuel },
    tiles = tiles,
    sounds = pmb_sounds.default_wood(),
    paramtype2 = "facedir",
    after_place_node = function(pos, placer, itemstack, pointed_thing)
        pmb_util.rotate_and_place_against(pos, placer, itemstack, pointed_thing, {offset = 0})
    end,
    _on_node_update = test_for_break_me,
    after_dig_node = function(pos, oldnode, oldmetadata, digger)
      test_for_break_me(pos, "treefeller_start", digger, 1)
    end,
  })
  pmb_util.register_slab( 'pmb_wood:' .. node_name .. '_log')
  pmb_util.register_post( 'pmb_wood:' .. node_name .. '_log')
end

local function leaf_decay(pos)
  if minetest.get_node_timer(pos):is_started() then return
  else minetest.get_node_timer(pos):stop() end

  pmb_util.did_abm("leaf decay")

  local n = minetest.find_node_near(pos, 3, {"group:wood_log"})
  if n then return false end
  n = minetest.find_node_near(pos, 3, {"group:leaf_decay"})
  if n and not minetest.get_node_timer(n):is_started() then
    minetest.get_node_timer(n):start(math.random()*10 + 2)
  end
  minetest.dig_node(pos)
  return false
end

function pmb_wood.register_leaves(name, tiles, tiles_simple)
  local node_name = string.lower(name)
  minetest.register_node('pmb_wood:' .. node_name .. '_leaves', {
    description = pmb_util.desc(S(name.." Leaves"), "grey"),
    drawtype = "allfaces_optional",
    waving = 1,
    tiles = tiles,
    special_tiles = tiles_simple,
    paramtype = "light",
    groups = { oddly_breakable_by_hand = 1, nature = 1, snappy = 1, solid = 1, suffocates = 0, leaves = 1, leaf_decay = 1, ["item_"..name.."_leaves"] = 1, flammable = 1 },
    is_ground_content = false,
    drop = {
      max_items = 1,
      items = {
        {
            items = {'pmb_trees:' .. node_name .. '_sapling'},
            rarity = 35,
        },
        {
            items = {'pmb_items:stick'},
            rarity = 30,
        },
      },
    },
    sounds = pmb_sounds.default_plant(), -- #TODO add leaf sounds
    _on_node_update = function(pos, cause, user, count, payload)
      local nt = minetest.get_node_timer(pos)
      if nt:is_started() then return false end
      nt:start(math.random()*10 + 2)
      return test_for_break_me(pos, cause, user, count, payload)
    end,
    on_timer = leaf_decay,
})
end

minetest.register_abm({
  nodenames = {"group:leaf_decay"},
  neighbors = {'air'},
  interval = 40.0,
  chance = 200,
  action = function(pos, node, active_object_count, active_object_count_wider)
    leaf_decay(pos)
  end
})

pmb_wood.register_log(   "Oak", {'pmb_wood_oak_log_top.png', 'pmb_wood_oak_log_top.png', 'pmb_wood_oak_log_side.png'})
pmb_wood.register_leaves("Oak", {'pmb_wood_oak_leaves.png'}, {'pmb_wood_oak_leaves_opaque.png'})
pmb_wood.register_planks("Oak", {'pmb_wood_oak_planks.png'})
pmb_wood.register_beam(  "Oak", {'pmb_wood_oak_plank.png'})
pmb_wood.register_plank( "Oak", {'pmb_wood_oak_plank.png'})

pmb_util.register_all_shapes("pmb_wood:oak_planks", {}, {remove_groups={"planks"}})


pmb_wood.register_log(   "Ash", {'pmb_wood_ash_log_top.png', 'pmb_wood_ash_log_top.png', 'pmb_wood_ash_log_side.png'})
pmb_wood.register_leaves("Ash", {'pmb_wood_ash_leaves.png'}, {'pmb_wood_ash_leaves_opaque.png'})
pmb_wood.register_planks("Ash", {'pmb_wood_ash_planks.png'})
pmb_wood.register_plank( "Ash", {'pmb_wood_ash_plank.png'})
pmb_wood.register_beam(  "Ash", {'pmb_wood_ash_plank.png'})

pmb_util.register_all_shapes("pmb_wood:ash_planks", {}, {remove_groups={"planks"}})


pmb_wood.register_log(   "Spruce", {'pmb_wood_spruce_log_top.png', 'pmb_wood_spruce_log_top.png', 'pmb_wood_spruce_log_side.png'})
pmb_wood.register_leaves("Spruce", {'pmb_wood_spruce_leaves.png'}, {'pmb_wood_spruce_leaves_opaque.png'})
pmb_wood.register_planks("Spruce", {'pmb_wood_spruce_planks.png'})
pmb_wood.register_plank( "Spruce", {'pmb_wood_spruce_plank.png'})
pmb_wood.register_beam(  "Spruce", {'pmb_wood_spruce_plank.png'})

pmb_util.register_all_shapes("pmb_wood:spruce_planks", {}, {remove_groups={"planks"}})



-- CHARCOAL
minetest.register_node('pmb_wood:charcoal_block', {
  description = pmb_util.desc(S("Block of Charcoal"), "grey"),
  groups = {
    full_solid = 1, nature = 1, item_charcoal_block = 1, oddly_breakable_by_hand = 3,
    cracky = 1, solid = 1, suffocates = 2, flammable = 1, fuel = 60 },
  tiles = {"pmb_charcoal_block.png"},
  drop = "pmb_items:charcoal",
  sounds = pmb_sounds.default_stone(),
})

minetest.register_node('pmb_wood:hot_coals', {
  description = pmb_util.desc(S("Hot Coals"), "grey"),
  groups = {
    full_solid = 1, nature = 1, item_hot_coals = 1, oddly_breakable_by_hand = 3,
    cracky = 1, solid = 1, suffocates = 2, flammable = 1, fuel = 60 },
  tiles = {"pmb_hot_coals.png"},
  drop = {
    max_items = 1,
    items = {
      {
        items = {'pmb_items:charcoal 1'},
        rarity = 2
      },
      {
        items = {'pmb_items:charcoal 1'},
        rarity = 2
      },
    },
  },
  sounds = pmb_sounds.default_stone(),
  light_source = 6,
  on_timer = function(pos, time)
    local above = minetest.get_node(vector.offset(pos, 0, 1, 0))
    if minetest.get_item_group(above.name, "fire") == 0
    and not minetest.find_node_near(pos, 2, "group:spreads_fire") then
      minetest.swap_node(pos, {name="pmb_wood:charcoal_block"})
      minetest.get_node_timer(pos):stop()
      return false
    else
      minetest.get_node_timer(pos):set(10,0)
    end
  end,
  on_construct = function(pos)
    minetest.get_node_timer(pos):start(math.random(5, 60))
  end,
  _on_node_update = function(pos)
    local nt = minetest.get_node_timer(pos)
    if nt:is_started() then return false end
    nt:start(math.random(5, 60))
  end,
})

dofile(mod_path .. DIR_DELIM .. "scaffolding.lua")