{-# OPTIONS_HADDOCK hide #-}

-- |
--
-- Copyright:
--   This file is part of the package byline. It is subject to the
--   license terms in the LICENSE file found in the top-level
--   directory of this distribution and at:
--
--     https://github.com/pjones/byline
--
--   No part of this package, including this file, may be copied,
--   modified, propagated, or distributed except according to the
--   terms contained in the LICENSE file.
--
-- License: BSD-2-Clause
module Byline.Internal.Types
  ( Color (..),
    Status (..),
    OnlyOne (..),
    Modifier (..),
  )
where

import qualified System.Console.ANSI as ANSI

-- | Opaque type for representing a color.
--
-- A color can be one of the eight standard terminal colors
-- constructed with one of the named color functions (e.g.,
-- 'Byline.black', 'Byline.red', etc.) or using the 'Byline.rgb'
-- function.
--
-- @since 1.0.0.0
data Color
  = ColorCode ANSI.Color
  | ColorRGB (Word8, Word8, Word8)
  deriving (Int -> Color -> ShowS
[Color] -> ShowS
Color -> String
(Int -> Color -> ShowS)
-> (Color -> String) -> ([Color] -> ShowS) -> Show Color
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Color] -> ShowS
$cshowList :: [Color] -> ShowS
show :: Color -> String
$cshow :: Color -> String
showsPrec :: Int -> Color -> ShowS
$cshowsPrec :: Int -> Color -> ShowS
Show, Color -> Color -> Bool
(Color -> Color -> Bool) -> (Color -> Color -> Bool) -> Eq Color
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Color -> Color -> Bool
$c/= :: Color -> Color -> Bool
== :: Color -> Color -> Bool
$c== :: Color -> Color -> Bool
Eq)

-- | Like @Bool@, but with a different @Monoid@ instance.
--
-- @since 1.0.0.0
data Status = On | Off
  deriving (Int -> Status -> ShowS
[Status] -> ShowS
Status -> String
(Int -> Status -> ShowS)
-> (Status -> String) -> ([Status] -> ShowS) -> Show Status
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Status] -> ShowS
$cshowList :: [Status] -> ShowS
show :: Status -> String
$cshow :: Status -> String
showsPrec :: Int -> Status -> ShowS
$cshowsPrec :: Int -> Status -> ShowS
Show, Status -> Status -> Bool
(Status -> Status -> Bool)
-> (Status -> Status -> Bool) -> Eq Status
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Status -> Status -> Bool
$c/= :: Status -> Status -> Bool
== :: Status -> Status -> Bool
$c== :: Status -> Status -> Bool
Eq)

-- | @since 1.0.0.0
instance Semigroup Status where
  <> :: Status -> Status -> Status
(<>) Status
Off Status
Off = Status
Off
  (<>) Status
Off Status
On = Status
On
  (<>) Status
On Status
On = Status
On
  (<>) Status
On Status
Off = Status
On

-- | @since 1.0.0.0
instance Monoid Status where
  mempty :: Status
mempty = Status
Off

-- | Like @Maybe@, but with a different @Monoid@ instance.
--
-- @since 1.0.0.0
newtype OnlyOne a = OnlyOne {OnlyOne a -> Maybe a
unOne :: Maybe a}
  deriving (Int -> OnlyOne a -> ShowS
[OnlyOne a] -> ShowS
OnlyOne a -> String
(Int -> OnlyOne a -> ShowS)
-> (OnlyOne a -> String)
-> ([OnlyOne a] -> ShowS)
-> Show (OnlyOne a)
forall a. Show a => Int -> OnlyOne a -> ShowS
forall a. Show a => [OnlyOne a] -> ShowS
forall a. Show a => OnlyOne a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OnlyOne a] -> ShowS
$cshowList :: forall a. Show a => [OnlyOne a] -> ShowS
show :: OnlyOne a -> String
$cshow :: forall a. Show a => OnlyOne a -> String
showsPrec :: Int -> OnlyOne a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> OnlyOne a -> ShowS
Show, OnlyOne a -> OnlyOne a -> Bool
(OnlyOne a -> OnlyOne a -> Bool)
-> (OnlyOne a -> OnlyOne a -> Bool) -> Eq (OnlyOne a)
forall a. Eq a => OnlyOne a -> OnlyOne a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OnlyOne a -> OnlyOne a -> Bool
$c/= :: forall a. Eq a => OnlyOne a -> OnlyOne a -> Bool
== :: OnlyOne a -> OnlyOne a -> Bool
$c== :: forall a. Eq a => OnlyOne a -> OnlyOne a -> Bool
Eq)

