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

local paralx2 = require("paralx2")

local onlinePlay = require("scripts/onlinePlay")
local battleMenu = require("scripts/battleMenu")

local playerSelect = require("playerSelect")
local levelSelect = require("levelSelect")
local musicSelect = require("musicSelect")
local costumeSelect = require("costumeSelect")


require("maskCollection/scripts/maskCollection")


local patternImage = Graphics.loadImageResolved("bg_pattern.png")
local sunCutoutImage = Graphics.loadImageResolved("bg_sun_cutout.png")

--local cloudColor = Color.fromHexRGB(0xC7FFFB)
local cloudColor = Color.fromHexRGB(0xF2C6D3)
local sunTopColor = Color.fromHexRGB(0xFAFF97)
local sunBottomColor = Color.fromHexRGB(0xF5B2C4)


local buffer = Graphics.CaptureBuffer()
local backgroundShader = Shader()
backgroundShader:compileFromFile(nil,"bg_full.frag")

function onCameraDraw(camIdx)
    local sectionObj = Section(player.section)
    local cam = Camera(camIdx)

    if sectionObj.backgroundID == 8 then
        local b = sectionObj.origBoundary

        local cameraX = cam.x + cam.width *0.5 - (b.left + b.right)*0.5
        local cameraY = cam.y + cam.height*0.5 - b.bottom

        local bg = player.sectionObj.background

        for _,layer in ipairs(bg.layers) do
            -- Handle shader uniforms and other layer properties
            local uniforms = layer.uniforms
            local image = layer.img

            uniforms.cameraX = cameraX + lunatime.tick()
            uniforms.cameraY = cameraY

            if layer.name == "pattern" then
                uniforms.patternImage = patternImage
                uniforms.patternSize = vector(patternImage.width,patternImage.height)
                uniforms.layerSize = vector(image.width,image.height)
                uniforms.cloudColor = cloudColor

                uniforms.focus = paralx2.focus
                uniforms.time = lunatime.tick()
            elseif layer.name == "clouds" then
                layer.color = cloudColor
            elseif layer.name == "sun" then
                uniforms.cutoutImage = sunCutoutImage

                uniforms.layerSize = vector(image.width,image.height)
                uniforms.time = lunatime.tick()

                uniforms.topColor = sunTopColor
                uniforms.bottomColor = sunBottomColor
            end

            if layer.name == "sun" or layer.name == "pattern" then
                layer.x = (cam.width + cam.renderX*2 - image.width)*0.5
            end
        end
    end

    -- Background shader
    buffer:captureAt(-99)

    Graphics.drawScreen{
        texture = buffer,priority = -99,
        shader = backgroundShader,uniforms = {
            bufferSize = vector(buffer.width,buffer.height),
            time = lunatime.tick(),
        },
    }
end


local function openMenu(menu,playerObj,args)
    if battleMenu.currentMenu ~= nil then
        return
    end

    local pauses = true

    if onlinePlay.currentMode ~= onlinePlay.MODE_OFFLINE then
        if playerObj.idx ~= onlinePlay.playerIdx then
            return
        end

        pauses = false
    end

    menu:open(args or {},1,playerObj,pauses)
end


local menuBlockFuncs = {
    [281] = function(playerObj)
        playerSelect.initialMenu:open({},1,player,false)
        battlePlayer.saveCharacters()
        battlePlayer.loadCharacters()
    end,
    [159] = function(playerObj)
        openMenu(battleGeneral.settingsMenu,playerObj)
    end,
    [223] = function(playerObj)
        openMenu(playerSelect.disconnectMenu,playerObj)
    end,
    [160] = function(playerObj)
        openMenu(musicSelect.menu,playerObj)
    end,
    [751] = function(playerObj)
        openMenu(costumeSelect.menu,playerObj,{
            character = playerObj.character,
            playerIdx = playerObj.idx,
        })
    end,
}

function onPostBlockHit(b,fromUpper,playerObj)
    if playerObj ~= nil and b:mem(0x56,FIELD_WORD) == 0 then
        local func = menuBlockFuncs[b.id]

        if func ~= nil then
            func(playerObj)
            playerObj.speedX = playerObj.speedX*0.25
        end
    end
end


function battleGeneral.onPlayerSelectFromPause()
    playerSelect.initialMenu:open({},1,player,false)
    battlePlayer.saveCharacters()
    battlePlayer.loadCharacters()
end

function battleGeneral.onMusicSelectFromPause()
    if onlinePlay.currentMode ~= onlinePlay.MODE_OFFLINE then
        musicSelect.menu:open({},1,Player(onlinePlay.playerIdx),false)
    else
        musicSelect.menu:open({},1,player,true)
    end
end

function onlinePlay.onDisconnect(playerIdx)
    if playerIdx == onlinePlay.playerIdx then
        battleMenu.closeAll()
        playerSelect.initialMenu:open({},1,player,false)
        --battlePlayer.saveCharacters()
        --battlePlayer.loadCharacters()
    end
end


function onDraw()
    --[[for _,p in ipairs(Player.get()) do
        if p.forcedState == FORCEDSTATE_PIPE then
            -- For some reason, Link is still in frame 15 when entering a pipe...
            local frame
            if p.character == CHARACTER_LINK and p.frame == 15 then
                frame = 1
            end

            p:render{frame = frame}
        end
    end]]
end