module FF.CSS.Spec.Safe.Value.ColorAdjust 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.Base using
  ( CustomIdent
  ; RawValue
  ; renderCustomIdent
  ; renderRawValue
  )

private
  infixr 5 _++_

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

-- MDN CSS Color Adjustment property values:
-- https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_color_adjustment

data ColorSchemePreference : Type lzero where
  colorAdjustSchemeLight  : ColorSchemePreference
  colorAdjustSchemeDark   : ColorSchemePreference
  colorAdjustSchemeCustom : CustomIdent -> ColorSchemePreference

renderColorSchemePreference : ColorSchemePreference -> String
renderColorSchemePreference colorAdjustSchemeLight = "light"
renderColorSchemePreference colorAdjustSchemeDark = "dark"
renderColorSchemePreference (colorAdjustSchemeCustom value) = renderCustomIdent value

data ColorSchemePreferenceList : Type lzero where
  colorAdjustSchemePreferenceOne  : ColorSchemePreference -> ColorSchemePreferenceList
  colorAdjustSchemePreferenceCons : ColorSchemePreference -> ColorSchemePreferenceList -> ColorSchemePreferenceList

renderColorSchemePreferenceList : ColorSchemePreferenceList -> String
renderColorSchemePreferenceList (colorAdjustSchemePreferenceOne value) =
  renderColorSchemePreference value
renderColorSchemePreferenceList (colorAdjustSchemePreferenceCons value rest) =
  renderColorSchemePreference value ++ " " ++ renderColorSchemePreferenceList rest

data ColorSchemeOnly : Type lzero where
  colorAdjustSchemeWithoutOnly : ColorSchemeOnly
  colorAdjustSchemeWithOnly    : ColorSchemeOnly

data ColorScheme : Type lzero where
  colorAdjustSchemeNormal      : ColorScheme
  colorAdjustSchemePreferences : ColorSchemeOnly -> ColorSchemePreferenceList -> ColorScheme

renderColorScheme : ColorScheme -> String
renderColorScheme colorAdjustSchemeNormal = "normal"
renderColorScheme (colorAdjustSchemePreferences colorAdjustSchemeWithoutOnly values) =
  renderColorSchemePreferenceList values
renderColorScheme (colorAdjustSchemePreferences colorAdjustSchemeWithOnly values) =
  "only " ++ renderColorSchemePreferenceList values

record DynamicRangeLimitMix : Type lzero where
  constructor colorAdjustDynamicRangeLimitMix
  field rawDynamicRangeLimitMix : RawValue

open DynamicRangeLimitMix public

renderDynamicRangeLimitMix : DynamicRangeLimitMix -> String
renderDynamicRangeLimitMix (colorAdjustDynamicRangeLimitMix value) = renderRawValue value

data DynamicRangeLimit : Type lzero where
  colorAdjustDynamicRangeStandard    : DynamicRangeLimit
  colorAdjustDynamicRangeNoLimit     : DynamicRangeLimit
  colorAdjustDynamicRangeConstrained : DynamicRangeLimit
  colorAdjustDynamicRangeMix         : DynamicRangeLimitMix -> DynamicRangeLimit

renderDynamicRangeLimit : DynamicRangeLimit -> String
renderDynamicRangeLimit colorAdjustDynamicRangeStandard = "standard"
renderDynamicRangeLimit colorAdjustDynamicRangeNoLimit = "no-limit"
renderDynamicRangeLimit colorAdjustDynamicRangeConstrained = "constrained"
renderDynamicRangeLimit (colorAdjustDynamicRangeMix value) = renderDynamicRangeLimitMix value

data ForcedColorAdjust : Type lzero where
  colorAdjustForcedAuto                : ForcedColorAdjust
  colorAdjustForcedNone                : ForcedColorAdjust
  colorAdjustForcedPreserveParentColor : ForcedColorAdjust

renderForcedColorAdjust : ForcedColorAdjust -> String
renderForcedColorAdjust colorAdjustForcedAuto = "auto"
renderForcedColorAdjust colorAdjustForcedNone = "none"
renderForcedColorAdjust colorAdjustForcedPreserveParentColor = "preserve-parent-color"

data PrintColorAdjust : Type lzero where
  colorAdjustPrintEconomy : PrintColorAdjust
  colorAdjustPrintExact   : PrintColorAdjust

renderPrintColorAdjust : PrintColorAdjust -> String
renderPrintColorAdjust colorAdjustPrintEconomy = "economy"
renderPrintColorAdjust colorAdjustPrintExact = "exact"

data ColorAdjustPropertyName : Type lzero where
  colorAdjustColorSchemeProp       : ColorAdjustPropertyName
  colorAdjustDynamicRangeLimitProp : ColorAdjustPropertyName
  colorAdjustForcedColorAdjustProp : ColorAdjustPropertyName
  colorAdjustPrintColorAdjustProp  : ColorAdjustPropertyName

renderColorAdjustPropertyName : ColorAdjustPropertyName -> String
renderColorAdjustPropertyName colorAdjustColorSchemeProp = "color-scheme"
renderColorAdjustPropertyName colorAdjustDynamicRangeLimitProp = "dynamic-range-limit"
renderColorAdjustPropertyName colorAdjustForcedColorAdjustProp = "forced-color-adjust"
renderColorAdjustPropertyName colorAdjustPrintColorAdjustProp = "print-color-adjust"

data ColorAdjustPropertyValue : ColorAdjustPropertyName -> Type lzero where
  colorAdjustColorSchemeValue :
    ColorScheme -> ColorAdjustPropertyValue colorAdjustColorSchemeProp
  colorAdjustDynamicRangeLimitValue :
    DynamicRangeLimit -> ColorAdjustPropertyValue colorAdjustDynamicRangeLimitProp
  colorAdjustForcedColorAdjustValue :
    ForcedColorAdjust -> ColorAdjustPropertyValue colorAdjustForcedColorAdjustProp
  colorAdjustPrintColorAdjustValue :
    PrintColorAdjust -> ColorAdjustPropertyValue colorAdjustPrintColorAdjustProp

renderColorAdjustPropertyValue :
  (propertyName : ColorAdjustPropertyName) ->
  ColorAdjustPropertyValue propertyName ->
  String
renderColorAdjustPropertyValue colorAdjustColorSchemeProp (colorAdjustColorSchemeValue value) =
  renderColorScheme value
renderColorAdjustPropertyValue
  colorAdjustDynamicRangeLimitProp
  (colorAdjustDynamicRangeLimitValue value) =
  renderDynamicRangeLimit value
renderColorAdjustPropertyValue
  colorAdjustForcedColorAdjustProp
  (colorAdjustForcedColorAdjustValue value) =
  renderForcedColorAdjust value
renderColorAdjustPropertyValue colorAdjustPrintColorAdjustProp (colorAdjustPrintColorAdjustValue value) =
  renderPrintColorAdjust value

record ColorAdjustPropertyPair : Type lzero where
  constructor colorAdjustPair
  field
    colorAdjustPairName  : ColorAdjustPropertyName
    colorAdjustPairValue : ColorAdjustPropertyValue colorAdjustPairName

open ColorAdjustPropertyPair public

renderColorAdjustPropertyPair : ColorAdjustPropertyPair -> String
renderColorAdjustPropertyPair (colorAdjustPair propertyName value) =
  renderColorAdjustPropertyName propertyName ++ ": " ++
  renderColorAdjustPropertyValue propertyName value