local textplus = require("textplus")
local textFiles = require("scripts/textFiles")

local battleGeneral,battlePlayer,battleCamera
local battleStars,battleStone,battleItems,battleTimer,battleOptions,battleMap
local onlinePlay
local battleMenu
local booMushroom

local battleHUD = {}


battleHUD.HUD_ELEMENT = {
    STARS = 0,
    POINTS = 1,
}


battleHUD.normalPadding = 16

battleHUD.coinImage = Graphics.loadImageResolved("resources/hud/coin.png")
battleHUD.coinImagePadding = 8

battleHUD.starImage = Graphics.loadImageResolved("resources/hud/star.png")
battleHUD.starNeutralColor = Color(1,1,0.25)

battleHUD.stoneImage = Graphics.loadImageResolved("resources/hud/stone.png")

battleHUD.phantoImage = Graphics.loadImageResolved("resources/hud/phanto.png")

battleHUD.bombsImage = Graphics.loadImageResolved("resources/hud/bombs.png")
battleHUD.bombsImagePadding = 8

battleHUD.reserveBoxImage = Graphics.loadImageResolved("resources/hud/reserveBox.png")

battleHUD.countersGap = 4

battleHUD.priority = 6


battleHUD.spectatorBorderImage = Graphics.loadImageResolved("resources/hud/spectatorBorder.png")
battleHUD.spectatorBorderOpacity = 0.6

battleHUD.spectatorArrowsImage = Graphics.loadImageResolved("resources/hud/spectatorChangeArrows.png")
battleHUD.spectatorArrowsOffsetX = 8
battleHUD.spectatorArrowsOffsetY = -3

battleHUD.spectateBoxImage = Graphics.loadImageResolved("resources/hud/timerBox.png")
battleHUD.spectateBoxMarginX = 24
battleHUD.spectateBoxMarginY = 4
battleHUD.spectateBoxOffsetX = 16
battleHUD.spectateBoxOffsetY = 16

battleHUD.teamIconImages = {
    Graphics.loadImageResolved("resources/hud/teamIcon_alpha.png"),
    Graphics.loadImageResolved("resources/hud/teamIcon_bravo.png"),
}


battleHUD.modeElements = {}
battleHUD.modeDisplayTeams = {}


battleHUD.disabled = false
battleHUD.opacity = 1


local numberFont = textplus.loadFont("textplus/font/1.ini")
local mainFont = textplus.loadFont("resources/font/mainFont.ini")

local gradientReserveBoxShader
local maxGradientColors = 6

local layoutsCache = {}

local function getLayout(name,text,font,scale)
    local layoutData = layoutsCache[name]

    if layoutData == nil or layoutData[2] ~= text or layoutData[3] ~= font or layoutData[4] ~= scale then
        if layoutData == nil then
            layoutData = {}
            layoutsCache[name] = layoutData
        end

        -- Update layout
        layoutData[1] = textplus.layout(text,nil,{font = font,xscale = scale,yscale = scale,plaintext = true})
        layoutData[2] = text
        layoutData[3] = font
        layoutData[4] = scale
    end

    return layoutData[1]
end


local function drawCharacterHead(cam,p,x,y,direction)
    local image = battlePlayer.getPlayerHead(p.character)

    if direction == DIR_LEFT then
        x = x - image.width
    end

    battlePlayer.renderOutlinedPlayerHead{
        playerIdx = p.idx,priority = battleHUD.priority,
        outlineOpacity = (onlinePlay.currentMode ~= onlinePlay.MODE_OFFLINE and 0.5) or 0,
        color = Color.white.. battleHUD.opacity,

        x = x + image.width*0.5,
        y = y,
    }

    return 24*direction
end

