{-|
Module      : Dep.Bricks.Palette
Description : A module to aims to make it easier to select colors that are distant from each other.
Maintainer  : hapytexeu+gh@gmail.com
Stability   : experimental
Portability : POSIX

This module generates palettes. A 'Palette' is an infinite list of 'Color's that endlessly repeats
itself. This is used to obtain colors to typeset different items on the screen.
-}

module Dep.Bricks.Palette (
    -- * Palettes
    Palette, isoColorPalette, brightIsoColorPalette, color240Palette
    -- * Determine other color for 'ISOColor's
  , swapIsoColorBright, isoColorToBright, isoColorFromBright
  ) where

import Graphics.Vty.Attributes.Color(Color(ISOColor, Color240))

-- | A palette is an (endless) list of 'Color's.
type Palette = [Color]

-- | Work with a color palette of the six ISO colors.
isoColorPalette
  :: Palette  -- ^ A palette that endlessly repeats itself and exhaustively enumerates the possible /ISO colors/.
isoColorPalette :: Palette
isoColorPalette = Palette -> Palette
forall a. [a] -> [a]
cycle (Word8 -> Color
ISOColor (Word8 -> Color) -> [Word8] -> Palette
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ Word8
1 .. Word8
6 ])

-- | Work with a color palette of the six ISO colors.
brightIsoColorPalette
  :: Palette  -- ^ A palette that endlessly repeats itself and exhaustively enumerates the possible /ISO colors/.
brightIsoColorPalette :: Palette
brightIsoColorPalette = Palette -> Palette
forall a. [a] -> [a]
cycle (Word8 -> Color
ISOColor (Word8 -> Color) -> [Word8] -> Palette
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ Word8
9 .. Word8
14 ])

-- | Swap between the bright mode and the normal mode of the given 'Color'.
swapIsoColorBright
  :: Color  -- ^ The given 'Color' to convert to a more/less bright color.
  -> Color  -- ^ The corresponding variant that is more/less bright of the given 'Color'.
swapIsoColorBright :: Color -> Color
swapIsoColorBright (ISOColor Word8
i)
  | Word8
i Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
8 = Word8 -> Color
ISOColor (Word8
iWord8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+Word8
8)
  | Bool
otherwise = Word8 -> Color
ISOColor (Word8
iWord8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
-Word8
8)
swapIsoColorBright Color
x = Color
x

-- | Create the brighter color
isoColorToBright
  :: Color  -- ^ The given 'Color' to make /bright/.
  -> Color  -- ^ The corresponding /bright/ variant of the given 'Color'.
isoColorToBright :: Color -> Color
isoColorToBright (ISOColor Word8
i)
  | Word8
i Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
8 = Word8 -> Color
ISOColor (Word8
iWord8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+Word8
8)
isoColorToBright Color
x = Color
x

-- | Obtain the equivalent color that is /not/ bright.
isoColorFromBright
  :: Color  -- ^ The given 'Color' to make a 'Color' that is less bright.
  -> Color  -- ^ The corresponding less bright variant of the given 'Color'.
isoColorFromBright :: Color -> Color
isoColorFromBright (ISOColor Word8
i)
  | Word8
i Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
8 = Word8 -> Color
ISOColor (Word8
iWord8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
-Word8
8)
isoColorFromBright Color
x = Color
x

-- | Work with a color palette with 240 colors, but only 238 are selected, since black and white are not considered to be colors for the palette.
color240Palette
  :: Palette -- ^ A palette that endlessly repeats itself and exhaustively enumerates the possible /colors 240s/.
color240Palette :: Palette
color240Palette = Palette -> Palette
forall a. [a] -> [a]
cycle (Word8 -> Color
Color240 (Word8 -> Color) -> [Word8] -> Palette
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [Word8] -> [Word8]
forall a. Int -> [a] -> [a]
take Int
238 ((Word8 -> Word8) -> Word8 -> [Word8]
forall a. (a -> a) -> a -> [a]
iterate ((Word8
1Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+)(Word8 -> Word8) -> (Word8 -> Word8) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Word8 -> Word8
forall a. Integral a => a -> a -> a
`mod` Word8
238) (Word8 -> Word8) -> (Word8 -> Word8) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8
82Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+)) Word8
1))