module StateManagement where
import Brick
import Control.Monad.IO.Class
import Data.Maybe (fromJust)
import Lens.Micro.Platform
import Recents
import States hiding (cardState)
import Stack hiding (head)
import qualified Brick.Widgets.List as L
import qualified Data.Vector as Vec
import qualified Data.Map.Strict as M
import qualified Stack
getMode :: State -> Mode
getMode (MainMenuState _) = MainMenu
getMode (SettingsState _) = Settings
getMode (InfoState _) = Info
getMode (CardSelectorState _) = CardSelector
getMode (FileBrowserState _) = FileBrowser
getMode (CardsState _) = Cards
getMode (ParameterState _) = Parameter
getState :: GlobalState -> State
getState = fromJust . safeGetState
updateState :: GlobalState -> State -> GlobalState
updateState gs s = gs & states %~ M.insert (getMode s) s
updateMMS :: GlobalState -> MMS -> GlobalState
updateMMS gs s = updateState gs (MainMenuState s)
updateSS :: GlobalState -> SS -> GlobalState
updateSS gs s = updateState gs (SettingsState s)
updateIS :: GlobalState -> IS -> GlobalState
updateIS gs s = updateState gs (InfoState s)
updateCS :: GlobalState -> CS -> GlobalState
updateCS gs s = updateState gs (CardsState s)
updateCSS :: GlobalState -> CSS -> GlobalState
updateCSS gs s = updateState gs (CardSelectorState s)
updateInfo :: GlobalState -> IS -> GlobalState
updateInfo gs s = updateState gs (InfoState s)
updateFBS :: GlobalState -> FBS -> GlobalState
updateFBS gs s = updateState gs (FileBrowserState s)
updatePS :: GlobalState -> PS -> GlobalState
updatePS gs s = updateState gs (ParameterState s)
goToState :: GlobalState -> State -> GlobalState
goToState gs s = gs & states %~ M.insert (getMode s) s
& stack %~ insert (getMode s)
moveToState :: GlobalState -> State -> GlobalState
moveToState gs = goToState (popState gs)
removeToState :: GlobalState -> State -> GlobalState
removeToState gs s = go (popState gs)
where go global =
let current = Stack.head (global ^. stack)
in if current == getMode s then moveToState global s
else go (popState global)
popState :: GlobalState -> GlobalState
popState gs = let
s = gs ^. stack
top = Stack.head s
s' = Stack.pop s in
gs & states %~ M.delete top
& stack .~ s'
popStateOrQuit :: GlobalState -> EventM n (Next GlobalState)
popStateOrQuit gs = let gs' = popState gs in
if Stack.size (gs' ^. stack) == 0
then halt gs'
else continue gs'
safeGetState :: GlobalState -> Maybe State
safeGetState gs = do
key <- safeHead (gs ^. stack)
M.lookup key (gs ^. states)
goToModeOrQuit :: GlobalState -> Mode -> EventM n (Next GlobalState)
goToModeOrQuit gs mode =
maybe (halt gs) (continue . goToState gs) $ M.lookup mode (gs ^. states)
moveToModeOrQuit :: GlobalState -> Mode -> EventM n (Next GlobalState)
moveToModeOrQuit = moveToModeOrQuit' return
moveToModeOrQuit' :: (State -> IO State) -> GlobalState -> Mode -> EventM n (Next GlobalState)
moveToModeOrQuit' f gs mode =
maybe (halt gs) (\s -> continue . moveToState gs =<< liftIO (f s)) $ M.lookup mode (gs ^. states)
removeToModeOrQuit :: GlobalState -> Mode -> EventM n (Next GlobalState)
removeToModeOrQuit = removeToModeOrQuit' return
removeToModeOrQuit' :: (State -> IO State) -> GlobalState -> Mode -> EventM n (Next GlobalState)
removeToModeOrQuit' f gs mode =
maybe (halt gs) (\s -> continue . removeToState gs =<< liftIO (f s)) $ M.lookup mode (gs ^. states)
refreshRecents :: CSS -> IO CSS
refreshRecents s = do
rs <- getRecents
let prettyRecents = shortenFilepaths (toList rs)
options = Vec.fromList (prettyRecents ++ ["Select file from system"])
return $ s & recents .~ rs
& list .~ L.list Ordinary options 1
refreshRecents' :: GlobalState -> IO GlobalState
refreshRecents' gs = maybe (return gs) ((updateCSS gs <$>) . refreshRecents) ((\(CardSelectorState s) -> s) <$> M.lookup CardSelector (gs^.states))