module Lighthouse.Utils.Color where

import qualified Data.ByteString.Lazy as BL
import Lighthouse.Utils.Serializable
import System.Random

-- | An RGB color.
data Color = Color Int Int Int
    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
$cshowsPrec :: Int -> Color -> ShowS
showsPrec :: Int -> Color -> ShowS
$cshow :: Color -> String
show :: Color -> String
$cshowList :: [Color] -> ShowS
showList :: [Color] -> ShowS
Show, Color -> Color -> Bool
(Color -> Color -> Bool) -> (Color -> Color -> Bool) -> Eq Color
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Color -> Color -> Bool
== :: Color -> Color -> Bool
$c/= :: Color -> Color -> Bool
/= :: Color -> Color -> Bool
Eq)

instance Random Color where
    random :: forall g. RandomGen g => g -> (Color, g)
random g
gen = (Int -> Int -> Int -> Color
Color Int
r Int
g Int
b, g
gen3)
        where (Int
r, g
gen1) = g -> (Int, g)
forall g. RandomGen g => g -> (Int, g)
next g
gen
              (Int
g, g
gen2) = g -> (Int, g)
forall g. RandomGen g => g -> (Int, g)
next g
gen1
              (Int
b, g
gen3) = g -> (Int, g)
forall g. RandomGen g => g -> (Int, g)
next g
gen2
    
    randomR :: forall g. RandomGen g => (Color, Color) -> g -> (Color, g)
randomR (Color Int
lr Int
lg Int
lb, Color Int
hr Int
hg Int
hb) g
gen = (Int -> Int -> Int -> Color
Color Int
r Int
g Int
b, g
gen3)
        where (Int
r, g
gen1) = (Int, Int) -> g -> (Int, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
forall g. RandomGen g => (Int, Int) -> g -> (Int, g)
randomR (Int
lr, Int
hr) g
gen
              (Int
g, g
gen2) = (Int, Int) -> g -> (Int, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
forall g. RandomGen g => (Int, Int) -> g -> (Int, g)
randomR (Int
lg, Int
hg) g
gen1
              (Int
b, g
gen3) = (Int, Int) -> g -> (Int, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
forall g. RandomGen g => (Int, Int) -> g -> (Int, g)
randomR (Int
lb, Int
hb) g
gen2

instance Serializable Color where
    serialize :: Color -> ByteString
serialize (Color Int
r Int
g Int
b) = [Word8] -> ByteString
BL.pack [Word8
r', Word8
g', Word8
b']
        where r' :: Word8
r' = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
r
              g' :: Word8
g' = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
g
              b' :: Word8
b' = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b

black :: Color
black :: Color
black = Int -> Int -> Int -> Color
Color Int
0 Int
0 Int
0

gray :: Color
gray :: Color
gray = Int -> Int -> Int -> Color
Color Int
128 Int
128 Int
128

white :: Color
white :: Color
white = Int -> Int -> Int -> Color
Color Int
255 Int
255 Int
255

red :: Color
red :: Color
red = Int -> Int -> Int -> Color
Color Int
255 Int
0 Int
0

green :: Color
green :: Color
green = Int -> Int -> Int -> Color
Color Int
0 Int
255 Int
0

blue :: Color
blue :: Color
blue = Int -> Int -> Int -> Color
Color Int
0 Int
0 Int
255

yellow :: Color
yellow :: Color
yellow = Int -> Int -> Int -> Color
Color Int
255 Int
255 Int
0

magenta :: Color
magenta :: Color
magenta = Int -> Int -> Int -> Color
Color Int
255 Int
0 Int
255

cyan :: Color
cyan :: Color
cyan = Int -> Int -> Int -> Color
Color Int
0 Int
255 Int
255