module System.Taffybar.Widget.Text.MemoryMonitor (textMemoryMonitorNew) where

import Control.Monad.IO.Class ( MonadIO )
import qualified Text.StringTemplate as ST
import System.Taffybar.Information.Memory
import System.Taffybar.Widget.Generic.PollingLabel ( pollingLabelNew )
import qualified GI.Gtk

-- | Creates a simple textual memory monitor. It updates once every polling
-- period (in seconds).
textMemoryMonitorNew :: MonadIO m
                     => String -- ^ Format. You can use variables: "used", "total", "free", "buffer", "cache", "rest", "used".
                     -> Double -- ^ Polling period in seconds.
                     -> m GI.Gtk.Widget
textMemoryMonitorNew :: String -> Double -> m Widget
textMemoryMonitorNew fmt :: String
fmt period :: Double
period = do
    Widget
label <- Double -> IO Text -> m Widget
forall (m :: * -> *). MonadIO m => Double -> IO Text -> m Widget
pollingLabelNew Double
period IO Text
callback
    Widget -> m Widget
forall (m :: * -> *) o. (MonadIO m, IsWidget o) => o -> m Widget
GI.Gtk.toWidget Widget
label
    where
      callback :: IO Text
callback = do
        MemoryInfo
info <- IO MemoryInfo
parseMeminfo
        let template :: StringTemplate Text
template = String -> StringTemplate Text
forall a. Stringable a => String -> StringTemplate a
ST.newSTMP String
fmt
        let labels :: [String]
labels = ["used", "total", "free", "buffer", "cache", "rest", "used"]
        let actions :: [MemoryInfo -> Double]
actions = [MemoryInfo -> Double
memoryUsed, MemoryInfo -> Double
memoryTotal, MemoryInfo -> Double
memoryFree, MemoryInfo -> Double
memoryBuffer, MemoryInfo -> Double
memoryCache, MemoryInfo -> Double
memoryRest]
            actions' :: [MemoryInfo -> String]
actions' = ((MemoryInfo -> Double) -> MemoryInfo -> String)
-> [MemoryInfo -> Double] -> [MemoryInfo -> String]
forall a b. (a -> b) -> [a] -> [b]
map ((Int -> String
forall a. Show a => a -> String
show (Int -> String) -> (Double -> Int) -> Double -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Int
intRound)(Double -> String)
-> (MemoryInfo -> Double) -> MemoryInfo -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) [MemoryInfo -> Double]
actions
        let stats :: [String]
stats = [MemoryInfo -> String
f MemoryInfo
info | MemoryInfo -> String
f <- [MemoryInfo -> String]
actions']
        let template' :: StringTemplate Text
template' = [(String, String)] -> StringTemplate Text -> StringTemplate Text
forall a b.
(ToSElem a, Stringable b) =>
[(String, a)] -> StringTemplate b -> StringTemplate b
ST.setManyAttrib ([String] -> [String] -> [(String, String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [String]
labels [String]
stats) StringTemplate Text
template
        Text -> IO Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> IO Text) -> Text -> IO Text
forall a b. (a -> b) -> a -> b
$ StringTemplate Text -> Text
forall a. Stringable a => StringTemplate a -> a
ST.render StringTemplate Text
template'

intRound :: Double -> Int
intRound :: Double -> Int
intRound = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round