mainLoopConfig ::
    MkProperty IO o EventMapHelp.IsHelpShown ->
    (Zoom -> IO (Fonts Font)) -> IO (Config ModKey, Theme, Language) -> MainConfig.Config
mainLoopConfig helpProp getFonts getConfig =
    MainConfig.Config
    { _cAnim =
        getConfig <&> (^. _2)
        <&> \theme ->
        Anim.Config
        { _acTimePeriod = theme ^. Theme.animationTimePeriodSec & realToFrac
        , _acRemainingRatioInPeriod = theme ^. Theme.animationRemainInPeriod
        , _acSpiral = Anim.SpiralAnimConf 0 0
        }
    , _cCursor =
        \zoom ->
        (,) <$> getFonts zoom <*> (getConfig <&> (^. _2))
        <&> \(fonts, theme) ->
        Cursor.Config
        { cursorColor = theme ^. Theme.cursorColor
        , Cursor.decay = Just Cursor.Decay
            { Cursor.heightUnit = fonts ^. Fonts.base & Font.height
            , Cursor.heightExponent = theme ^. Theme.cursorDecayExponent
            }
        }
    , _cZoom = getConfig <&> (^. _1 . Config.zoom)
    , _cPostProcess =
        \zoom size widget ->
        Property.getP helpProp
        >>= \case
        HelpNotShown -> pure widget
        HelpShown ->
            do
                helpFont <- getFonts zoom <&> (^. Fonts.help)
                (config, theme, language) <- getConfig
                addHelp config theme language helpFont size widget & pure
    , _cInvalidCursorOverlayColor =
        getConfig <&> (^. _2)
        <&> \theme ->
        theme ^. Theme.invalidCursorOverlayColor
    }
mainLoopConfig ::
    MkProperty IO o EventMapHelp.IsHelpShown ->
    (Zoom -> IO (Fonts Font)) -> IO (Config ModKey, Theme, Language) -> MainConfig.Config
mainLoopConfig helpProp getFonts getConfig =
    MainConfig.Config
    { _cAnim =
        getConfig <&> (^. _2)
        <&> \theme ->
        Anim.Config
        { _acTimePeriod = theme ^. Theme.animationTimePeriodSec & realToFrac
        , _acRemainingRatioInPeriod = theme ^. Theme.animationRemainInPeriod
        , _acSpiral = Anim.SpiralAnimConf 0 0
        }
    , _cCursor =
        \zoom ->
        (,) <$> getFonts zoom <*> (getConfig <&> (^. _2))
        <&> \(fonts, theme) ->
        Cursor.Config
        { cursorColor = theme ^. Theme.cursorColor
        , Cursor.decay = Just Cursor.Decay
            { Cursor.heightUnit = fonts ^. Fonts.base & Font.height
            , Cursor.heightExponent = theme ^. Theme.cursorDecayExponent
            }
        }
    , _cZoom = getConfig <&> (^. _1 . Config.zoom)
    , _cPostProcess =
        \zoom size widget ->
        Property.getP helpProp
        >>= \case
        HelpNotShown -> pure widget
        HelpShown ->
            do
                helpFont <- getFonts zoom <&> (^. Fonts.help)
                (config, theme, language) <- getConfig
                addHelp config theme language helpFont size widget & pure
    , _cInvalidCursorOverlayColor =
        getConfig <&> (^. _2)
        <&> \theme ->
        theme ^. Theme.invalidCursorOverlayColor
    }
mainLoopConfig helpProp getFonts getConfig =
    MainConfig.Config
    { _cAnim =
        getConfig <&> (^. _2)
        <&> \theme ->
        Anim.Config
        { _acTimePeriod = theme ^. Theme.animationTimePeriodSec & realToFrac
        , _acRemainingRatioInPeriod = theme ^. Theme.animationRemainInPeriod
        , _acSpiral = Anim.SpiralAnimConf 0 0
        }
    , _cCursor =
        \zoom ->
        (,) <$> getFonts zoom <*> (getConfig <&> (^. _2))
        <&> \(fonts, theme) ->
        Cursor.Config
        { cursorColor = theme ^. Theme.cursorColor
        , Cursor.decay = Just Cursor.Decay
            { Cursor.heightUnit = fonts ^. Fonts.base & Font.height
            , Cursor.heightExponent = theme ^. Theme.cursorDecayExponent
            }
        }
    , _cZoom = getConfig <&> (^. _1 . Config.zoom)
    , _cPostProcess =
        \zoom size widget ->
        Property.getP helpProp
        >>= \case
        HelpNotShown -> pure widget
        HelpShown ->
            do
                helpFont <- getFonts zoom <&> (^. Fonts.help)
                (config, theme, language) <- getConfig
                addHelp config theme language helpFont size widget & pure
    , _cInvalidCursorOverlayColor =
        getConfig <&> (^. _2)
        <&> \theme ->
        theme ^. Theme.invalidCursorOverlayColor
    }