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

local coral_bug = {}
function coral_bug.do_sound(self, name, gain)
    minetest.sound_play(("pmb_underworld_"..name), {
        gain = gain or 1,
        pos = self.object:get_pos(),
        object = self.object,
        pitch = (math.random()*0.2) + 0.9
    })
end

coral_bug.conversion_table = {
    ["pmb_underworld:lava_rock_mythril"] = 1
}

coral_bug.conversion_chance = {
    ["pmb_underworld:lava_rock_mythril"] = 1
}

function coral_bug.register_infested_node(name, chance)
    chance = chance or 1
    local def = table.copy(minetest.registered_nodes[name])
    local overlay = "pmb_underworld_coral_overlay.png"
    if not def then error("coral_bug.register_infested_node: failed because "..name.." has no definition") end
    def.groups.magicky = 1
    def.groups.lava_coral = 1
    def.tiles[1] = def.tiles[1].."^"..overlay
    if def.drop == nil then
        def.drop = name
    end
    local newnode = name.."_coral_infested"
    minetest.register_node(newnode, def)
    coral_bug.conversion_table[name] = newnode
    coral_bug.conversion_chance[name] = chance
end

coral_bug.register_infested_node("pmb_underworld:lava_rock_mythril", 1)
coral_bug.register_infested_node("pmb_underworld:lava_rock", 0.1)

-- the coral bug has entered the node and made it easier to dig
function coral_bug.convert_node(self)
    if self._removed then return false end
    local pos = self.object:get_pos()
    if not pos then return false end
    pos = vector.offset(pos, 0, -0.6, 0)
    local node = minetest.get_node(pos)
    local convert = coral_bug.conversion_table[node.name]
    if not convert then return false end
    minetest.set_node(pos, {name=convert})
    return true
end

function coral_bug.do_particles(self)
    local pos = self.object:get_pos()
    local va = 0.2
    for i = 1, 10 do
        minetest.add_particle({
            pos = vector.offset(pos, (math.random() * va)-va/2, (math.random() * va)-va/2, (math.random() * va)-va/2),
            velocity = vector.new(0,math.random(),0),
            expirationtime = math.random() * 4,
            size = math.random() * 4,
            collisiondetection = false,
            vertical = false,
            texture = "pmb_underworld_lava_coral_particle.png",
            glow = 4,
        })
    end
end

