{-#LANGUAGE RecordWildCards#-}

------------------------------------------------------------------------------
-- |
-- Module: Xmobar.Plugins.Monitors.Types
-- Copyright: (c) 2018 Jose Antonio Ortega Ruiz
-- License: BSD3-style (see LICENSE)
--
-- Maintainer: jao@gnu.org
-- Stability: unstable
-- Portability: portable
-- Created: Sun Dec 02, 2018 04:31
--
--
-- Type definitions and constructors for Monitors
--
------------------------------------------------------------------------------


module Xmobar.Plugins.Monitors.Common.Types ( Monitor
                                            , MConfig (..)
                                            , Opts (..)
                                            , Selector
                                            , setConfigValue
                                            , mkMConfig
                                            , io
                                            , MonitorConfig (..)
                                            , getPConfigValue
                                            , getConfigValue
                                            , getMonitorConfig
                                            , PSelector
                                            , TemplateInput(..)
                                            ) where

import Control.Monad.Reader (ReaderT, ask, liftIO)
import Data.IORef (IORef, modifyIORef, newIORef, readIORef)


type Monitor a = ReaderT MConfig IO a

io :: IO a -> Monitor a
io :: forall a. IO a -> Monitor a
io = IO a -> ReaderT MConfig IO a
forall a. IO a -> Monitor a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

data TemplateInput = TemplateInput {
      TemplateInput -> [String]
temMonitorValues :: [String],
      TemplateInput -> [(String, String, String)]
temInputTemplate :: [(String, String, String)],
      TemplateInput -> [(String, [(String, String, String)])]
temAllTemplate :: [(String, [(String, String, String)])]
    }

data MConfig =
    MC { MConfig -> IORef (Maybe String)
normalColor :: IORef (Maybe String)
       , MConfig -> IORef Int
low :: IORef Int
       , MConfig -> IORef (Maybe String)
lowColor :: IORef (Maybe String)
       , MConfig -> IORef Int
high :: IORef Int
       , MConfig -> IORef (Maybe String)
highColor :: IORef (Maybe String)
       , MConfig -> IORef String
template :: IORef String
       , MConfig -> IORef [String]
export :: IORef [String]
       , MConfig -> IORef Int
ppad :: IORef Int
       , MConfig -> IORef Int
decDigits :: IORef Int
       , MConfig -> IORef Int
minWidth :: IORef Int
       , MConfig -> IORef Int
maxWidth :: IORef Int
       , MConfig -> IORef String
maxWidthEllipsis :: IORef String
       , MConfig -> IORef String
padChars :: IORef String
       , MConfig -> IORef Bool
padRight :: IORef Bool
       , MConfig -> IORef String
barBack :: IORef String
       , MConfig -> IORef String
barFore :: IORef String
       , MConfig -> IORef Int
barWidth :: IORef Int
       , MConfig -> IORef Bool
useSuffix :: IORef Bool
       , MConfig -> IORef String
naString :: IORef String
       , MConfig -> IORef Int
maxTotalWidth :: IORef Int
       , MConfig -> IORef String
maxTotalWidthEllipsis :: IORef String
       }

data MonitorConfig =
  MonitorConfig
    { MonitorConfig -> Maybe String
pNormalColor :: Maybe String
    , MonitorConfig -> Int
pLow :: Int
    , MonitorConfig -> Maybe String
pLowColor :: Maybe String
    , MonitorConfig -> Int
pHigh :: Int
    , MonitorConfig -> Maybe String
pHighColor :: Maybe String
    , MonitorConfig -> String
pTemplate :: String
    , MonitorConfig -> [String]
pExport :: [String]
    , MonitorConfig -> Int
pPpad :: Int
    , MonitorConfig -> Int
pDecDigits :: Int
    , MonitorConfig -> Int
pMinWidth :: Int
    , MonitorConfig -> Int
pMaxWidth :: Int
    , MonitorConfig -> String
pMaxWidthEllipsis :: String
    , MonitorConfig -> String
pPadChars :: String
    , MonitorConfig -> Bool
pPadRight :: Bool
    , MonitorConfig -> String
pBarBack :: String
    , MonitorConfig -> String
pBarFore :: String
    , MonitorConfig -> Int
pBarWidth :: Int
    , MonitorConfig -> Bool
pUseSuffix :: Bool
    , MonitorConfig -> String
pNaString :: String
    , MonitorConfig -> Int
pMaxTotalWidth :: Int
    , MonitorConfig -> String
pMaxTotalWidthEllipsis :: String
    }
  deriving (MonitorConfig -> MonitorConfig -> Bool
(MonitorConfig -> MonitorConfig -> Bool)
-> (MonitorConfig -> MonitorConfig -> Bool) -> Eq MonitorConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MonitorConfig -> MonitorConfig -> Bool
== :: MonitorConfig -> MonitorConfig -> Bool
$c/= :: MonitorConfig -> MonitorConfig -> Bool
/= :: MonitorConfig -> MonitorConfig -> Bool
Eq, Eq MonitorConfig
Eq MonitorConfig =>
(MonitorConfig -> MonitorConfig -> Ordering)
-> (MonitorConfig -> MonitorConfig -> Bool)
-> (MonitorConfig -> MonitorConfig -> Bool)
-> (MonitorConfig -> MonitorConfig -> Bool)
-> (MonitorConfig -> MonitorConfig -> Bool)
-> (MonitorConfig -> MonitorConfig -> MonitorConfig)
-> (MonitorConfig -> MonitorConfig -> MonitorConfig)
-> Ord MonitorConfig
MonitorConfig -> MonitorConfig -> Bool
MonitorConfig -> MonitorConfig -> Ordering
MonitorConfig -> MonitorConfig -> MonitorConfig
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MonitorConfig -> MonitorConfig -> Ordering
compare :: MonitorConfig -> MonitorConfig -> Ordering
$c< :: MonitorConfig -> MonitorConfig -> Bool
< :: MonitorConfig -> MonitorConfig -> Bool
$c<= :: MonitorConfig -> MonitorConfig -> Bool
<= :: MonitorConfig -> MonitorConfig -> Bool
$c> :: MonitorConfig -> MonitorConfig -> Bool
> :: MonitorConfig -> MonitorConfig -> Bool
$c>= :: MonitorConfig -> MonitorConfig -> Bool
>= :: MonitorConfig -> MonitorConfig -> Bool
$cmax :: MonitorConfig -> MonitorConfig -> MonitorConfig
max :: MonitorConfig -> MonitorConfig -> MonitorConfig
$cmin :: MonitorConfig -> MonitorConfig -> MonitorConfig
min :: MonitorConfig -> MonitorConfig -> MonitorConfig
Ord)

getMonitorConfig :: MConfig -> IO MonitorConfig
getMonitorConfig :: MConfig -> IO MonitorConfig
getMonitorConfig MC{IORef Bool
IORef Int
IORef String
IORef [String]
IORef (Maybe String)
normalColor :: MConfig -> IORef (Maybe String)
low :: MConfig -> IORef Int
lowColor :: MConfig -> IORef (Maybe String)
high :: MConfig -> IORef Int
highColor :: MConfig -> IORef (Maybe String)
template :: MConfig -> IORef String
export :: MConfig -> IORef [String]
ppad :: MConfig -> IORef Int
decDigits :: MConfig -> IORef Int
minWidth :: MConfig -> IORef Int
maxWidth :: MConfig -> IORef Int
maxWidthEllipsis :: MConfig -> IORef String
padChars :: MConfig -> IORef String
padRight :: MConfig -> IORef Bool
barBack :: MConfig -> IORef String
barFore :: MConfig -> IORef String
barWidth :: MConfig -> IORef Int
useSuffix :: MConfig -> IORef Bool
naString :: MConfig -> IORef String
maxTotalWidth :: MConfig -> IORef Int
maxTotalWidthEllipsis :: MConfig -> IORef String
normalColor :: IORef (Maybe String)
low :: IORef Int
lowColor :: IORef (Maybe String)
high :: IORef Int
highColor :: IORef (Maybe String)
template :: IORef String
export :: IORef [String]
ppad :: IORef Int
decDigits :: IORef Int
minWidth :: IORef Int
maxWidth :: IORef Int
maxWidthEllipsis :: IORef String
padChars :: IORef String
padRight :: IORef Bool
barBack :: IORef String
barFore :: IORef String
barWidth :: IORef Int
useSuffix :: IORef Bool
naString :: IORef String
maxTotalWidth :: IORef Int
maxTotalWidthEllipsis :: IORef String
..} = do
  pNormalColor <- IORef (Maybe String) -> IO (Maybe String)
forall a. IORef a -> IO a
readIORef IORef (Maybe String)
normalColor
  pLow <- readIORef low
  pLowColor <- readIORef lowColor
  pHigh <- readIORef high
  pHighColor <- readIORef highColor
  pTemplate <- readIORef template
  pExport <- readIORef export
  pPpad <- readIORef ppad
  pDecDigits <- readIORef decDigits
  pMinWidth <- readIORef minWidth
  pMaxWidth <- readIORef maxWidth
  pMaxWidthEllipsis <- readIORef maxWidthEllipsis
  pPadChars <- readIORef padChars
  pPadRight <- readIORef padRight
  pBarBack <- readIORef barBack
  pBarFore <- readIORef barFore
  pBarWidth <- readIORef barWidth
  pUseSuffix <- readIORef useSuffix
  pNaString <- readIORef naString
  pMaxTotalWidth <- readIORef maxTotalWidth
  pMaxTotalWidthEllipsis <- readIORef maxTotalWidthEllipsis
  pure $ MonitorConfig {..}

-- | from 'http:\/\/www.haskell.org\/hawiki\/MonadState'
type Selector a = MConfig -> IORef a
type PSelector a = MonitorConfig -> a

psel :: MonitorConfig -> PSelector a -> a
psel :: forall a. MonitorConfig -> PSelector a -> a
psel MonitorConfig
value PSelector a
accessor = PSelector a
accessor MonitorConfig
value

sel :: Selector a -> Monitor a
sel :: forall a. Selector a -> Monitor a
sel Selector a
s =
    do hs <- ReaderT MConfig IO MConfig
forall r (m :: * -> *). MonadReader r m => m r
ask
       liftIO $ readIORef (s hs)

mods :: Selector a -> (a -> a) -> Monitor ()
mods :: forall a. Selector a -> (a -> a) -> Monitor ()
mods Selector a
s a -> a
m =
    do v <- ReaderT MConfig IO MConfig
forall r (m :: * -> *). MonadReader r m => m r
ask
       io $ modifyIORef (s v) m

setConfigValue :: a -> Selector a -> Monitor ()
setConfigValue :: forall a. a -> Selector a -> Monitor ()
setConfigValue a
v Selector a
s =
       Selector a -> (a -> a) -> Monitor ()
forall a. Selector a -> (a -> a) -> Monitor ()
mods Selector a
s (a -> a -> a
forall a b. a -> b -> a
const a
v)

getConfigValue :: Selector a -> Monitor a
getConfigValue :: forall a. Selector a -> Monitor a
getConfigValue = Selector a -> Monitor a
forall a. Selector a -> Monitor a
sel

getPConfigValue :: MonitorConfig -> PSelector a -> a
getPConfigValue :: forall a. MonitorConfig -> PSelector a -> a
getPConfigValue = MonitorConfig -> PSelector a -> a
forall a. MonitorConfig -> PSelector a -> a
psel

mkMConfig :: String
          -> [String]
          -> IO MConfig
mkMConfig :: String -> [String] -> IO MConfig
mkMConfig String
tmpl [String]
exprts =
    do lc <- Maybe String -> IO (IORef (Maybe String))
forall a. a -> IO (IORef a)
newIORef Maybe String
forall a. Maybe a
Nothing
       l  <- newIORef 33
       nc <- newIORef Nothing
       h  <- newIORef 66
       hc <- newIORef Nothing
       t  <- newIORef tmpl
       e  <- newIORef exprts
       p  <- newIORef 0
       d  <- newIORef 0
       mn <- newIORef 0
       mx <- newIORef 0
       mel <- newIORef ""
       pc <- newIORef " "
       pr <- newIORef False
       bb <- newIORef ":"
       bf <- newIORef "#"
       bw <- newIORef 10
       up <- newIORef False
       na <- newIORef "N/A"
       mt <- newIORef 0
       mtel <- newIORef ""
       return $ MC nc l lc h hc t e p d mn mx mel pc pr bb bf bw up na mt mtel

data Opts = HighColor String
          | NormalColor String
          | LowColor String
          | Low String
          | High String
          | Template String
          | PercentPad String
          | DecDigits String
          | MinWidth String
          | MaxWidth String
          | Width String
          | WidthEllipsis String
          | PadChars String
          | PadAlign String
          | BarBack String
          | BarFore String
          | BarWidth String
          | UseSuffix String
          | NAString String
          | MaxTotalWidth String
          | MaxTotalWidthEllipsis String