local MT = minetest
local vMod = vm_lighting_wand

local player_effects = {}

local play_wand_sound = function(pos)
  MT.sound_play(vMod.modname, { pos = pos, gain = 0.1, max_hear_distance = 6 })
end

-- spawns particles at given pos
local play_wand_particles = function(pos)
  local speed = 24
  for _, color in pairs({ "green", "red", "blue", "yellow" }) do
    MT.add_particlespawner(
      {
        amount = 20,
        time = 1,
        minpos = { x = pos.x + 2, y = pos.y + 2, z = pos.z + 2 },
        maxpos = { x = pos.x - 2, y = pos.y - 2, z = pos.z - 2 },
        minvel = { x = -1, y = -1, z = -1 },
        maxvel = { x = 1, y = 1, z = 1 },
        minacc = { x = -speed, y = -speed, z = -speed },
        maxacc = { x = speed, y = speed, z = speed },
        minexptime = 1,
        maxexptime = 3,
        minsize = 0.5,
        maxsize = 1.5,
        vertical = false,
        collisiondetection = false,
        texture = vMod.modname .. "_particle_" .. color .. ".png"
      }
    )
  end
end

vMod.set_player_effects = function(player, effect, status)
  local meta = player:get_meta()
  local player_name = player:get_player_name()
  if effect ~= "sound" and effect ~= "particles" then
    return
  end
  meta:set_string(vMod.modname .. "_play_" .. effect, status)
  player_effects[player_name][effect] = status
end

vMod.get_player_effects = function(player)
  return player_effects[player:get_player_name()]
end

-- Main function to play effects
vMod.play_effects = function(player, node_pos)
  local effects = vMod.get_player_effects(player)
  if effects.sound == "true" then
    play_wand_sound(player:get_pos())
  end
  if effects.particles == "true" then
    play_wand_particles(node_pos)
  end
end

vMod.play_failed_effects = function(player, reason)
  reason = reason and reason or nil
  if reason then
    MT.chat_send_player(player:get_player_name(), "[LightingWand] " .. reason)
  end
  local effects = vMod.get_player_effects(player)
  if effects.particles ~= "true" then
    return
  end
  local speed = 40
  local pos = player:get_pos()
  MT.add_particlespawner(
    {
      amount = 100,
      time = 1,
      minpos = { x = pos.x + 3, y = pos.y + 3, z = pos.z + 3 },
      maxpos = { x = pos.x - 3, y = pos.y, z = pos.z - 3 },
      minvel = { x = -3, y = 0, z = -3 },
      maxvel = { x = 3, y = 2, z = 3 },
      minacc = { x = -speed, y = -speed, z = -speed },
      maxacc = { x = speed, y = speed, z = speed },
      minexptime = 1,
      maxexptime = 3,
      minsize = 0.5,
      maxsize = 1.5,
      vertical = true,
      collisiondetection = true,
      texture = vMod.modname .. "_particle_fail.png"
    }
  )
end

MT.register_on_joinplayer(
  function(player)
    local meta = player:get_meta()
    local sound = meta:get_string(vMod.modname .. "_play_sound") or "true"
    local particles = meta:get_string(vMod.modname .. "_play_particles") or "true"
    sound = sound ~= "" and sound or "true"
    particles = particles ~= "" and particles or "true"
    player_effects[player:get_player_name()] = {
      sound = sound,
      particles = particles
    }
  end
)

MT.register_on_leaveplayer(
  function(player)
    player_effects[player:get_player_name()] = nil
  end
)
