{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Monomer.EnhancedSlider.EnhancedSliderCfg
    ( -- * Configuration
      EnhancedSliderCfg(..)
    , titleMethod
    , hideLabel
    , hideLabel_
    ) where

import Control.Applicative ((<|>))
import Data.Default
import Data.Text (Text)
import Monomer.Widgets.Single

{-|
Configuration options for enhancedSlider:

- 'dragRate': the rate at which drag movement affects the number.
- 'hideLabel': don't show the label, leave only slider and buttons.
- 'titleCaption': the title for the shown value.
- 'titleMethod': function to generate the label with value.
- 'alignLeft': put horizontal slider to the left of the buttons.
This is default.
- 'alignCenter': put horizontal slider between the buttons.
- 'alignRight': put horizontal slider to the right of the buttons.
- 'alignTop': put vertical slider to the top of the buttons.
- 'alignMiddle': put vertical slider between the buttons.
- 'alignBottom': put vertical slider to the bottom of the buttons.
- '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.
-}
data EnhancedSliderCfg s e a = EnhancedSliderCfg
    { forall s e a. EnhancedSliderCfg s e a -> Maybe Rational
_escDragRate :: Maybe Rational
    , forall s e a. EnhancedSliderCfg s e a -> Maybe Bool
_escHideLabel :: Maybe Bool
    , forall s e a. EnhancedSliderCfg s e a -> Maybe Text
_escTitle :: Maybe Text
    , forall s e a. EnhancedSliderCfg s e a -> Maybe (a -> Text)
_escTitleMethod :: Maybe (a -> Text)
    , forall s e a. EnhancedSliderCfg s e a -> Maybe AlignH
_escAlignH :: Maybe AlignH
    , forall s e a. EnhancedSliderCfg s e a -> Maybe AlignV
_escAlignV :: Maybe AlignV
    , forall s e a.
EnhancedSliderCfg s e a -> [Path -> WidgetRequest s e]
_escOnFocusReq :: [Path -> WidgetRequest s e]
    , forall s e a.
EnhancedSliderCfg s e a -> [Path -> WidgetRequest s e]
_escOnBlurReq :: [Path -> WidgetRequest s e]
    , forall s e a. EnhancedSliderCfg s e a -> [a -> WidgetRequest s e]
_escOnChangeReq :: [a -> WidgetRequest s e]
    }

instance Default (EnhancedSliderCfg s e a) where
    def :: EnhancedSliderCfg s e a
def = EnhancedSliderCfg
        { _escDragRate :: Maybe Rational
_escDragRate = forall a. Maybe a
Nothing
        , _escHideLabel :: Maybe Bool
_escHideLabel = forall a. Maybe a
Nothing
        , _escTitle :: Maybe Text
_escTitle = forall a. Maybe a
Nothing
        , _escTitleMethod :: Maybe (a -> Text)
_escTitleMethod = forall a. Maybe a
Nothing
        , _escAlignH :: Maybe AlignH
_escAlignH = forall a. Maybe a
Nothing
        , _escAlignV :: Maybe AlignV
_escAlignV = forall a. Maybe a
Nothing
        , _escOnFocusReq :: [Path -> WidgetRequest s e]
_escOnFocusReq = []
        , _escOnBlurReq :: [Path -> WidgetRequest s e]
_escOnBlurReq = []
        , _escOnChangeReq :: [a -> WidgetRequest s e]
_escOnChangeReq = []
        }

instance Semigroup (EnhancedSliderCfg s e a) where
    <> :: EnhancedSliderCfg s e a
-> EnhancedSliderCfg s e a -> EnhancedSliderCfg s e a
(<>) EnhancedSliderCfg s e a
c1 EnhancedSliderCfg s e a
c2 = EnhancedSliderCfg
        { _escDragRate :: Maybe Rational
_escDragRate = forall s e a. EnhancedSliderCfg s e a -> Maybe Rational
_escDragRate EnhancedSliderCfg s e a
c2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. EnhancedSliderCfg s e a -> Maybe Rational
_escDragRate EnhancedSliderCfg s e a
c1
        , _escHideLabel :: Maybe Bool
_escHideLabel = forall s e a. EnhancedSliderCfg s e a -> Maybe Bool
_escHideLabel EnhancedSliderCfg s e a
c2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. EnhancedSliderCfg s e a -> Maybe Bool
_escHideLabel EnhancedSliderCfg s e a
c1
        , _escTitle :: Maybe Text
_escTitle = forall s e a. EnhancedSliderCfg s e a -> Maybe Text
_escTitle EnhancedSliderCfg s e a
c2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. EnhancedSliderCfg s e a -> Maybe Text
_escTitle EnhancedSliderCfg s e a
c1
        , _escTitleMethod :: Maybe (a -> Text)
_escTitleMethod =
            forall s e a. EnhancedSliderCfg s e a -> Maybe (a -> Text)
_escTitleMethod EnhancedSliderCfg s e a
c2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. EnhancedSliderCfg s e a -> Maybe (a -> Text)
_escTitleMethod EnhancedSliderCfg s e a
c1
        , _escAlignH :: Maybe AlignH
_escAlignH = forall s e a. EnhancedSliderCfg s e a -> Maybe AlignH
_escAlignH EnhancedSliderCfg s e a
c2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. EnhancedSliderCfg s e a -> Maybe AlignH
_escAlignH EnhancedSliderCfg s e a
c1
        , _escAlignV :: Maybe AlignV
_escAlignV = forall s e a. EnhancedSliderCfg s e a -> Maybe AlignV
_escAlignV EnhancedSliderCfg s e a
c2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e a. EnhancedSliderCfg s e a -> Maybe AlignV
_escAlignV EnhancedSliderCfg s e a
c1
        , _escOnFocusReq :: [Path -> WidgetRequest s e]
_escOnFocusReq = forall s e a.
EnhancedSliderCfg s e a -> [Path -> WidgetRequest s e]
_escOnFocusReq EnhancedSliderCfg s e a
c1 forall a. Semigroup a => a -> a -> a
<> forall s e a.
EnhancedSliderCfg s e a -> [Path -> WidgetRequest s e]
_escOnFocusReq EnhancedSliderCfg s e a
c2
        , _escOnBlurReq :: [Path -> WidgetRequest s e]
_escOnBlurReq = forall s e a.
EnhancedSliderCfg s e a -> [Path -> WidgetRequest s e]
_escOnBlurReq EnhancedSliderCfg s e a
c1 forall a. Semigroup a => a -> a -> a
<> forall s e a.
EnhancedSliderCfg s e a -> [Path -> WidgetRequest s e]
_escOnBlurReq EnhancedSliderCfg s e a
c2
        , _escOnChangeReq :: [a -> WidgetRequest s e]
_escOnChangeReq = forall s e a. EnhancedSliderCfg s e a -> [a -> WidgetRequest s e]
_escOnChangeReq EnhancedSliderCfg s e a
c1 forall a. Semigroup a => a -> a -> a
<> forall s e a. EnhancedSliderCfg s e a -> [a -> WidgetRequest s e]
_escOnChangeReq EnhancedSliderCfg s e a
c2
        }

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

instance CmbDragRate (EnhancedSliderCfg s e a) Rational where
    dragRate :: Rational -> EnhancedSliderCfg s e a
dragRate Rational
rate = forall a. Default a => a
def
        { _escDragRate :: Maybe Rational
_escDragRate = forall a. a -> Maybe a
Just Rational
rate
        }

instance CmbTitleCaption (EnhancedSliderCfg s e a) where
    titleCaption :: Text -> EnhancedSliderCfg s e a
titleCaption Text
title = forall a. Default a => a
def
        { _escTitle :: Maybe Text
_escTitle = forall a. a -> Maybe a
Just Text
title
        }

instance CmbAlignLeft (EnhancedSliderCfg s e a) where
    alignLeft_ :: Bool -> EnhancedSliderCfg s e a
alignLeft_ Bool
False = forall a. Default a => a
def
    alignLeft_ Bool
True = forall a. Default a => a
def
        { _escAlignH :: Maybe AlignH
_escAlignH = forall a. a -> Maybe a
Just AlignH
ALeft
        }

instance CmbAlignCenter (EnhancedSliderCfg s e a) where
    alignCenter_ :: Bool -> EnhancedSliderCfg s e a
alignCenter_ Bool
False = forall a. Default a => a
def
    alignCenter_ Bool
True = forall a. Default a => a
def
        { _escAlignH :: Maybe AlignH
_escAlignH = forall a. a -> Maybe a
Just AlignH
ACenter
        }

instance CmbAlignRight (EnhancedSliderCfg s e a) where
    alignRight_ :: Bool -> EnhancedSliderCfg s e a
alignRight_ Bool
False = forall a. Default a => a
def
    alignRight_ Bool
True = forall a. Default a => a
def
        { _escAlignH :: Maybe AlignH
_escAlignH = forall a. a -> Maybe a
Just AlignH
ARight
        }

instance CmbAlignTop (EnhancedSliderCfg s e a) where
    alignTop_ :: Bool -> EnhancedSliderCfg s e a
alignTop_ Bool
False = forall a. Default a => a
def
    alignTop_ Bool
True = forall a. Default a => a
def
        { _escAlignV :: Maybe AlignV
_escAlignV = forall a. a -> Maybe a
Just AlignV
ATop
        }

instance CmbAlignMiddle (EnhancedSliderCfg s e a) where
    alignMiddle_ :: Bool -> EnhancedSliderCfg s e a
alignMiddle_ Bool
False = forall a. Default a => a
def
    alignMiddle_ Bool
True = forall a. Default a => a
def
        { _escAlignV :: Maybe AlignV
_escAlignV = forall a. a -> Maybe a
Just AlignV
AMiddle
        }

instance CmbAlignBottom (EnhancedSliderCfg s e a) where
    alignBottom_ :: Bool -> EnhancedSliderCfg s e a
alignBottom_ Bool
False = forall a. Default a => a
def
    alignBottom_ Bool
True = forall a. Default a => a
def
        { _escAlignV :: Maybe AlignV
_escAlignV = forall a. a -> Maybe a
Just AlignV
ABottom
        }

instance WidgetEvent e =>
    CmbOnFocus (EnhancedSliderCfg s e a) e Path where
        onFocus :: (Path -> e) -> EnhancedSliderCfg s e a
onFocus Path -> e
fn = forall a. Default a => a
def
            { _escOnFocusReq :: [Path -> WidgetRequest s e]
_escOnFocusReq = [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 (EnhancedSliderCfg s e a) s e Path where
    onFocusReq :: (Path -> WidgetRequest s e) -> EnhancedSliderCfg s e a
onFocusReq Path -> WidgetRequest s e
req = forall a. Default a => a
def
        { _escOnFocusReq :: [Path -> WidgetRequest s e]
_escOnFocusReq = [Path -> WidgetRequest s e
req]
        }

instance WidgetEvent e =>
    CmbOnBlur (EnhancedSliderCfg s e a) e Path where
        onBlur :: (Path -> e) -> EnhancedSliderCfg s e a
onBlur Path -> e
fn = forall a. Default a => a
def
            { _escOnBlurReq :: [Path -> WidgetRequest s e]
_escOnBlurReq = [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 (EnhancedSliderCfg s e a) s e Path where
    onBlurReq :: (Path -> WidgetRequest s e) -> EnhancedSliderCfg s e a
onBlurReq Path -> WidgetRequest s e
req = forall a. Default a => a
def
        { _escOnBlurReq :: [Path -> WidgetRequest s e]
_escOnBlurReq = [Path -> WidgetRequest s e
req]
        }

instance WidgetEvent e =>
    CmbOnChange (EnhancedSliderCfg s e a) a e where
        onChange :: (a -> e) -> EnhancedSliderCfg s e a
onChange a -> e
fn = forall a. Default a => a
def
            { _escOnChangeReq :: [a -> WidgetRequest s e]
_escOnChangeReq = [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 (EnhancedSliderCfg s e a) s e a where
    onChangeReq :: (a -> WidgetRequest s e) -> EnhancedSliderCfg s e a
onChangeReq a -> WidgetRequest s e
req = forall a. Default a => a
def
        { _escOnChangeReq :: [a -> WidgetRequest s e]
_escOnChangeReq = [a -> WidgetRequest s e
req]
        }

{-|
Receives function which converts the value into text and uses it to
generate the label. Should be used if the title depends on the value
or different formatting is needed.
-}
titleMethod :: (a -> Text) -> EnhancedSliderCfg s e a
titleMethod :: forall a s e. (a -> Text) -> EnhancedSliderCfg s e a
titleMethod a -> Text
makeTitle = forall a. Default a => a
def
    { _escTitleMethod :: Maybe (a -> Text)
_escTitleMethod = forall a. a -> Maybe a
Just a -> Text
makeTitle
    }

{-|
Should be used when the label with the current value is not needed.
-}
hideLabel :: EnhancedSliderCfg s e a
hideLabel :: forall s e a. EnhancedSliderCfg s e a
hideLabel = forall s e a. Bool -> EnhancedSliderCfg s e a
hideLabel_ Bool
True

hideLabel_ :: Bool -> EnhancedSliderCfg s e a
hideLabel_ :: forall s e a. Bool -> EnhancedSliderCfg s e a
hideLabel_ Bool
v = forall a. Default a => a
def
    { _escHideLabel :: Maybe Bool
_escHideLabel = forall a. a -> Maybe a
Just Bool
v
    }