{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}

module Monomer.SaveManager.SaveManagerCfg
    ( -- * Configuration
      Saves
    , SaveManagerCfg(..)
    , onSavesChange
    , onSavesChangeReq
    , captionMethod
    , noConfirm
    , noConfirm_
    ) where

import Control.Applicative ((<|>))
import Data.Default
import Data.Sequence (Seq)
import Data.Text (Text)
import Data.Time.LocalTime (ZonedTime)
import Monomer.Core
import Monomer.Core.Combinators

type Saves a = Seq (a, Text)

{-|
Configuration options for saveManager:

- 'onFocus': event to raise when focus is received.
- 'onFocusReq': 'WidgetRequest' to generate when focus is received.
- 'onBlur': event to raise when focus is lost.
- 'onBlurReq': 'WidgetRequest' to generate when focus is lost.
- 'onChange': event to raise when the value changes.
- 'onChangeReq': 'WidgetRequest' to generate when the value changes.
- 'onSavesChange': event to raise when the saves change.
- 'onSavesChangeReq': 'WidgetRequest' to generate when the saves change.
- 'captionMethod': function to generate the caption for the slot.
- 'noConfirm': don't show confirmation dialog.
-}
data SaveManagerCfg s e a = SaveManagerCfg
    { forall s e a. SaveManagerCfg s e a -> [Path -> WidgetRequest s e]
_smcOnFocusReq :: [Path -> WidgetRequest s e]
    , forall s e a. SaveManagerCfg s e a -> [Path -> WidgetRequest s e]
_smcOnBlurReq :: [Path -> WidgetRequest s e]
    , forall s e a. SaveManagerCfg s e a -> [a -> WidgetRequest s e]
_smcOnChangeReq :: [a -> WidgetRequest s e]
    , forall s e a.
SaveManagerCfg s e a -> [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq :: [Saves a -> WidgetRequest s e]
    , forall s e a.
SaveManagerCfg s e a -> Maybe (a -> ZonedTime -> Text)
_smcCaptionMethod :: Maybe (a -> ZonedTime -> Text)
    , forall s e a. SaveManagerCfg s e a -> Maybe Bool
_smcNoConfirm :: Maybe Bool
    }

instance Default (SaveManagerCfg s e a) where
    def :: SaveManagerCfg s e a
def = SaveManagerCfg
        { _smcOnFocusReq :: [Path -> WidgetRequest s e]
_smcOnFocusReq = []
        , _smcOnBlurReq :: [Path -> WidgetRequest s e]
_smcOnBlurReq = []
        , _smcOnChangeReq :: [a -> WidgetRequest s e]
_smcOnChangeReq = []
        , _smcOnSavesChangeReq :: [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq = []
        , _smcCaptionMethod :: Maybe (a -> ZonedTime -> Text)
_smcCaptionMethod = forall a. Maybe a
Nothing
        , _smcNoConfirm :: Maybe Bool
_smcNoConfirm = forall a. Maybe a
Nothing
        }

instance Semigroup (SaveManagerCfg s e a) where
    <> :: SaveManagerCfg s e a
-> SaveManagerCfg s e a -> SaveManagerCfg s e a
(<>) SaveManagerCfg s e a
a1 SaveManagerCfg s e a
a2 = forall a. Default a => a
def
        { _smcOnFocusReq :: [Path -> WidgetRequest s e]
_smcOnFocusReq = forall s e a. SaveManagerCfg s e a -> [Path -> WidgetRequest s e]
_smcOnFocusReq SaveManagerCfg s e a
a1 forall a. Semigroup a => a -> a -> a
<> forall s e a. SaveManagerCfg s e a -> [Path -> WidgetRequest s e]
_smcOnFocusReq SaveManagerCfg s e a
a2
        , _smcOnBlurReq :: [Path -> WidgetRequest s e]
_smcOnBlurReq = forall s e a. SaveManagerCfg s e a -> [Path -> WidgetRequest s e]
_smcOnBlurReq SaveManagerCfg s e a
a1 forall a. Semigroup a => a -> a -> a
<> forall s e a. SaveManagerCfg s e a -> [Path -> WidgetRequest s e]
_smcOnBlurReq SaveManagerCfg s e a
a2
        , _smcOnChangeReq :: [a -> WidgetRequest s e]
_smcOnChangeReq = forall s e a. SaveManagerCfg s e a -> [a -> WidgetRequest s e]
_smcOnChangeReq SaveManagerCfg s e a
a1 forall a. Semigroup a => a -> a -> a
<> forall s e a. SaveManagerCfg s e a -> [a -> WidgetRequest s e]
_smcOnChangeReq SaveManagerCfg s e a
a2
        , _smcOnSavesChangeReq :: [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq =
            forall s e a.
SaveManagerCfg s e a -> [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq SaveManagerCfg s e a
a1 forall a. Semigroup a => a -> a -> a
<> forall s e a.
SaveManagerCfg s e a -> [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq SaveManagerCfg s e a
a2
        , _smcCaptionMethod :: Maybe (a -> ZonedTime -> Text)
_smcCaptionMethod =
            forall s e a.
SaveManagerCfg s e a -> Maybe (a -> ZonedTime -> Text)
_smcCaptionMethod SaveManagerCfg s e a
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a.
SaveManagerCfg s e a -> Maybe (a -> ZonedTime -> Text)
_smcCaptionMethod SaveManagerCfg s e a
a1
        , _smcNoConfirm :: Maybe Bool
_smcNoConfirm = forall s e a. SaveManagerCfg s e a -> Maybe Bool
_smcNoConfirm SaveManagerCfg s e a
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. SaveManagerCfg s e a -> Maybe Bool
_smcNoConfirm SaveManagerCfg s e a
a1
        }

instance Monoid (SaveManagerCfg s e a) where
    mempty :: SaveManagerCfg s e a
mempty = forall a. Default a => a
def

instance WidgetEvent e =>
    CmbOnFocus (SaveManagerCfg s e a) e Path where
        onFocus :: (Path -> e) -> SaveManagerCfg s e a
onFocus Path -> e
fn = forall a. Default a => a
def
            { _smcOnFocusReq :: [Path -> WidgetRequest s e]
_smcOnFocusReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path -> e
fn]
            }

instance CmbOnFocusReq (SaveManagerCfg s e a) s e Path where
    onFocusReq :: (Path -> WidgetRequest s e) -> SaveManagerCfg s e a
onFocusReq Path -> WidgetRequest s e
req = forall a. Default a => a
def
        { _smcOnFocusReq :: [Path -> WidgetRequest s e]
_smcOnFocusReq = [Path -> WidgetRequest s e
req]
        }

instance WidgetEvent e =>
    CmbOnBlur (SaveManagerCfg s e a) e Path where
        onBlur :: (Path -> e) -> SaveManagerCfg s e a
onBlur Path -> e
fn = forall a. Default a => a
def
            { _smcOnBlurReq :: [Path -> WidgetRequest s e]
_smcOnBlurReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path -> e
fn]
            }

instance CmbOnBlurReq (SaveManagerCfg s e a) s e Path where
    onBlurReq :: (Path -> WidgetRequest s e) -> SaveManagerCfg s e a
onBlurReq Path -> WidgetRequest s e
req = forall a. Default a => a
def
        { _smcOnBlurReq :: [Path -> WidgetRequest s e]
_smcOnBlurReq = [Path -> WidgetRequest s e
req]
        }

instance WidgetEvent e =>
    CmbOnChange (SaveManagerCfg s e a) a e where
        onChange :: (a -> e) -> SaveManagerCfg s e a
onChange a -> e
fn = forall a. Default a => a
def
            { _smcOnChangeReq :: [a -> WidgetRequest s e]
_smcOnChangeReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> e
fn]
            }

instance CmbOnChangeReq
    (SaveManagerCfg s e a) s e a where
        onChangeReq :: (a -> WidgetRequest s e) -> SaveManagerCfg s e a
onChangeReq a -> WidgetRequest s e
req = forall a. Default a => a
def
            { _smcOnChangeReq :: [a -> WidgetRequest s e]
_smcOnChangeReq = [a -> WidgetRequest s e
req]
            }

{-|
On saves change event.
-}
onSavesChange
    :: (WidgetEvent e)
    => (Saves a -> e)
    -> SaveManagerCfg s e a
onSavesChange :: forall e a s.
WidgetEvent e =>
(Saves a -> e) -> SaveManagerCfg s e a
onSavesChange Saves a -> e
fn = forall a. Default a => a
def
    { _smcOnSavesChangeReq :: [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Saves a -> e
fn]
    }

{-|
On saves change 'WidgetRequest'.
-}
onSavesChangeReq
    :: (Saves a -> WidgetRequest s e)
    -> SaveManagerCfg s e a
onSavesChangeReq :: forall a s e.
(Saves a -> WidgetRequest s e) -> SaveManagerCfg s e a
onSavesChangeReq Saves a -> WidgetRequest s e
req = forall a. Default a => a
def
    { _smcOnSavesChangeReq :: [Saves a -> WidgetRequest s e]
_smcOnSavesChangeReq = [Saves a -> WidgetRequest s e
req]
    }

{-|
Receives function which converts the value and current time into
text and uses it to generate the caption for the slot. Should be
used to show more information than just modification time about the
stored value.
-}
captionMethod :: (a -> ZonedTime -> Text) -> SaveManagerCfg s e a
captionMethod :: forall a s e. (a -> ZonedTime -> Text) -> SaveManagerCfg s e a
captionMethod a -> ZonedTime -> Text
makeCaption = forall a. Default a => a
def
    { _smcCaptionMethod :: Maybe (a -> ZonedTime -> Text)
_smcCaptionMethod = forall a. a -> Maybe a
Just a -> ZonedTime -> Text
makeCaption
    }

{-|
Should be used when the confirmation dialog is not needed.
-}
noConfirm :: SaveManagerCfg s e a
noConfirm :: forall s e a. SaveManagerCfg s e a
noConfirm = forall s e a. Bool -> SaveManagerCfg s e a
noConfirm_ Bool
True

noConfirm_ :: Bool -> SaveManagerCfg s e a
noConfirm_ :: forall s e a. Bool -> SaveManagerCfg s e a
noConfirm_ Bool
v = forall a. Default a => a
def
    { _smcNoConfirm :: Maybe Bool
_smcNoConfirm = forall a. a -> Maybe a
Just Bool
v
    }