    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE DeriveAnyClass #-}

    module Graphics.Vty.Attributes.Color
      ( Color(..)

      -- ** Fixed Colors
      -- | Standard 8-color ANSI terminal color codes.
      --
      -- Note that these map to colors in the terminal's custom palette. For
      -- instance, `white` maps to whatever the terminal color theme uses for
      -- white.
      --
      -- Use these functions if you want to make apps that fit the terminal theme.
      -- If you want access to more/stronger colors use `rgbColor`
      , black
      , red
      , green
      , yellow
      , blue
      , magenta
      , cyan
      , white

      -- | Bright/Vivid variants of the standard 8-color ANSI
      , brightBlack
      , brightRed
      , brightGreen
      , brightYellow
      , brightBlue
      , brightMagenta
      , brightCyan
      , brightWhite
      -- ** Creating Colors From RGB
      , rgbColor
      , module Graphics.Vty.Attributes.Color240
      )
    where

    import Data.Word
    import GHC.Generics
    import Control.DeepSeq

    import Graphics.Vty.Attributes.Color240

    -- | Abstract data type representing a color.
    --
    -- Currently the foreground and background color are specified as points
    -- in either a:
    --
    --  * 16 color palette. Where the first 8 colors are equal to the 8
    --  colors of the ISO 6429 (ANSI) 8 color palette and the second 8
    --  colors are bright/vivid versions of the first 8 colors.
    --
    --  * 240 color palette. This palette is a regular sampling of the full
    --  RGB colorspace for the first 224 colors. The remaining 16 colors is
    --  a greyscale palette.
    --
    -- The 8 ISO 6429 (ANSI) colors are as follows:
    --
    --      0. black
    --
    --      1. red
    --
    --      2. green
    --
    --      3. yellow
    --
    --      4. blue
    --
    --      5. magenta
    --
    --      6. cyan
    --
    --      7. white
    --
    -- The mapping from points in the 240 color palette to colors actually
    -- displayable by the terminal depends on the number of colors the
    -- terminal claims to support. Which is usually determined by the
    -- terminfo "colors" property. If this property is not being accurately
    -- reported then the color reproduction will be incorrect.
    --
    -- If the terminal reports <= 16 colors then the 240 color palette
    -- points are only mapped to the 8 color pallete. I'm not sure of
    -- the RGB points for the "bright" colors which is why they are not
    -- addressable via the 240 color palette.
    --
    -- If the terminal reports > 16 colors then the 240 color palette
    -- points are mapped to the nearest points in a ("color count" - 16)
    -- subsampling of the 240 color palette.
    --
    -- All of this assumes the terminals are behaving similarly to xterm and
    -- rxvt when handling colors. And that the individual colors have not
    -- been remapped by the user. There may be a way to verify this through
    -- terminfo but I don't know it.
    --
    -- Seriously, terminal color support is INSANE.
    data Color = ISOColor !Word8 | Color240 !Word8
        deriving ( 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, 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, ReadPrec [Color]
    ReadPrec Color
    Int -> ReadS Color
    ReadS [Color]
    (Int -> ReadS Color)
    -> ReadS [Color]
    -> ReadPrec Color
    -> ReadPrec [Color]
    -> Read Color
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Color]
    $creadListPrec :: ReadPrec [Color]
    readPrec :: ReadPrec Color
    $creadPrec :: ReadPrec Color
    readList :: ReadS [Color]
    $creadList :: ReadS [Color]
    readsPrec :: Int -> ReadS Color
    $creadsPrec :: Int -> ReadS Color
    Read, (forall x. Color -> Rep Color x)
    -> (forall x. Rep Color x -> Color) -> Generic Color
    forall x. Rep Color x -> Color
    forall x. Color -> Rep Color x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep Color x -> Color
    $cfrom :: forall x. Color -> Rep Color x
    Generic, Color -> ()
    (Color -> ()) -> NFData Color
    forall a. (a -> ()) -> NFData a
    rnf :: Color -> ()
    $crnf :: Color -> ()
    NFData )

    black, red, green, yellow, blue, magenta, cyan, white :: Color
    black :: Color
    black  = Word8 -> Color
    ISOColor 0
    red :: Color
    red    = Word8 -> Color
    ISOColor 1
    green :: Color
    green  = Word8 -> Color
    ISOColor 2
    yellow :: Color
    yellow = Word8 -> Color
    ISOColor 3
    blue :: Color
    blue   = Word8 -> Color
    ISOColor 4
    magenta :: Color
    magenta= Word8 -> Color
    ISOColor 5
    cyan :: Color
    cyan   = Word8 -> Color
    ISOColor 6
    white :: Color
    white  = Word8 -> Color
    ISOColor 7

    brightBlack, brightRed, brightGreen, brightYellow :: Color
    brightBlue, brightMagenta, brightCyan, brightWhite :: Color
    brightBlack :: Color
    brightBlack  = Word8 -> Color
    ISOColor 8
    brightRed :: Color
    brightRed    = Word8 -> Color
    ISOColor 9
    brightGreen :: Color
    brightGreen  = Word8 -> Color
    ISOColor 10
    brightYellow :: Color
    brightYellow = Word8 -> Color
    ISOColor 11
    brightBlue :: Color
    brightBlue   = Word8 -> Color
    ISOColor 12
    brightMagenta :: Color
    brightMagenta= Word8 -> Color
    ISOColor 13
    brightCyan :: Color
    brightCyan   = Word8 -> Color
    ISOColor 14
    brightWhite :: Color
    brightWhite  = Word8 -> Color
    ISOColor 15

    -- | Create a Vty 'Color' (in the 240 color set) from an RGB triple.
    -- This function is lossy in the sense that we only internally support 240 colors but the
    -- #RRGGBB format supports 16^3 colors.
    rgbColor :: Integral i => i -> i -> i -> Color
    rgbColor :: i -> i -> i -> Color
    rgbColor r :: i
    r g :: i
    g b :: i
    b = Word8 -> Color
    Color240 (i -> i -> i -> Word8
    forall i. Integral i => i -> i -> i -> Word8
    rgbColorToColor240 i
    r i
    g i
    b)