local function drawCoins(cam,p,x,y,direction)
    local coinsForItem = battleItems.getCoinsForItem()
    local data = battlePlayer.getPlayerData(p)

    local coinImage = battleHUD.coinImage

    local textColor = Color.white*battleHUD.opacity

    local text = tostring(data.coins).. "/".. tostring(coinsForItem)
    local layout = getLayout("coins".. p.idx,text,numberFont,1)

    if direction == DIR_LEFT then
        -- Apply different pivot
        x = x - layout.width - coinImage.width - battleHUD.coinImagePadding
    end

    -- Coin icon
    Graphics.drawImageWP(coinImage,x,y - coinImage.height*0.5,battleHUD.opacity,battleHUD.priority)
    x = x + coinImage.width + battleHUD.coinImagePadding

    -- Text
    if data.itemGrantState ~= battleItems.GRANT_STATE.INACTIVE and data.itemGrantIsFromCoins then
        -- Bouncing
        y = y - math.abs(math.sin(lunatime.tick()/8))*6 + 2
    end

    textplus.render{
        layout = layout,priority = battleHUD.priority,
        color = textColor,smooth = false,

        x = math.floor(x + 0.5),
        y = math.floor(y - layout.height*0.5 + 2.5),
    }

    return coinImage.height + battleHUD.countersGap
end

local function drawReserveBox(cam,p,x,y,direction)
    local image = battleHUD.reserveBoxImage

    if direction == DIR_LEFT then
        x = x - image.width*0.5
    else
        x = x + image.width*0.5
    end

    y = y - image.height*0.5

    -- Item box itself
    local gradientColors = battlePlayer.getColorGradient(p.idx)
    local color,shader,uniforms

    if gradientColors ~= nil then
        if gradientReserveBoxShader == nil then
            gradientReserveBoxShader = Shader.fromFile(nil,"resources/playerGradient.frag",{MAX_COLORS = maxGradientColors})
        end

        color = Color.white.. battleHUD.opacity
        shader = gradientReserveBoxShader
        uniforms = {}

        uniforms.baseX = x
        uniforms.baseY = y
        uniforms.time = lunatime.drawtick()

        uniforms.colorCount = #gradientColors
        uniforms.colors = {}

        for colorIndex,color in ipairs(gradientColors) do
            uniforms.colors[colorIndex*3 - 2] = color.r
            uniforms.colors[colorIndex*3 - 1] = color.g
            uniforms.colors[colorIndex*3] = color.b
        end

        for colorIndex = (uniforms.colorCount*3 + 1),maxGradientColors*3 do
            uniforms.colors[colorIndex] = 0
        end
    else
        color = battlePlayer.getColor(p.idx).. battleHUD.opacity
    end

    Graphics.drawBox{
        texture = image,priority = battleHUD.priority,centred = true,
        x = x,y = y,

        color = color,shader = shader,uniforms = uniforms,
    }

    -- Reserve item
    if p.reservePowerup > 0 then
        local npcImage = Graphics.sprites.npc[p.reservePowerup].img
        local config = NPC.config[p.reservePowerup]

        local width = config.gfxwidth
        local height = config.gfxheight

        if width == 0 or height == 0 then
            width = config.width
            height = config.height
        end

        Graphics.drawImageWP(npcImage,x - width*0.5,y - height*0.5,0,0,width,height,battleHUD.opacity,battleHUD.priority)
    end
end

local function drawBombs(cam,p,x,y,direction)
    local data = battlePlayer.getPlayerData(p)

    local textColor = Color.white*battleHUD.opacity

    local text = tostring(data.bombs)
    local layout = getLayout("bombs".. p.idx,text,numberFont,1)

    if direction == DIR_LEFT then
        -- Apply different pivot
        x = x - layout.width - battleHUD.bombsImage.width - battleHUD.bombsImagePadding
    end

    -- Bombs icon
    Graphics.drawImageWP(battleHUD.bombsImage,x,y - battleHUD.bombsImage.height*0.5,battleHUD.opacity,battleHUD.priority)
    x = x + battleHUD.bombsImage.width + battleHUD.bombsImagePadding

    -- Text
    textplus.render{
        layout = layout,priority = battleHUD.priority,
        color = textColor,smooth = false,

        x = math.floor(x + 0.5),
        y = math.floor(y - layout.height*0.5 + 4.5),
    }

    return battleHUD.bombsImage.height + battleHUD.countersGap
end


