module DarkPlaces.Text.Colors (
RGB(..),
getRGB,
getColor,
simplifyColor,
hReset
) where
import Data.Bits
import System.Console.ANSI
import System.IO (Handle)
newtype RGB = RGB (Int, Int, Int) deriving(Show, Eq)
newtype HSV = HSV (Double, Double, Double) deriving(Show, Eq)
getRGB :: Int -> RGB
getRGB c = RGB (shiftR c 8 .&. 0xff, shiftR c 4 .&. 0xf , c .&. 0xf)
scaleRGB :: RGB -> Int -> RGB
scaleRGB (RGB (r, g, b)) s = RGB (r * s, g * s, b * s)
minMaxRGB :: (Num a, Ord a) => a -> a -> a -> (a, a)
minMaxRGB r g b = if r > g
then if r > b
then (if g < b then g else b, r)
else (g, b)
else if g > b
then (if b < r then b else r, g)
else (r, b)
rgbToHSV :: RGB -> HSV
rgbToHSV (RGB (r, g, b)) = HSV (hue, saturation, value)
where
(min, max) = minMaxRGB r g b
delta = fromIntegral $ max min :: Double
hue
| min == max = 0
| r == max = fromIntegral (60 * (g b)) / delta
| g == max = fromIntegral (60 * (b r)) / delta + 120
| otherwise = fromIntegral (60 * (r g)) / delta + 240
saturation = if max == 0 then 0 else 1 fromIntegral min / fromIntegral max
value = fromIntegral max / 255
simplifyColor :: Int -> Int
simplifyColor hex_c
| s < 0.2 && v < 0.5 = 0
| s < 0.2 = 7
| h < 36 = 1
| h < 80 = 3
| h < 150 = 2
| h < 200 = 5
| h < 270 = 4
| h < 330 = 6
| otherwise = 1
where
rgb = scaleRGB (getRGB hex_c) 17
HSV (h, s, v) = rgbToHSV rgb
getColor :: Int -> [SGR]
getColor 1 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Red]
getColor 2 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Green]
getColor 3 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Yellow]
getColor 4 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Blue]
getColor 5 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Cyan]
getColor 6 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Magenta]
getColor n
| n == 0 || n == 7 = [Reset]
| n == 8 || n == 9 = [SetConsoleIntensity BoldIntensity, SetColor Foreground Dull Black]
| otherwise = []
hReset :: Handle -> IO ()
hReset h = hSetSGR h [Reset]