minetest.register_entity("pmb_underworld:coral_bug", {
    initial_properties = {
        visual = "mesh",
        mesh = "pmb_underworld_coral_bug.b3d",
        textures = {"pmb_underworld_coral_bug.png"},
        use_texture_alpha = false,
        stepheight = 0.2,
        hp_max = 2,
        physical = true,
        collisionbox = {-3/16, -0.5, -3/16,  3/16,  3/16,  6/16,  3/16},
        selectionbox = {-3/16, -0.5, -3/16,  3/16,  3/16,  6/16,  3/16},
        pointable = true,
        damage_texture_modifier = "^[colorize:#ff9999:50",
        -- automatic_face_movement_dir = 90.0,
        -- automatic_face_movement_max_rotation_per_sec = 360,
    },
    glow = 2,
    _name = "pmb_underworld:coral_bug",


    on_step = pmb_entity_api.do_states(),
    -- _drop = {
    --     max_items = 2,
    --     items = {
    --         {
    --             rarity = 4,
    --             items = {"pmb_items:copper_nugget"},
    --         },
    --     }
    -- },
    on_death = function(self, killer)
        if killer and killer ~= self.object then
            pmb_entity_api.do_drops(self)
            coral_bug.do_sound(self, "soul_escape", 0.2)
            coral_bug.do_particles(self)
        end
        self._removed = true
    end,

    _states = {
        idle = {
            animation = "idle",
            step = function(self, dtime, moveresult)
                if self._removed then return false end
                if not self._pmb_idle_time then
                    self._pmb_idle_time = 0
                    self._checked_for_node = false
                else self._pmb_idle_time = self._pmb_idle_time + dtime end
                pmb_entity_api.get_target(self)
                -- if (self._pmb_target and pmb_entity_api.get_target_dist(self) > 2) then return "walk" end
                pmb_entity_api.get_wander(self, 30)
                pmb_entity_api.decelerate(self, 0.90)
                local dist = pmb_entity_api.get_target_dist(self)
                if (self._pmb_to_pos and self._pmb_idle_time > 1) then
                    if  ((not self._pmb_target) or (dist and dist > 2)) then
                        self._pmb_idle_time = nil
                        return "walk"
                    end
                end
                local pos = self.object:get_pos()
                local node_below = minetest.get_node(vector.offset(pos, 0, -0.6, 0))
                if not self._checked_for_node and coral_bug.conversion_table[node_below.name] ~= nil then
                    self._checked_for_node = true
                    if math.random() < coral_bug.conversion_chance[node_below.name] then
                        return "dive"
                    end
                end
            end,
        },
        walk = {
            animation = "walk",
            step = function(self, dtime, moveresult)
                if self._removed then return false end
                if self._pmb_target and not self._pmb_to_pos then
                    self._pmb_to_pos = self._pmb_target:get_pos()
                    self._pmb_path = {self._pmb_to_pos}
                end
                pmb_entity_api.get_path(self, pmb_entity_api.min_cost)
                pmb_entity_api.do_path(self)
                pmb_entity_api.check_jump(self, 5)
                pmb_entity_api.decelerate(self, 0.90)
                if self._pmb_path then
                    pmb_entity_api.rotate_to_path(self, dtime*3)
                end
                if (not self._pmb_to_pos) then return "idle" end
                local dist = pmb_entity_api.get_target_dist(self)
                if (self._pmb_target and (dist and dist < 2)) then return "idle" end
            end,
        },
        dive = {
            animation = "dive",
            step = function(self, dtime, moveresult)
                if self._removed then return false end
                if not self._pmb_dive_time then self._pmb_dive_time = 0
                else self._pmb_dive_time = self._pmb_dive_time + dtime end
                self.object:set_velocity(vector.new())
                if self._pmb_dive_time > 1.0 then
                    self._pmb_dive_time = nil
                    local ret = coral_bug.convert_node(self)
                    if not ret then return "idle"
                    else
                        coral_bug.do_sound(self, "soul_escape", 0.8)
                        coral_bug.do_particles(self)
                        self.object:punch(self.object, 1.0, {
                            full_punch_interval = 1.0,
                            damage_groups = {magic = 100}
                        }, nil)
                        return "die"
                    end -- remove it because it used up
                end
            end,
        },
    },
    _default_state = "idle",
    on_activate = function(self, staticdata, dtime_s)
        self.object:set_armor_groups({
            pierce=200,
            slash=200,
            blunt=200,
            magic=200,
            poison=900,
        })
        pmb_entity_api.on_activate(self, staticdata, dtime_s)
    end,
    get_staticdata = function(self)
        return pmb_entity_api.get_staticdata(self)
    end,
    on_deactivate = function(self, removal)
        pmb_entity_api.on_deactivate(self, removal)
    end,
    on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
        if damage and damage > 0 then
            -- coral_bug.do_sound(self, "hurt_0", 1)
        end
        return pmb_entity_api.damage.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
    end,
    _pmb_speed = 5,
    _pmb_acceleration = 20,
    _pmb_gravity = 9,
    _pmb_hostile = {player=1},
    _animations = {
        idle = {frames={x=0, y=40}},
        walk = {frames={x=50, y=70}},
        dive = {frames={x=80, y=120}, loop = false}
    },
    _pmb_wander = 3,
    _pmb_range = 20,
})
minetest.register_craftitem("pmb_underworld:lava_coral_bulb", {
    description = pmb_util.desc(S("Lava Coral Bulb"), "red"),
    _tt_long_desc = S("It's... Moving."),
    inventory_image = "pmb_underworld_lava_coral_bulb.png",
    groups = { item_lava_coral_bulb = 1, craftitem = 1, lava_coral = 1, },
    on_place = function(itemstack, placer, pointed_thing)
        local node = minetest.get_node(pointed_thing.under)
        if minetest.get_item_group(node.name, "lava_coral") > 0 then
            local ent = minetest.add_entity(vector.offset(minetest.get_pointed_thing_position(pointed_thing), 0, 1, 0), "pmb_underworld:coral_bug")
            itemstack:take_item()
        end
        return itemstack
    end,
})

local allowed_biomes = {underworld_coral = 1}

if pmb_mob_spawn then
    pmb_mob_spawn.register_mob({
        name = "pmb_underworld:coral_bug",
        groups = {"passive", "pmb_underworld_coral_bug"},
        biomes = {},
        on_spawn = function(self, pos) end,
        can_spawn = function(pos, spawn_info)
            if minetest.find_node_near(pos, 1, "pmb_underworld:lava_coral")
            and pmb_entity_api.has_mobs_in_radius(pos, 40, {"pmb_underworld:coral_bug"}, 0, 3) then
                return true
            end
            return false
        end,
        can_despawn = function(self)
            if self._age and self._age < 20 then return false end
            return true
        end,
    })
    pmb_mob_spawn.cap.pmb_underworld_coral_bug.max = 30
end