-- Functions to draw specific HUD elements
local playerElementDrawFuncs = {}
local teamElementDrawFuncs = {}

do
    -- Drawing stars for players
    playerElementDrawFuncs[battleHUD.HUD_ELEMENT.STARS] = function(cam,p,x,y,direction)
        local max = battleStars.getStarsToWin()

        if max <= 0 then
            return x
        end

        local data = battlePlayer.getPlayerData(p)
        local starImage = battleHUD.starImage

        if data.stars <= 0 then
            return x
        end

        -- What could should it be?
        local iconColor = battlePlayer.getColor(p.idx):lerp(Color.lightgrey,0.25).. battleHUD.opacity

        if data.stars == (max - 1) then
            -- Flash!
            iconColor = iconColor:lerp(Color.white,0.25 + 0.25*math.abs(math.sin(lunatime.tick()*math.pi/16)))
        end

        -- Draw stars
        local offset = (direction == DIR_LEFT and -starImage.width) or 0

        for i = 1,data.stars do
            local hopOffset = 0

            if data.stars == (max - 1) then
                local hopDelay = 5
                local hopTimer = math.max(0,math.min(1,((lunatime.tick() - i*hopDelay) % ((data.stars + 1)*hopDelay + 32))/16))

                hopOffset = math.abs(math.sin(hopTimer*math.pi))*6
            end

            Graphics.drawBox{
                texture = starImage,priority = battleHUD.priority,
                color = iconColor,

                x = x + offset,y = y - starImage.height*0.5 - hopOffset,
            }

            x = x + (starImage.width + 2)*direction
        end

        return x + 8*direction
    end

    -- Drawing points for players
    local perlinRNG = RNG.perlin{amp = 1, wl = 3, oct = 3, per = 0.5, mod = 2} -- definitely not stolen from handycam's trauma code. nuh-uh. no way.

    playerElementDrawFuncs[battleHUD.HUD_ELEMENT.POINTS] = function(cam,p,x,y,direction)
        local data = battlePlayer.getPlayerData(p)

        local text = tostring(data.points)
        local layout = getLayout("points".. p.idx,text,numberFont,1)

        local textColor = battlePlayer.getColor(p.idx):lerp(Color.white,0.8)*battleHUD.opacity

        if p.idx == battleStone.holdingPlayerIdx then
            -- Bouncing
            y = y - math.abs(math.sin(lunatime.tick()/8))*6 + 2
        end

        y = y - math.sin(data.pointsHopTimer*math.pi)*6

        local shakeX = (perlinRNG:get(lunatime.tick()*0.872)*2 - 1)*data.pointsShakeFactor
        local shakeY = (perlinRNG:get(lunatime.tick()*0.991)*2 - 1)*data.pointsShakeFactor

        local offset = (direction == DIR_LEFT and -layout.width) or 0

        textplus.render{
            layout = layout,priority = battleHUD.priority,
            color = textColor,smooth = false,

            x = math.floor(x + shakeX + offset + 0.5),
            y = math.floor(y + shakeY - layout.height*0.5 + 2.5),
        }

        return x + 8*direction
    end

    -- Drawing points for teams
    teamElementDrawFuncs[battleHUD.HUD_ELEMENT.POINTS] = function(cam,teamIdx,x,y,direction)
        local text = tostring(battlePlayer.teamPoints[teamIdx])
        local layout = getLayout("teamPoints".. teamIdx,text,numberFont,1)

        local textColor = battleGeneral.teamColors[teamIdx]:lerp(Color.white,0.8)*battleHUD.opacity

        if teamIdx == battlePlayer.getTeam(battleStone.holdingPlayerIdx) then
            -- Bouncing
            y = y - math.abs(math.sin(lunatime.tick()/8))*6 + 2
        end

        local offset = (direction == DIR_LEFT and -layout.width) or 0

        textplus.render{
            layout = layout,priority = battleHUD.priority,
            color = textColor,smooth = false,

            x = math.floor(x + offset + 0.5),
            y = math.floor(y - layout.height*0.5 + 2.5),
        }

        return x + 8*direction
    end
