local function rotate_and_shoot() end
local function draw_particles() end

local SENTRY_RANGE = 14



local multiplier2 = 3.6
local sentry = {
  initial_properties = {
    hp_max = 8, -- TODO: da aumentare una volta implementato lo scudo
    physical = true,
    collide_with_objects = true,
    visual = "mesh",
    mesh = "bl_tutorial_turret.b3d",
    backface_culling = false,
    visual_size = {x = 1 * multiplier2, y = 1 * multiplier2, z = 1 * multiplier2},
    textures = {"bl_tutorial_turret.png"},
    collisionbox = {-0.15 * multiplier2, -0.16 * multiplier2, -0.14 * multiplier2, 0.15 * multiplier2, 0.16 * multiplier2, 0.14 * multiplier2}
    },

    spawning = true,
    shooting = false,
    dying = false,

    on_activate = function(self)
      local sentry = self.object
      sentry:set_animation({x=120, y=130}, 20, nil, false)
      audio_lib.play_sound("bl_tutorial_sentry_spawn", {gain = 0.2, pitch = 1.15, object = sentry, max_hear_distance = SENTRY_RANGE + 5})
      minetest.after(1.2, function()
        if not self.object then return end
        self.object:set_animation({x=1, y=100}, 20)
        self.spawning = false
      end)
    end,

    on_step = function(self, dtime, moveresult)
      if self.spawning or self.shooting then return end

      local obj
      local turret = self.object
      local t_pos = turret:get_pos()
      local dir = vector.new(math.sin(turret:get_yaw()), 0, math.cos(turret:get_yaw()))
      local to_target_dir, angle

      -- cerca l'obiettivo
      for _, objs in pairs(minetest.get_objects_inside_radius(t_pos, SENTRY_RANGE)) do
        to_target_dir = vector.direction(t_pos, vector.add(objs:get_pos(), vector.new(0,1,0)))
        angle = math.acos(vector.dot(vector.normalize(dir), to_target_dir))
        if objs:is_player() and angle <= math.pi/3 then
          obj = objs
          break
        end
      end

      if not obj then return end

      turret:set_animation({x=105, y=106}, 10)
      self.shooting = true
      rotate_and_shoot(turret, to_target_dir)   -- 1° colpo

      minetest.after(0.3, function()            -- 2° colpo
        -- se controllo solo obj e l'obiettivo si è sconnesso, passa il controllo
        if not obj:get_pos() or not self.object or self.dying then return end
        to_target_dir = vector.direction(t_pos, vector.add(obj:get_pos(), vector.new(0,1,0)))
        rotate_and_shoot(turret, to_target_dir)

        minetest.after(0.3, function()          -- 3° colpo
          if not obj:get_pos() or not self.object or self.dying then return end
          to_target_dir = vector.direction(t_pos, vector.add(obj:get_pos(), vector.new(0,1,0)))
          rotate_and_shoot(turret, to_target_dir)
        end)
      end)

      minetest.after(1, function()
        if not self.object then return end
        self.object:set_animation({x=26, y=26})

        minetest.after(1, function()
          if not self then return end
          turret:set_bone_position("Rotation", vector.new(0,1,0), {x=0,y=0,z=0})
          turret:set_animation({x=1, y=100}, 20)
          self.shooting = false
        end)
      end)
    end,

    on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
      local entity = self.object
      if not self.dying and entity:get_hp() - damage <= 0 then
        entity:set_hp(1)
        entity:set_animation({x=112, y=115}, 25, nil, false)
        self.dying = true

        audio_lib.play_sound("bl_tutorial_sentry_death", {pos = entity:get_pos(), max_hear_distance = SENTRY_RANGE + 5})
        minetest.add_particlespawner({
          attached = self.object,
          amount = 200,
          time = 0.1,
          minvel = {x = -10,y = -6, z = -10},
          maxvel = {x = 10, y = 6, z = 10},
          minsize = 1,
          maxsize = 3,
          texture = {
            name = "bl_tutorial_sentry_explosion.png",
            alpha_tween = {1, 0},
            scale_tween = {
              {x = 1, y = 1},
              {x = 0, y = 0},
            },
            animation = {
              type = "vertical_frames",
              aspect_w = 16, aspect_h = 16,
              length = 0.3,
            },
            },
          glow = 12,
        })

        minetest.after(0.15, function()
          entity:punch(puncher, nil, {damage_groups = { fleshy = 999}})
        end)

        return true
      end
    end,

    on_death = function(self, killer)
      local p_name = killer:get_player_name()
      if not arena_lib.is_player_in_arena(p_name) then return end

      bl_tutorial.decrease_sentries(p_name)
    end,
}

minetest.register_entity("bl_tutorial:sentry", sentry)



function rotate_and_shoot(sentry, dir)
  if not sentry:get_rotation() then return end -- se controllo solo `sentry`, crasha sotto. Prob le entità non vengono rimosse all'istante, ma le loro funzioni sì (?)
  local new_rot = vector.apply(vector.add(vector.dir_to_rotation(dir), sentry:get_rotation()), math.deg)

  new_rot.y = -new_rot.y
  sentry:set_bone_position("Rotation", vector.new(0,1,0), new_rot)

  local sentry_centre = 0.3
  local pointed_object = weapons_lib.get_pointed_objects(sentry, 20, false, {height = sentry_centre, dir = dir})

  draw_particles(dir, vector.add(sentry:get_pos(), vector.new(0, sentry_centre, 0)))
  audio_lib.play_sound("bl_smg_shoot", {pitch =  2.3, object = sentry, max_hear_distance = SENTRY_RANGE + 5})

  if next(pointed_object) then
    local target = pointed_object[1].object

    if target:get_hp() < 1.5 then
      if arena_lib.is_player_in_arena(target:get_player_name()) then
        bl_tutorial.kill(target)
      else
        target:set_hp(2)
      end

    else
      target:punch(sentry, nil, {damage_groups = {fleshy = 1}})
    end
  end
end



function draw_particles(dir, origin)
  minetest.add_particlespawner({
    amount = 5,
    time = 0.1,
    pos = vector.new(origin),
    vel = vector.multiply(dir, 60),
    size = 1.5,
    collisiondetection = true,
    collision_removal = true,
    object_collision = true,
    texture = "bl_pixelgun_trail.png"
  })
end