-- | @since 1.0.0.0
instance Semigroup (OnlyOne a) where
  <> :: OnlyOne a -> OnlyOne a -> OnlyOne a
(<>) OnlyOne a
_ b :: OnlyOne a
b@(OnlyOne (Just a
_)) = OnlyOne a
b
  (<>) OnlyOne a
a OnlyOne a
_ = OnlyOne a
a

-- | @since 1.0.0.0
instance Monoid (OnlyOne a) where
  mempty :: OnlyOne a
mempty = Maybe a -> OnlyOne a
forall a. Maybe a -> OnlyOne a
OnlyOne Maybe a
forall a. Maybe a
Nothing

-- | Information about modifications made to stylized text.
--
-- @since 1.0.0.0
data Modifier = Modifier
  { Modifier -> OnlyOne Color
modColorFG :: OnlyOne Color,
    Modifier -> OnlyOne Color
modColorBG :: OnlyOne Color,
    Modifier -> Status
modBold :: Status,
    Modifier -> Status
modUnderline :: Status,
    Modifier -> Status
modSwapFgBg :: Status
  }
  deriving (Int -> Modifier -> ShowS
[Modifier] -> ShowS
Modifier -> String
(Int -> Modifier -> ShowS)
-> (Modifier -> String) -> ([Modifier] -> ShowS) -> Show Modifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Modifier] -> ShowS
$cshowList :: [Modifier] -> ShowS
show :: Modifier -> String
$cshow :: Modifier -> String
showsPrec :: Int -> Modifier -> ShowS
$cshowsPrec :: Int -> Modifier -> ShowS
Show, Modifier -> Modifier -> Bool
(Modifier -> Modifier -> Bool)
-> (Modifier -> Modifier -> Bool) -> Eq Modifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Modifier -> Modifier -> Bool
$c/= :: Modifier -> Modifier -> Bool
== :: Modifier -> Modifier -> Bool
$c== :: Modifier -> Modifier -> Bool
Eq)

-- | @since 1.0.0.0
instance Semigroup Modifier where
  <> :: Modifier -> Modifier -> Modifier
(<>) (Modifier OnlyOne Color
a OnlyOne Color
b Status
c Status
d Status
e) (Modifier OnlyOne Color
a' OnlyOne Color
b' Status
c' Status
d' Status
e') =
    OnlyOne Color
-> OnlyOne Color -> Status -> Status -> Status -> Modifier
Modifier (OnlyOne Color
a OnlyOne Color -> OnlyOne Color -> OnlyOne Color
forall a. Semigroup a => a -> a -> a
<> OnlyOne Color
a') (OnlyOne Color
b OnlyOne Color -> OnlyOne Color -> OnlyOne Color
forall a. Semigroup a => a -> a -> a
<> OnlyOne Color
b') (Status
c Status -> Status -> Status
forall a. Semigroup a => a -> a -> a
<> Status
c') (Status
d Status -> Status -> Status
forall a. Semigroup a => a -> a -> a
<> Status
d') (Status
e Status -> Status -> Status
forall a. Semigroup a => a -> a -> a
<> Status
e')

-- | @since 1.0.0.0
instance Monoid Modifier where
  mempty :: Modifier
mempty = OnlyOne Color
-> OnlyOne Color -> Status -> Status -> Status -> Modifier
Modifier OnlyOne Color
forall a. Monoid a => a
mempty OnlyOne Color
forall a. Monoid a => a
mempty Status
forall a. Monoid a => a
mempty Status
forall a. Monoid a => a
mempty Status
forall a. Monoid a => a
mempty