end


local function drawPlayer(cam,p,x,y,direction)
    local data = battlePlayer.getPlayerData(p)

    y = y + 12

    -- Lives/character head
    local headCount = 1
    if data.lives >= 0 then
        headCount = data.lives
    end

    for i = 1,headCount do
        x = x + drawCharacterHead(cam,p,x,y,direction)
    end

    x = x + 12*direction

    -- Elements
    if battleHUD.modeElements[battleGeneral.mode] ~= nil then
        for _,element in ipairs(battleHUD.modeElements[battleGeneral.mode]) do
            if playerElementDrawFuncs[element] ~= nil then
                x = playerElementDrawFuncs[element](cam,p,x,y,direction) or x
            end
        end
    end
end

local function drawTeam(cam,teamIdx,x,y,direction)
    local teamIcon = battleHUD.teamIconImages[teamIdx]

    x = x + 12*direction
    y = y + 12

    Graphics.drawImageWP(teamIcon,x - teamIcon.width*0.5,y - teamIcon.height*0.5,battleHUD.opacity,battleHUD.priority)

    x = x + 24*direction

    -- Elements
    if battleHUD.modeElements[battleGeneral.mode] ~= nil then
        for _,element in ipairs(battleHUD.modeElements[battleGeneral.mode]) do
            if teamElementDrawFuncs[element] ~= nil then
                x = teamElementDrawFuncs[element](cam,teamIdx,x,y,direction) or x
            end
        end
    end
end


local function limitedLivesAreBeingUsed()
    local modeRuleset = battleOptions.getModeRuleset()

    return (modeRuleset.lives ~= nil and modeRuleset.lives > 0)
end

local function getPlayersOnHUD(camIdx)
    if battleGeneral.isInHub then
        return {},{}
    end

    -- In local play, just display this camera's players since split screen is a thing
    if onlinePlay.currentMode == onlinePlay.MODE_OFFLINE then
        if battleCamera.splitMode == battleCamera.SPLIT_MODE.VERTICAL then
            if camIdx == 1 then
                return {Player(1)},{}
            else
                return {},{Player(2)}
            end
        elseif battleCamera.splitMode == battleCamera.SPLIT_MODE.HORIZONTAL then
            return {Player(camIdx)},{}
        end

        if battleGeneral.disableSplitScreen and battleGeneral.gameData.playerCount > 1 then
            return {Player(1)},{Player(2)}
        end

        return {Player(1)},{}
    end

    -- Split up by teams
    if battlePlayer.teamsAreEnabled() then
        -- If there is no reason to display players on the HUD, don't
        if battleHUD.modeDisplayTeams[battleGeneral.mode] and not limitedLivesAreBeingUsed() then
            return {},{}
        end

        -- Our own team is on the left, the opposing team is on the right
        local ownTeam = battlePlayer.getTeam(onlinePlay.playerIdx)
        local leftPlayers = {}
        local rightPlayers = {}

        if ownTeam == 0 then
            ownTeam = 1
        end

        for _,p in ipairs(battlePlayer.getActivePlayers()) do
            if p.idx == onlinePlay.playerIdx then
                table.insert(leftPlayers,1,p)
            elseif battlePlayer.getTeam(p.idx) == ownTeam then
                table.insert(leftPlayers,p)
            else
                table.insert(rightPlayers,p)
            end
        end

        return leftPlayers,rightPlayers
    end

    -- Online, display active players, but with our player first
    local leftPlayers = {}
    local rightPlayers = {}
    local onRight = true

    for _,p in ipairs(battlePlayer.getActivePlayers()) do
        if p.idx ~= onlinePlay.playerIdx then
            if onRight then
                table.insert(rightPlayers,p)
            else
                table.insert(leftPlayers,p)
            end

            onRight = not onRight
        else
            table.insert(leftPlayers,1,p)
        end
    end

    return leftPlayers,rightPlayers
end

