local battleBombs
local onlinePlay

local randomPowerups = {}


randomPowerups.transformIDs = {9,14,34,169,170,264}

randomPowerups.npcID = 287


local activePlayerExplosions = {}


function randomPowerups.chooseID(p)
    if RNG.random() < battleBombs.getChanceFromRandomPowerup(p) then
        return battleBombs.bagNPCID
    end

    return RNG.irandomEntry(randomPowerups.transformIDs)
end


local nonBlockHittingNPCIDMap = table.map{13,265,58,21,67,68,69,70}

local function npcCouldveHitBlock(block,npc)
    if npc.despawnTimer <= 0 or not npc.isProjectile or npc.noblockcollision or nonBlockHittingNPCIDMap[npc.id] then
        return false
    end

    local config = NPC.config[npc.id]

    if config == nil or config.noblockcollision then
        return false
    end

    return true
end

function randomPowerups.guessHittingPlayer(block)
    -- Look for projectile NPCs hitting the side of the block. If they belong to a player, use that player
    for _,npc in NPC.iterateIntersecting(block.x - 1,block.y,block.x + block.width + 1,block.y + block.height) do
        if npc:mem(0x132,FIELD_WORD) > 0 and npcCouldveHitBlock(block,npc) then
            return Player(npc:mem(0x132,FIELD_WORD))
        end
    end

    -- Look for players' explosions hitting the block
    for _,explosionData in ipairs(activePlayerExplosions) do
        local explosion = explosionData[1]

        if explosion.collider:collide(block) then
            return explosionData[2]
        end
    end
end


function randomPowerups.pickBlockContent(block,p)
    if block.contentID == (1000 + randomPowerups.npcID) then
        return 1000 + randomPowerups.chooseID(p)
    end

    if battleBombs.bagReplaceableIDMap[block.contentID - 1000] and RNG.random() < battleBombs.getChanceFromRandomPowerup(p) then
        return 1000 + battleBombs.bagNPCID
    end

    return block.contentID
end


function randomPowerups.onBlockHit(eventObj,block,fromTop,playerObj)
    if onlinePlay.currentMode ~= onlinePlay.MODE_OFFLINE then
        -- When online, this logic is instead handled by onlinePlay's onBlockHit handler instead
        return
    end

    if block.contentID > 0 then
        block.contentID = randomPowerups.pickBlockContent(block,playerObj or randomPowerups.guessHittingPlayer(block))
    end
end


function randomPowerups.onPostExplosion(explosion,p)
    if explosion.friendly and p ~= nil then
        table.insert(activePlayerExplosions,{explosion,p})
    end
end

function randomPowerups.onTickEnd()
    -- Clear active explosions
    local i = 1

    while (activePlayerExplosions[i] ~= nil) do
        activePlayerExplosions[i] = nil
        i = i + 1
    end
end


function randomPowerups.onInitAPI()
    registerEvent(randomPowerups,"onBlockHit")
    registerEvent(randomPowerups,"onPostExplosion")
    registerEvent(randomPowerups,"onTickEnd")

    battleBombs = require("scripts/battleBombs")
    onlinePlay = require("scripts/onlinePlay")
end


return randomPowerups