local S = core.get_translator("block_league")

local function check_positions() end

local POINTS_TO_CHECK = 4
local last_player_pos = {}          -- KEY: p_name; VALUE: pos

-- per ottimizzare funzioni globalstep
local get_players_in_minigame = arena_lib.get_players_in_minigame
local get_node = core.get_node
local get_player_by_name = core.get_player_by_name
local get_arena_by_player = arena_lib.get_arena_by_player



local function register_rays(name, texture, is_invisible)
  core.register_node("block_league:" .. name, {
    description = S("Rays"),
    inventory_image = texture,
    tiles = {{
      name = texture,
      animation = {
        type = "vertical_frames",
        aspect_w = 16,
        aspect_h = 16,
        length = 0.5
      }}
    },
    use_texture_alpha = "clip",
    drawtype = "nodebox",
    paramtype = "light",
    paramtype2 = "wallmounted",
    node_box = { type = "wallmounted" },
    light_source = 10,
    walkable = false,
    pointable = false,
    buildable_to = true,
    groups = {oddly_breakable_by_hand = 3}
  })

  core.register_node("block_league:" .. name .. "_inv", {
    description = S("Rays (invisible)"),
    inventory_image = "[combine:16x16:0,0=" .. texture .. ":0,0=arenalib_infobox_spectate.png",
    tiles = {{name = "blank.png"}},
    use_texture_alpha = "clip",
    drawtype = "nodebox",
    paramtype = "light",
    paramtype2 = "wallmounted",
    node_box = { type = "wallmounted" },
    walkable = false,
    pointable = false,
    buildable_to = true,
    groups = {oddly_breakable_by_hand = 3}
  })
end

register_rays("rays_orange", "bl_rays_orange.png")
register_rays("rays_blue", "bl_rays_blue.png")



core.register_globalstep(function(dtime)
  for _, pl_name in pairs(get_players_in_minigame("block_league")) do
    if not arena_lib.is_player_spectating(pl_name) then
      local arena = get_arena_by_player(pl_name)

      if not arena.in_loading then
        local player = get_player_by_name(pl_name)
        local p_pos = player:get_pos()
        local last_pos = last_player_pos[pl_name] or p_pos
        local is_touching_rays, is_ray_blue = check_positions(last_pos, p_pos)

        if is_touching_rays then
          local p_data = arena.players[pl_name]
          local p_team = p_data.teamID
          local p_meta = player:get_meta()

          if p_meta:get_int("bl_has_ball") == 1 then
            block_league.get_ball(player):reset()

            -- reindirizza sulla palla gli spettatori
            for sp_name, _ in pairs(arena_lib.get_player_spectators(pl_name)) do
              if arena.spectators[sp_name].was_following_ball then
                arena_lib.spectate_target("block_league", arena, sp_name, "entity", "Ball")
              end
            end
          end

          -- Controllo immunità extra perché sennò, se muoiono contro i raggi, al
          -- rinascere vengono riuccisi subito
          if player:get_hp() > 0 and p_meta:get_int("bl_invincibility") == 0 and ((p_team == 1 and is_ray_blue) or (p_team == 2 and not is_ray_blue)) then
            block_league.kill_by_suicide(arena, player, p_data.dmg_received, "bl_log_rays.png")
          end
        end

        last_player_pos[pl_name] = p_pos
      end
    end
  end
end)





----------------------------------------------
---------------FUNZIONI LOCALI----------------
----------------------------------------------

-- derived from Wuzzy's get_intermediate_positions function on Glitch, GPL 3.0
-- https://content.luanti.org/packages/Wuzzy/glitch/
function check_positions(pos1, pos2)
  local posses = { pos1 }
  local sx, sy, sz, ex, ey, ez

  sx = math.min(pos1.x, pos2.x)
  sy = math.min(pos1.y, pos2.y)
  sz = math.min(pos1.z, pos2.z)
  ex = math.max(pos1.x, pos2.x)
  ey = math.max(pos1.y, pos2.y)
  ez = math.max(pos1.z, pos2.z)

  local xup, yup, zup

  xup = pos1.x < pos2.x
  yup = pos1.y < pos2.y
  zup = pos1.z < pos2.z

  local x,y,z
  local steps = POINTS_TO_CHECK - 1

  for s=1, steps-1 do
    if xup then
      x = sx + (ex - sx) * (s/steps)
    else
      x = sx + (ex - sx) * ((steps-s)/steps)
    end
    if yup then
      y = sy + (ey - sy) * (s/steps)
    else
      y = sy + (ey - sy) * ((steps-s)/steps)
    end
    if zup then
      z = sz + (ez - sz) * (s/steps)
    else
      z = sz + (ez - sz) * ((steps-s)/steps)
    end
    table.insert(posses, vector.new(x,y,z))
  end

  table.insert(posses, pos2)

  for i = 1, #posses do
    local p_nodename = get_node(posses[i]).name

    if p_nodename == "block_league:rays_blue"
       or p_nodename == "block_league:rays_blue_inv"
       or p_nodename == "block_league:rays_orange"
       or p_nodename == "block_league:rays_orange_inv" then
      return true, p_nodename == "block_league:rays_blue" or p_nodename == "block_league:rays_blue_inv"
    end
  end
end