local function generalDrawForOne(camIdx,onRight)
    local cam = Camera(camIdx)

    local leftX = battleHUD.normalPadding
    local rightX = cam.width - battleHUD.normalPadding

    local leftY = battleHUD.normalPadding
    local rightY = leftY

    -- Draw team elements
    local hasTeamHUD = (battlePlayer.teamsAreEnabled() and battleHUD.modeDisplayTeams[battleGeneral.mode])

    if hasTeamHUD then
        drawTeam(cam,1,leftX,leftY,DIR_RIGHT)
        drawTeam(cam,2,rightX,rightY,DIR_LEFT)

        leftY = leftY + 32
        rightY = rightY + 32
    end

    -- Draw per-player elements
    --local rightPlayers = {player}
    --local leftPlayers = {player,player,player,player,player,player,player,player,player}
    local leftPlayers,rightPlayers = getPlayersOnHUD(camIdx)

    if #leftPlayers > 0 then
        for _,p in ipairs(leftPlayers) do
            drawPlayer(cam,p,leftX,leftY,DIR_RIGHT)
            leftY = leftY + 28
        end

        leftY = leftY + 8
    elseif not hasTeamHUD then
        leftY = leftY + 8
    end

    if #rightPlayers > 0 then
        for _,p in ipairs(rightPlayers) do
            drawPlayer(cam,p,rightX,rightY,DIR_LEFT)
            rightY = rightY + 28
        end

        rightY = rightY + 8
    elseif not hasTeamHUD then
        rightY = rightY + 8
    end


    local mainPlayer = battleCamera.getCamerasPlayers(camIdx)[1]

    -- Coins
    if battleItems.getCoinsForItem() > 0 then
        if onRight then
            rightY = rightY + drawCoins(cam,mainPlayer,rightX,rightY,-1)
        else
            leftY = leftY + drawCoins(cam,mainPlayer,leftX,leftY,1)
        end
    end

    -- Bombs
    if battleBombs.shouldDisplayBombs(mainPlayer) then
        if onRight then
            rightY = rightY + drawBombs(cam,mainPlayer,rightX,rightY,-1)
        else
            leftY = leftY + drawBombs(cam,mainPlayer,leftX,leftY,1)
        end
    end

    -- Reserve box
    local bottomY = cam.height - battleHUD.normalPadding

    if battleItems.playerHasReserveBox(mainPlayer) then
        if onRight then
            drawReserveBox(cam,mainPlayer,rightX,bottomY,-1)
        else
            drawReserveBox(cam,mainPlayer,leftX,bottomY,1)
        end

        --bottomY = bottomY - battleHUD.reserveBoxImage.height - battleHUD.normalPadding
    end
end


local function drawSpectatorBorder(camIdx,color)
    local cam = Camera(camIdx)

    local image = battleHUD.spectatorBorderImage

    local vertexCoords = {}
    local textureCoords = {}
    local vertexCounter = 0

    for i = 1,4 do
        -- Vertex coords
        local x1,y1,x2,y2

        if i == 1 then
            x1 = 0
            y1 = 0
            x2 = cam.width - image.width
            y2 = image.height
        elseif i == 2 then
            x1 = cam.width
            y1 = 0
            x2 = x1 - image.width
            y2 = cam.height - image.height
        elseif i == 3 then
            x1 = cam.width
            y1 = cam.height
            x2 = image.width
            y2 = y1 - image.height
        else
            x1 = 0
            y1 = cam.height
            x2 = image.width
            y2 = image.height
        end

        vertexCoords[vertexCounter+1 ] = x1 -- top left
        vertexCoords[vertexCounter+2 ] = y1
        vertexCoords[vertexCounter+3 ] = x2 -- top right
        vertexCoords[vertexCounter+4 ] = y1
        vertexCoords[vertexCounter+5 ] = x1 -- bottom left
        vertexCoords[vertexCounter+6 ] = y2
        vertexCoords[vertexCounter+7 ] = x2 -- top right
        vertexCoords[vertexCounter+8 ] = y1
        vertexCoords[vertexCounter+9 ] = x1 -- bottom left
        vertexCoords[vertexCounter+10] = y2
        vertexCoords[vertexCounter+11] = x2 -- bottom right
        vertexCoords[vertexCounter+12] = y2

        -- Texture coords
        local tx1 = 0
        local ty1 = 0
        local tx2 = math.abs(x2 - x1)/image.width
        local ty2 = math.abs(y2 - y1)/image.height

        textureCoords[vertexCounter+1 ] = tx1 -- top left
        textureCoords[vertexCounter+2 ] = ty1
        textureCoords[vertexCounter+3 ] = tx2 -- top right
        textureCoords[vertexCounter+4 ] = ty1
        textureCoords[vertexCounter+5 ] = tx1 -- bottom left
        textureCoords[vertexCounter+6 ] = ty2
        textureCoords[vertexCounter+7 ] = tx2 -- top right
        textureCoords[vertexCounter+8 ] = ty1
        textureCoords[vertexCounter+9 ] = tx1 -- bottom left
        textureCoords[vertexCounter+10] = ty2
        textureCoords[vertexCounter+11] = tx2 -- bottom right
        textureCoords[vertexCounter+12] = ty2

        vertexCounter = vertexCounter + 12
    end

    Graphics.glDraw{
        texture = image,
        color = color,
        priority = 2,
        vertexCoords = vertexCoords,
        textureCoords = textureCoords,
    }
