{-# LANGUAGE OverloadedLists #-}

module Stage.Loader.Render
  ( updateBuffers
  , recordCommands
  ) where

import RIO

import RIO.State (gets)
import Vulkan.Core10 qualified as Vk

import Engine.Types qualified as Engine
import Engine.Vulkan.Pipeline qualified as Pipeline
import Engine.Vulkan.Swapchain qualified as Swapchain
import Engine.Worker qualified as Worker
import Render.Basic qualified as Basic
import Render.DescSets.Set0 qualified as Set0
import Render.Draw qualified as Draw
import Render.ForwardMsaa qualified as ForwardMsaa

import Stage.Loader.Types (FrameResources(..), RunState(..))
import Stage.Loader.UI qualified as UI

updateBuffers
  :: RunState
  -> FrameResources
  -> Basic.StageFrameRIO FrameResources RunState ()
updateBuffers RunState{..} FrameResources{..} = do
  Set0.observe rsSceneUiP frSceneUi
  UI.observe rsUI frUI

recordCommands
  :: Vk.CommandBuffer
  -> FrameResources
  -> Word32
  -> Basic.StageFrameRIO FrameResources RunState ()
recordCommands cb FrameResources{..} imageIndex = do
  (_context, Engine.Frame{fSwapchainResources, fRenderpass, fPipelines}) <- ask
  let Basic.Pipelines{..} = fPipelines

  ui <- mapRIO fst $ gets rsUI
  uiMessages <- traverse Worker.readObservedIO (UI.messages frUI)
  background <- Worker.readObservedIO (UI.background frUI)
  spinner <- Worker.readObservedIO (UI.spinner frUI)

  ForwardMsaa.usePass (Basic.rpForwardMsaa fRenderpass) imageIndex cb do
    Swapchain.setDynamicFullscreen cb fSwapchainResources

    Set0.withBoundSet0 frSceneUi pWireframe cb do
      -- Render UI
      Pipeline.bind cb pUnlitTexturedBlend do
        Draw.indexed cb (UI.quadUV ui) background
        Draw.indexed cb (UI.quadUV ui) spinner

      Pipeline.bind cb pEvanwSdf $
        traverse_ (Draw.quads cb) uiMessages
