module Text.Layout.Table.Primitives.AlignInfo where

import Data.Foldable (asum)

-- | Specifies the length before and after an alignment position (excluding the
-- alignment character).
data AlignInfo = AlignInfo Int (Maybe Int)
  deriving (AlignInfo -> AlignInfo -> Bool
(AlignInfo -> AlignInfo -> Bool)
-> (AlignInfo -> AlignInfo -> Bool) -> Eq AlignInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AlignInfo -> AlignInfo -> Bool
$c/= :: AlignInfo -> AlignInfo -> Bool
== :: AlignInfo -> AlignInfo -> Bool
$c== :: AlignInfo -> AlignInfo -> Bool
Eq, Int -> AlignInfo -> ShowS
[AlignInfo] -> ShowS
AlignInfo -> String
(Int -> AlignInfo -> ShowS)
-> (AlignInfo -> String)
-> ([AlignInfo] -> ShowS)
-> Show AlignInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AlignInfo] -> ShowS
$cshowList :: [AlignInfo] -> ShowS
show :: AlignInfo -> String
$cshow :: AlignInfo -> String
showsPrec :: Int -> AlignInfo -> ShowS
$cshowsPrec :: Int -> AlignInfo -> ShowS
Show)

-- | Private show function.
showAI :: AlignInfo -> String
showAI :: AlignInfo -> String
showAI (AlignInfo Int
l Maybe Int
optR) = String
"AlignInfo " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
l String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Maybe Int -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Maybe Int
optR String
""

-- | The column width when using the 'AlignInfo'.
widthAI :: AlignInfo -> Int
widthAI :: AlignInfo -> Int
widthAI (AlignInfo Int
l Maybe Int
optR) = Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 Int -> Int
forall a. Enum a => a -> a
succ Maybe Int
optR

-- | Produce an 'AlignInfo' that is wide enough to hold inputs of both given
-- 'AlignInfo's.
instance Semigroup AlignInfo where
    AlignInfo Int
ll Maybe Int
lOptR <> :: AlignInfo -> AlignInfo -> AlignInfo
<> AlignInfo Int
rl Maybe Int
rOptR =
        Int -> Maybe Int -> AlignInfo
AlignInfo (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
ll Int
rl) ([Maybe Int] -> Maybe Int
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int -> Int -> Int) -> Maybe Int -> Maybe (Int -> Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
lOptR Maybe (Int -> Int) -> Maybe Int -> Maybe Int
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Int
rOptR, Maybe Int
lOptR, Maybe Int
rOptR])

instance Monoid AlignInfo where
    mempty :: AlignInfo
mempty = Int -> Maybe Int -> AlignInfo
AlignInfo Int
0 Maybe Int
forall a. Maybe a
Nothing