end

local function drawSpectatorThings(camIdx)
    local cam = Camera(camIdx)

    -- Draw border
    local spectatedPlayer = Player(battleCamera.onlineFollowedPlayerIdx)

    local playerColor = battlePlayer.getColor(spectatedPlayer.idx)
    local playerName = battlePlayer.getName(spectatedPlayer.idx)

    drawSpectatorBorder(camIdx,playerColor.. battleHUD.spectatorBorderOpacity*battleHUD.opacity)

    -- Layout stuff
    local namePrefixLayout = getLayout("spectateNamePrefix",textFiles.hud.spectateNamePrefix,mainFont,2)
    local nameLayout = getLayout("spectateName",playerName,mainFont,2)

    local boxMainWidth = math.max(namePrefixLayout.width,battleGeneral.usernameMaxWidth,nameLayout.width)
    local boxMainHeight = namePrefixLayout.height + nameLayout.height
    local boxFullWidth = boxMainWidth + battleHUD.spectateBoxMarginX*2
    local boxFullHeight = boxMainHeight + battleHUD.spectateBoxMarginY*2

    local boxFullX = cam.width - boxFullWidth - battleHUD.spectateBoxOffsetX
    local boxFullY = cam.height - boxFullHeight - battleHUD.spectateBoxOffsetY
    local boxMainX = boxFullX + battleHUD.spectateBoxMarginX
    local boxMainY = boxFullY + battleHUD.spectateBoxMarginY

    -- Draw box
    battleMenu.drawSegmentedBox{
        texture = battleHUD.spectateBoxImage,priority = battleHUD.priority,
        color = Color.white.. battleHUD.opacity,

        width = boxFullWidth,height = boxFullHeight,
        x = boxFullX,y = boxFullY,
    }

    -- Name prefix
    textplus.render{
        layout = namePrefixLayout,priority = battleHUD.priority,
        color = Color.lightgrey*battleHUD.opacity,

        x = math.floor(boxMainX + (boxMainWidth - namePrefixLayout.width)*0.5 + 0.5),
        y = math.floor(boxMainY + 0.5),
    }

    -- Target name
    textplus.render{
        layout = nameLayout,priority = battleHUD.priority,
        color = playerColor*battleHUD.opacity,

        x = math.floor(boxMainX + (boxMainWidth - nameLayout.width)*0.5 + 0.5),
        y = math.floor(boxMainY + namePrefixLayout.height + 0.5),
    }

    -- Arrows
    if battlePlayer.getActivePlayerCount() <= 1 then
        return
    end

    local arrowImage = battleHUD.spectatorArrowsImage
    local arrowWidth = arrowImage.width*0.5
    local arrowHeight = arrowImage.height

    local arrowY = boxMainY + namePrefixLayout.height + nameLayout.height*0.5 + battleHUD.spectatorArrowsOffsetY

    for i = 0,1 do
        local direction = i*2 - 1
        local movementOffset = math.abs(math.sin(lunatime.tick()/16))*6

        local arrowX = boxMainX + boxMainWidth*0.5 + (nameLayout.width*0.5 + movementOffset + battleHUD.spectatorArrowsOffsetX)*direction

        Graphics.drawBox{
            texture = arrowImage,priority = battleHUD.priority,
            color = Color.white.. battleHUD.opacity,
            centred = true,

            sourceWidth = arrowWidth,sourceHeight = arrowHeight,
            sourceX = i*arrowWidth,sourceY = 0,
            x = arrowX,y = arrowY,
        }
    end
