module FF.CSS.Spec.Safe.Value.Color where

open import Agda.Builtin.String using (String; primStringAppend)
open import Agda.Primitive using (lzero) renaming (Set to Type)

open import FF.CSS.Spec.Safe.Value.Unit using (Number; Percentage; renderNumber; renderPercentage)

private
  infixr 5 _++_

  _++_ : String -> String -> String
  _++_ = primStringAppend

-- MDN <color> value reference:
-- https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
data NamedColor : Type lzero where
  aliceblue black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua orange rebeccapurple : NamedColor

renderNamedColor : NamedColor -> String
renderNamedColor aliceblue = "aliceblue"
renderNamedColor black = "black"
renderNamedColor silver = "silver"
renderNamedColor gray = "gray"
renderNamedColor white = "white"
renderNamedColor maroon = "maroon"
renderNamedColor red = "red"
renderNamedColor purple = "purple"
renderNamedColor fuchsia = "fuchsia"
renderNamedColor green = "green"
renderNamedColor lime = "lime"
renderNamedColor olive = "olive"
renderNamedColor yellow = "yellow"
renderNamedColor navy = "navy"
renderNamedColor blue = "blue"
renderNamedColor teal = "teal"
renderNamedColor aqua = "aqua"
renderNamedColor orange = "orange"
renderNamedColor rebeccapurple = "rebeccapurple"

record HexColor : Type lzero where
  constructor hexColor
  field rawHexColor : String

open HexColor public

renderHexColor : HexColor -> String
renderHexColor (hexColor raw) = raw

data AlphaValue : Type lzero where
  alphaNumber     : Number -> AlphaValue
  alphaPercentage : Percentage -> AlphaValue

renderAlphaValue : AlphaValue -> String
renderAlphaValue (alphaNumber value) = renderNumber value
renderAlphaValue (alphaPercentage value) = renderPercentage value

data Color : Type lzero where
  named        : NamedColor -> Color
  transparent  : Color
  currentColor : Color
  hex          : HexColor -> Color
  rgb          : Number -> Number -> Number -> Color
  rgba         : Number -> Number -> Number -> AlphaValue -> Color
  hsl          : Number -> Percentage -> Percentage -> Color
  hsla         : Number -> Percentage -> Percentage -> AlphaValue -> Color
  colorFunction : String -> Color

renderColor : Color -> String
renderColor (named value) = renderNamedColor value
renderColor transparent = "transparent"
renderColor currentColor = "currentColor"
renderColor (hex value) = renderHexColor value
renderColor (rgb r g b) =
  "rgb(" ++ renderNumber r ++ " " ++ renderNumber g ++ " " ++ renderNumber b ++ ")"
renderColor (rgba r g b alpha) =
  "rgb(" ++ renderNumber r ++ " " ++ renderNumber g ++ " " ++ renderNumber b ++ " / " ++ renderAlphaValue alpha ++ ")"
renderColor (hsl h s l) =
  "hsl(" ++ renderNumber h ++ " " ++ renderPercentage s ++ " " ++ renderPercentage l ++ ")"
renderColor (hsla h s l alpha) =
  "hsl(" ++ renderNumber h ++ " " ++ renderPercentage s ++ " " ++ renderPercentage l ++ " / " ++ renderAlphaValue alpha ++ ")"
renderColor (colorFunction raw) = raw