module Ghcitui.Util (showT, splitBy, linesToText, clamp, getNumDigits, formatDigits) where

import Data.Text (Text, breakOn, drop, length, pack)
import Prelude hiding (drop, length)

-- | Split text based on a delimiter.
splitBy
    :: Text
    -- ^ Delimeter.
    -> Text
    -- ^ Text to split on.
    -> [Text]
splitBy :: Text -> Text -> [Text]
splitBy Text
"" Text
source = [Text
source]
splitBy Text
delim Text
source =
    case HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
breakOn Text
delim Text
source of
        (Text
l, Text
"") -> [Text
l]
        (Text
l, Text
r) -> Text
l Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text -> Text -> [Text]
splitBy Text
delim (Int -> Text -> Text
drop (Text -> Int
length Text
delim) Text
r)

-- | Convert Strings to Text.
linesToText :: [String] -> Text
linesToText :: [String] -> Text
linesToText = String -> Text
pack (String -> Text) -> ([String] -> String) -> [String] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
Prelude.unlines

-- | 'show' but to Text.
showT :: (Show a) => a -> Text
showT :: forall a. Show a => a -> Text
showT = String -> Text
pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

-- Return the number of digits in a given integral
getNumDigits :: (Integral a) => a -> Int
getNumDigits :: forall a. Integral a => a -> Int
getNumDigits a
0 = Int
1
getNumDigits a
num = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
10 (a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
num) :: Double) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1

-- | Format digits into a string with padding.
formatDigits
    :: Int
    -- ^ Number of spaces
    -> Int
    -- ^ Number to format digits of
    -> Text
    -- ^ Formatted Text
formatDigits :: Int -> Int -> Text
formatDigits Int
spacing Int
num = String -> Text
pack (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
amount Char
' ') Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (Int -> String
forall a. Show a => a -> String
show Int
num)
  where
    amount :: Int
amount = Int
spacing Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int
forall a. Integral a => a -> Int
getNumDigits Int
num

clamp
    :: (Ord a)
    => (a, a)
    -- ^ The minimum and maximum (inclusive)
    -> a
    -- ^ Value to clamp
    -> a
    -- ^ Result
clamp :: forall a. Ord a => (a, a) -> a -> a
clamp (a
mi, a
mx) a
v
    | a
v a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
mi = a
mi
    | a
v a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
mx = a
mx
    | Bool
otherwise = a
v