end


local function drawMap(camIdx)
    local cam = Camera(camIdx)

    local screenWidth,screenHeight = battleGeneral.getScreenSize()

    local sectionIdx,mapsShared = battleMap.getSection(camIdx)

    local x = screenWidth - battleHUD.normalPadding
    local y = screenHeight - battleHUD.normalPadding
    local alignX = 1
    local alignY = 1

    if battleCamera.splitMode == battleCamera.SPLIT_MODE.VERTICAL then
        y = y - cam.renderY

        if mapsShared then
            x = screenWidth*0.5 - cam.renderX
            alignX = 0.5
        elseif camIdx == 1 then
            x = cam.width - battleHUD.normalPadding
            alignX = 1
        else
            x = battleHUD.normalPadding
            alignX = 0
        end
    elseif battleCamera.splitMode == battleCamera.SPLIT_MODE.HORIZONTAL then
        x = x - cam.renderX

        if mapsShared then
            y = screenHeight*0.5 - cam.renderY
            alignY = 0.5
        elseif camIdx == 1 then
            y = camera.height - battleHUD.normalPadding
            alignY = 1
        else
            y = battleHUD.normalPadding
            alignY = 0
        end
    end

    battleMap.draw(sectionIdx,battleHUD.priority,battleHUD.opacity,x,y,alignX,alignY)
end


function battleHUD.draw(camIdx)
    if battleHUD.opacity <= 0 or battleHUD.disabled then
        return
    end

    local onRight = (camIdx == 2 and battleCamera.splitMode == battleCamera.SPLIT_MODE.VERTICAL)

    if battleCamera.isSpectating then
        drawSpectatorThings(camIdx)
    end

    generalDrawForOne(camIdx,onRight)

    if not battleCamera.isSpectating and not battleGeneral.disableMap then
        drawMap(camIdx)
    end

    battleTimer.draw(camIdx)
end


function battleHUD.onInitAPI()
    battleGeneral = require("scripts/battleGeneral")
    battlePlayer = require("scripts/battlePlayer")
    battleCamera = require("scripts/battleCamera")
    battleStars = require("scripts/battleStars")
    battleStone = require("scripts/battleStone")
    battleItems = require("scripts/battleItems")
    battleBombs = require("scripts/battleBombs")
    battleTimer = require("scripts/battleTimer")
    battleOptions = require("scripts/battleOptions")
    battleMap = require("scripts/battleMap")

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

    booMushroom = require("scripts/booMushroom")


    battleHUD.mapSize = battleMap.size -- for compatability reasons


    -- Set up mode-specific properties
    battleHUD.modeElements[battleGeneral.gameMode.STARS] = {battleHUD.HUD_ELEMENT.STARS}

    battleHUD.modeElements[battleGeneral.gameMode.STONE] = {battleHUD.HUD_ELEMENT.POINTS}
    battleHUD.modeDisplayTeams[battleGeneral.gameMode.STONE] = true

    battleHUD.modeElements[battleGeneral.gameMode.PHANTO] = {battleHUD.HUD_ELEMENT.POINTS}
    battleHUD.modeDisplayTeams[battleGeneral.gameMode.PHANTO] = true

    battleHUD.modeElements[battleGeneral.gameMode.BOMBS] = {battleHUD.HUD_ELEMENT.POINTS}
    battleHUD.modeDisplayTeams[battleGeneral.gameMode.BOMBS] = true
end


return battleHUD