local DURATION_SECONDS = 2
local AI_PERCENTAGE    = 0.30
local WEAPON_NAME      = 'Shield Pack'

local reset, activateShieldPack, applyShieldPacks = (function()

  local state

  local function reset()
    state = {}
  end

  local function activateShieldPack(ship)
    local signature = ship:getSignature()
    local cutoff = mn.getMissionTime() + DURATION_SECONDS
    state[signature] = cutoff
  end

  local function applyShieldPacks()
    local now = mn.getMissionTime()
    for signature, cutoff in pairs(state) do
      if now <= cutoff then
        local ship = mn.getObjectFromSignature(signature)
        if ship:getBreedName() == 'Ship' then
          local shields = ship.Shields
          local count = #shields
          local full = shields.CombinedMax / count
          for i = 1, count do shields[i] = full end
        end
      end
    end
  end

  return reset, activateShieldPack, applyShieldPacks

end)()

local onShieldPackFired = (function()

  local ScriptedAudio = require("soundhandler")

  local function selectDifferentWeapon(ship)
    local primaries = ship.PrimaryBanks
    local primaryCount = #primaries
    for i = 1, primaryCount do
      local bank = primaries[i]
      if bank.WeaponClass.Name ~= WEAPON_NAME then
        bank.Armed = true
        return
      end
    end
  end

  return function(ship)
    activateShieldPack(ship)
    if ship:isPlayer() then
      ScriptedAudio:playSound("ShieldPack.ogg", false)
      -- Select an actual gun, with a brief pause so it doesn't immediately fire.
      mn.waitAsync(0.5):continueWith(function() selectDifferentWeapon(ship) end)
    else
      ba.warning("AI-controlled ship fired a Shield Pack")
    end
  end

end)()

local checkAIUsage = (function()

  local function shouldUseShieldPack(ship)
    if ship:isPlayer() then return false end
    local shields = ship.Shields
    local remaining = shields.CombinedLeft 
    -- Getting to zero shields legitimately is very rare;
    -- it usually indicates a capship or in-mission jump.
    if remaining == 0 then return false end
    -- Use a shield pack only if our shields are damaged.
    local max = shields.CombinedMax
    return (remaining / max) <= AI_PERCENTAGE
  end

  return function()
    for ship in mn.getShipList() do
      if shouldUseShieldPack(ship) then
        local banks = ship.PrimaryBanks
        local count = #banks
        for i = 1, count do
          local bank = banks[i]
          if bank.WeaponClass.Name == WEAPON_NAME then
            local ammo = bank.AmmoLeft
            if ammo > 0 then
              bank.AmmoLeft = ammo - 1
              activateShieldPack(ship)
              return
            end
          end
        end
      end
    end
  end
  
end)()

return {
  reset = reset,
  onShieldPackFired = onShieldPackFired,
  onFrame = function()
    checkAIUsage()
    applyShieldPacks()
  end
}

