{- |
Module      : RsiBreak.Widget.Settings
Copyright   : (c) Ruben Astudillo, 2023
License     : BSD-2
Maintainer  : ruben.astud@gmail.com

Composite for setting values and their modifications.
-}
module RsiBreak.Widget.Settings (
    handleEvent,
    buildUI,
) where

import Control.Lens (set)
import Monomer
import RsiBreak.Actions (storeSettingsOnConfigFile)
import RsiBreak.Model.Minutes (Minutes)
import RsiBreak.Model.Settings (TimerSetting (..), restInterval, workInterval)

data TimerChange = TSENewWorkTime Minutes | TSENewRestTime Minutes
    deriving (TimerChange -> TimerChange -> Bool
(TimerChange -> TimerChange -> Bool)
-> (TimerChange -> TimerChange -> Bool) -> Eq TimerChange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimerChange -> TimerChange -> Bool
== :: TimerChange -> TimerChange -> Bool
$c/= :: TimerChange -> TimerChange -> Bool
/= :: TimerChange -> TimerChange -> Bool
Eq, Minutes -> TimerChange -> ShowS
[TimerChange] -> ShowS
TimerChange -> String
(Minutes -> TimerChange -> ShowS)
-> (TimerChange -> String)
-> ([TimerChange] -> ShowS)
-> Show TimerChange
forall a.
(Minutes -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Minutes -> TimerChange -> ShowS
showsPrec :: Minutes -> TimerChange -> ShowS
$cshow :: TimerChange -> String
show :: TimerChange -> String
$cshowList :: [TimerChange] -> ShowS
showList :: [TimerChange] -> ShowS
Show)

data TimerSettingEvent = TimerChangeEvent TimerChange | TSENoOp
    deriving (TimerSettingEvent -> TimerSettingEvent -> Bool
(TimerSettingEvent -> TimerSettingEvent -> Bool)
-> (TimerSettingEvent -> TimerSettingEvent -> Bool)
-> Eq TimerSettingEvent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimerSettingEvent -> TimerSettingEvent -> Bool
== :: TimerSettingEvent -> TimerSettingEvent -> Bool
$c/= :: TimerSettingEvent -> TimerSettingEvent -> Bool
/= :: TimerSettingEvent -> TimerSettingEvent -> Bool
Eq, Minutes -> TimerSettingEvent -> ShowS
[TimerSettingEvent] -> ShowS
TimerSettingEvent -> String
(Minutes -> TimerSettingEvent -> ShowS)
-> (TimerSettingEvent -> String)
-> ([TimerSettingEvent] -> ShowS)
-> Show TimerSettingEvent
forall a.
(Minutes -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Minutes -> TimerSettingEvent -> ShowS
showsPrec :: Minutes -> TimerSettingEvent -> ShowS
$cshow :: TimerSettingEvent -> String
show :: TimerSettingEvent -> String
$cshowList :: [TimerSettingEvent] -> ShowS
showList :: [TimerSettingEvent] -> ShowS
Show)

handleEvent :: ep -> EventHandler TimerSetting TimerSettingEvent sp ep
handleEvent :: forall ep sp.
ep -> EventHandler TimerSetting TimerSettingEvent sp ep
handleEvent ep
_onChangeEvent WidgetEnv TimerSetting TimerSettingEvent
_wenv WidgetNode TimerSetting TimerSettingEvent
_node TimerSetting
_model TimerSettingEvent
TSENoOp = []
handleEvent ep
onChangeEvent WidgetEnv TimerSetting TimerSettingEvent
_wenv WidgetNode TimerSetting TimerSettingEvent
_node TimerSetting
model (TimerChangeEvent TimerChange
evt) =
    let newModel :: TimerSetting
newModel = case TimerChange
evt of
            TSENewWorkTime Minutes
newm -> ASetter TimerSetting TimerSetting Minutes Minutes
-> Minutes -> TimerSetting -> TimerSetting
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter TimerSetting TimerSetting Minutes Minutes
Lens' TimerSetting Minutes
workInterval Minutes
newm TimerSetting
model
            TSENewRestTime Minutes
newm -> ASetter TimerSetting TimerSetting Minutes Minutes
-> Minutes -> TimerSetting -> TimerSetting
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter TimerSetting TimerSetting Minutes Minutes
Lens' TimerSetting Minutes
restInterval Minutes
newm TimerSetting
model
     in [ TimerSetting -> EventResponse TimerSetting TimerSettingEvent sp ep
forall s e sp ep. s -> EventResponse s e sp ep
Model TimerSetting
newModel
        , ep -> EventResponse TimerSetting TimerSettingEvent sp ep
forall s e sp ep. ep -> EventResponse s e sp ep
Report ep
onChangeEvent
        , TaskHandler TimerSettingEvent
-> EventResponse TimerSetting TimerSettingEvent sp ep
forall s e sp ep. TaskHandler e -> EventResponse s e sp ep
Task (TimerSettingEvent
TSENoOp TimerSettingEvent -> IO () -> TaskHandler TimerSettingEvent
forall a b. a -> IO b -> IO a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ TimerSetting -> IO ()
storeSettingsOnConfigFile TimerSetting
newModel)
        ]

buildUI :: UIBuilder TimerSetting TimerSettingEvent
buildUI :: UIBuilder TimerSetting TimerSettingEvent
buildUI WidgetEnv TimerSetting TimerSettingEvent
_wenv TimerSetting
_model =
    [WidgetNode TimerSetting TimerSettingEvent]
-> WidgetNode TimerSetting TimerSettingEvent
forall (t :: * -> *) s e.
Traversable t =>
t (WidgetNode s e) -> WidgetNode s e
vstack
        [ [WidgetNode TimerSetting TimerSettingEvent]
-> WidgetNode TimerSetting TimerSettingEvent
forall (t :: * -> *) s e.
Traversable t =>
t (WidgetNode s e) -> WidgetNode s e
hstack
            [ Text -> WidgetNode TimerSetting TimerSettingEvent
forall s e. Text -> WidgetNode s e
label Text
"Work time: "
            , ALens' TimerSetting Minutes
-> [NumericFieldCfg TimerSetting TimerSettingEvent Minutes]
-> WidgetNode TimerSetting TimerSettingEvent
forall a e s.
(FormattableNumber a, WidgetEvent e) =>
ALens' s a -> [NumericFieldCfg s e a] -> WidgetNode s e
numericField_ ALens' TimerSetting Minutes
Lens' TimerSetting Minutes
workInterval [Minutes -> NumericFieldCfg TimerSetting TimerSettingEvent Minutes
forall t a. CmbMinValue t a => a -> t
minValue Minutes
0, Minutes -> NumericFieldCfg TimerSetting TimerSettingEvent Minutes
forall t a. CmbMaxValue t a => a -> t
maxValue Minutes
300, (Minutes -> TimerSettingEvent)
-> NumericFieldCfg TimerSetting TimerSettingEvent Minutes
forall t a e. CmbOnChange t a e => (a -> e) -> t
onChange (TimerChange -> TimerSettingEvent
TimerChangeEvent (TimerChange -> TimerSettingEvent)
-> (Minutes -> TimerChange) -> Minutes -> TimerSettingEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Minutes -> TimerChange
TSENewWorkTime)]
            ]
        , [WidgetNode TimerSetting TimerSettingEvent]
-> WidgetNode TimerSetting TimerSettingEvent
forall (t :: * -> *) s e.
Traversable t =>
t (WidgetNode s e) -> WidgetNode s e
hstack
            [ Text -> WidgetNode TimerSetting TimerSettingEvent
forall s e. Text -> WidgetNode s e
label Text
"Rest time: "
            , ALens' TimerSetting Minutes
-> [NumericFieldCfg TimerSetting TimerSettingEvent Minutes]
-> WidgetNode TimerSetting TimerSettingEvent
forall a e s.
(FormattableNumber a, WidgetEvent e) =>
ALens' s a -> [NumericFieldCfg s e a] -> WidgetNode s e
numericField_ ALens' TimerSetting Minutes
Lens' TimerSetting Minutes
restInterval [Minutes -> NumericFieldCfg TimerSetting TimerSettingEvent Minutes
forall t a. CmbMinValue t a => a -> t
minValue Minutes
0, Minutes -> NumericFieldCfg TimerSetting TimerSettingEvent Minutes
forall t a. CmbMaxValue t a => a -> t
maxValue Minutes
300, (Minutes -> TimerSettingEvent)
-> NumericFieldCfg TimerSetting TimerSettingEvent Minutes
forall t a e. CmbOnChange t a e => (a -> e) -> t
onChange (TimerChange -> TimerSettingEvent
TimerChangeEvent (TimerChange -> TimerSettingEvent)
-> (Minutes -> TimerChange) -> Minutes -> TimerSettingEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Minutes -> TimerChange
TSENewRestTime)]
            ]
        ]