local battleGeneral,battlePlayer,battleCamera
local onlinePlay,onlinePlayPlayers

local playerstun = require("playerstun")

local booMushroom = {}


local startCommand
local stopCommand


local function poofEffect(p)
    if onlinePlay.currentMode == onlinePlay.MODE_OFFLINE or p.idx == battleCamera.onlineFollowedPlayerIdx then
        SFX.play(87)
    end

    Effect.spawn(63,p.x + p.width*0.5,p.y + p.height*0.5)
    p:mem(0x140,FIELD_WORD,p:mem(0x140,FIELD_WORD) + 30)
end

local function startInternal(p,duration)
    p.data.booMushroom = {
        duration = duration,
        timeLeft = duration,
        restoreFrame = nil,
    }
    poofEffect(p)
end

local function stopInternal(p)
    p.data.booMushroom = nil
    poofEffect(p)
end


function booMushroom.start(p,duration)
    if p.hasStarman or not onlinePlayPlayers.ownsPlayer(p) then
        return
    end
    
    if onlinePlay.currentMode ~= onlinePlay.MODE_OFFLINE then
        startCommand:send(0, duration)
    end

    startInternal(p,duration)
end

function booMushroom.stop(p)
    if not booMushroom.isActive(p) or not onlinePlayPlayers.ownsPlayer(p) then
        return
    end

    if onlinePlay.currentMode ~= onlinePlay.MODE_OFFLINE then
        stopCommand:send(0)
    end

    stopInternal(p)
end

function booMushroom.isActive(p)
    return (p.data.booMushroom ~= nil)
end


function booMushroom.onTick()
    for _,p in ipairs(Player.get()) do
        local data = p.data.booMushroom

        if data ~= nil then
            data.timeLeft = math.max(0,data.timeLeft - 1)

            if (data.timeLeft <= 0 or p.hasStarman) and onlinePlayPlayers.ownsPlayer(p) then
                booMushroom.stop(p)
            end
        end
    end
end

function booMushroom.onTickEnd()
    for _,p in ipairs(Player.get()) do
        local data = p.data.booMushroom

        if data ~= nil then
            -- Flash at the end
            if data.timeLeft <= 64 and p:mem(0x140,FIELD_WORD) == 0 and data.timeLeft%6 < 3 then
                p:mem(0x142,FIELD_BOOL,true)
            end
        end
    end
end


function booMushroom.booMushroomedPlayerShouldBeVisible(p,camIdx)
    if battleCamera.cameraIsFocusedOnPlayer(camIdx,p.idx) then
        return true
    end

    if battlePlayer.teamsAreEnabled() and battlePlayer.playersAreOnSameTeam(p.idx,battleCamera.onlineFollowedPlayerIdx) then
        return true
    end

    return false
end

function booMushroom.onCameraDraw(camIdx)
    for _,p in ipairs(battleCamera.getCamerasPlayers(camIdx)) do
        local data = p.data.booMushroom

        if data ~= nil and battleCamera.cameraIsFocusedOnPlayer(camIdx,p.idx) then
            battleGeneral.drawProgressCircle{
                sceneCoords = true,
                priority = -0.1,
                x = p.x + p.width*0.5,
                y = p.y - 20,
                progress = data.timeLeft/data.duration,
            }
        end
    end
end

--[[function booMushroom.onDraw()
    for _,p in ipairs(Player.get()) do
        local data = p.data.booMushroom

        if data ~= nil and data.restoreFrame == nil and not p:mem(0x0C,FIELD_BOOL) then
            data.restoreFrame = p.frame
            p:setFrame(-50*p.direction)
        end
    end
end

function booMushroom.onDrawEnd()
    for _,p in ipairs(Player.get()) do
        local data = p.data.booMushroom

        if data ~= nil and data.restoreFrame ~= nil then
            p.frame = data.restoreFrame
            data.restoreFrame = nil
        end
    end
end]]


function booMushroom.onInitAPI()
    registerEvent(booMushroom,"onTick")
    registerEvent(booMushroom,"onTickEnd")
    registerEvent(booMushroom,"onCameraDraw")
    --[[registerEvent(booMushroom,"onDraw","onDraw",false)
    registerEvent(booMushroom,"onDrawEnd")]]


    battleGeneral = require("scripts/battleGeneral")
    battlePlayer = require("scripts/battlePlayer")
    battleCamera = require("scripts/battleCamera")

    onlinePlay = require("scripts/onlinePlay")
    onlinePlayPlayers = require("scripts/onlinePlay_players")


    startCommand = onlinePlay.createCommand("battle_booMushroom_start",onlinePlay.IMPORTANCE_MAJOR)
    stopCommand = onlinePlay.createCommand("battle_booMushroom_stop",onlinePlay.IMPORTANCE_MAJOR)


    function battlePlayer.onPostPlayerKillCustom(p)
        if booMushroom.isActive(p) then
            stopInternal(p)
        end
    end

    function onlinePlay.onDisconnect(playerIdx)
        local p = Player(playerIdx)

        if booMushroom.isActive(p) then
            stopInternal(p)
        end
    end

    function startCommand.onReceive(sourcePlayerIdx, duration)
        local p = Player(sourcePlayerIdx)

        startInternal(p,duration)
    end

    function stopCommand.onReceive(sourcePlayerIdx)
        local p = Player(sourcePlayerIdx)

        stopInternal(p)
    end
end


return booMushroom