module Main where

import           Control.Monad.Reader  (ask, runReaderT)
import           Control.Monad.State   (get, runStateT, modify)
import           UI.NCurses            (Event(..), runCurses, defaultWindow, setEcho, setKeypad, getEvent)

import           RogueLike
import           RogueLike.Update
import           RogueLike.Update.Game
import           RogueLike.Update.Pickup
import           RogueLike.Update.Inventory
import           RogueLike.Render
import           RogueLike.Render.Game
import           RogueLike.Render.Pickup
import           RogueLike.Render.Inventory


main = runCurses $ do
    window <- defaultWindow
    setEcho False
    setKeypad window True
    let appConfig = AppConfig {window=window}
    runStateT (runReaderT renderGame appConfig) defaultGameState
    runStateT (runReaderT mainLoop appConfig) defaultGameState


mainLoop = do
    curGameState <- get
    appConfig <- ask
    event <- liftCurses $ getEvent (window appConfig) Nothing
    case event of
        Nothing                      -> mainLoop
        Just (EventCharacter 'q')    -> exitMainLoop
        Just event'                  -> do
            modify (updateDispatch event')
            gameState <- get
            renderDispatch appConfig gameState
            mainLoop
  where exitMainLoop = return ()


updateDispatch :: Event -> GameState -> GameState
updateDispatch event gameState =
    case gameMode gameState of
        GameMode      -> updateGame event gameState
        InventoryMode -> updateInventory event gameState
        PickupMode    -> updatePickup event gameState


renderDispatch :: AppConfig -> GameState -> App ()
renderDispatch appConfig gameState =
    case gameMode gameState of
        GameMode      -> renderGame
        InventoryMode -> renderInventory
        PickupMode    -> renderPickup
