dofile_once("data/scripts/lib/utilities.lua")

local larpa_mod_enable = {
  -- Generated from settings.lua
}

local larpa_exclude_projectiles = {
  -- Generated from settings.lua
}

local larpa_exclude_misc = {
  -- Generated from settings.lua
}

for i=0,ModSettingGetCount() do
  local setting,value = ModSettingGetAtIndex(i)
  if (type(setting) ~= "string") then
    goto nextSetting
  end
  if (string.sub(setting,1,11) ~= "larpachaos.") then
    goto nextSetting
  end
  local larpa_setting = string.sub(setting,12,-1)
  -- larpa_mod_enable
  if (string.sub(larpa_setting,1,6) == "larpa_") then
    larpa_mod_enable[larpa_setting] = value
    print("Larpa " .. tostring(value) .. ": " .. larpa_setting)
  end
  -- larpa_exclude_projectiles
  if (string.sub(larpa_setting,1,5) == "data/" and value) then
    table.insert(larpa_exclude_projectiles,larpa_setting)
    print("Larpa exclude: " .. larpa_setting)
  end
  -- larpa_exclude_misc
  if (string.sub(larpa_setting,1,6) == "other_") then
    larpa_exclude_misc[larpa_setting] = value
    print("Larpa exclude: " .. larpa_setting)
  end
  ::nextSetting::
end

local limit_projectiles = ModSettingGet("larpachaos.limit_projectiles")
local limit_radius = ModSettingGet("larpachaos.limit_radius")

--debug_print_table(larpa_mod_enable)
debug_print_table(larpa_exclude_projectiles)

local function contains(table,val)
  for i=1,#table do
    if table[i] == val then 
      return true
    end
  end
  return false
end

function OnWorldPreUpdate(player_entity)
  local punits = EntityGetWithTag("player_unit")
  if (punits == nil or #punits == 0) then
    return
  end
  local x,y = EntityGetTransform(punits[1])
  if (x == nil or y == nil) then
    return
  end

  local targets = EntityGetInRadiusWithTag(x,y,limit_radius,"projectile")

  if (#targets > limit_projectiles) then
    -- print("Exceeded larpa limit: " .. tostring(#targets))
    return
  end

  for i,target in ipairs(targets) do
    -- if (i > limit_projectiles) then
    --   -- print("Larpa limit: " .. tostring(i))
    --   break
    -- end

    -- everyone loves larpa tag
    -- if (EntityHasTag(target,"projectile_larpa_added")) then
      -- local projectile_filename = EntityGetFilename(target)
      -- print("skip applied "..projectile_filename)
      -- goto nextProjectile
    -- end

    -- vanilla Noita larpa tag
    if (EntityHasTag(target,"projectile_cloned")) then
      -- local projectile_filename = EntityGetFilename(target)
      -- print("skip cloned  "..projectile_filename)
      goto nextProjectile
    end


    -- tag everything else to show projectile has been processed
    EntityAddTag(target,"projectile_cloned")

    -- "Ylialkemisti's countered projectiles tag
    if (EntityHasTag(target,"boss_alchemist")) then
      goto nextProjectile
    end
        
    -- exclude projectiles
    local projectile_filename = EntityGetFilename(target)
    if (contains(larpa_exclude_projectiles,projectile_filename)) then
      goto nextProjectile
    end
    
-- print("larpa'ed "..projectile_filename)

    local projectilecomponents = EntityGetComponent(target,"ProjectileComponent")
    -- exclude other
    if (larpa_exclude_misc.other_environment) then
      -- do not larpa projectiles that originate from the environment
      local mWhoShot = ComponentGetValue2(projectilecomponents[1],"mWhoShot")
      if (mWhoShot == 0) then
        goto nextProjectile
      end
    end

    if (larpa_exclude_misc.other_novelocity) then
      -- do not larpa projectiles that originate from the environment and have no initial velocity
      local mWhoShot = ComponentGetValue2(projectilecomponents[1],"mWhoShot")
      if (mWhoShot == 0) then
        local velocitycomponents = EntityGetComponent(target,"VelocityComponent")       
        if (velocitycomponents == nil) then
          goto nextProjectile
        end
        local mVelx,mVely = ComponentGetValueVector2(velocitycomponents[1],"mVelocity")
        if ((mVelx == 0) and (mVely == 0 )) then
          goto nextProjectile
        end
      end
    end

    if (larpa_mod_enable.larpa_orbit) then
      EntityAddComponent(target,"VariableStorageComponent",{
        _tags = "orbit_projectile_type",
        name = "orbit_projectile_type",
        value_string = "orbit_larpa"
      })
      EntityAddComponent(target,"VariableStorageComponent",{
        _tags = "orbit_projectile_speed",
        name = "orbit_projectile_speed",
        value_float = "0"
      })
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/orbit_projectile.lua",
        execute_every_n_frame = "1",
        remove_after_executed = "1"
      })
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/orbit_projectile_rotation.lua",
        execute_every_n_frame = "1"
      })
    end

    if (larpa_mod_enable.larpa_explosion) then
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/larpa_death.lua",
        execute_every_n_frame = "-1",
        execute_on_removed = "1"
      })
    end

    if (larpa_mod_enable.larpa_bounce) then
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/bounce_larpa.lua",
        execute_every_n_frame = "1",
        remove_after_executed = "1"
      })  
      for c=1,#projectilecomponents do
        ComponentSetValue2(projectilecomponents[c],"bounce_always",true)
        ComponentSetValue2(projectilecomponents[c],"bounces_left",1)
      end
    end

    if (larpa_mod_enable.larpa_trail) then
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/larpa_chaos_2.lua",
        execute_every_n_frame = "5",
      })
      EntityAddComponent(target,"LifetimeComponent",{
        lifetime = "200"
      })
    end

    if (larpa_mod_enable.larpa_chaos) then
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/larpa_chaos.lua",
        execute_every_n_frame = "10",
      })
      EntityAddComponent(target,"LifetimeComponent",{
        lifetime = "300"
      })
    end

    if (larpa_mod_enable.larpa_upwards) then
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/larpa_upwards.lua",
        execute_every_n_frame = "10",
      })
      EntityAddComponent(target,"LifetimeComponent",{
        lifetime = "300"
      })
    end
    
    if (larpa_mod_enable.larpa_downwards) then
      EntityAddComponent(target,"LuaComponent",{
        script_source_file = "data/scripts/projectiles/larpa_downwards.lua",
        execute_every_n_frame = "10",
      })
      EntityAddComponent(target,"LifetimeComponent",{
        lifetime = "300"
      })
    end
    ::nextProjectile::
  end
end
