{-# LANGUAGE OverloadedStrings #-}
module Clay.Pseudo where

import Data.Text (Text)

import Clay.Render (renderSelector)
import Clay.Selector

import qualified Data.Text.Lazy as Lazy

-- List of specific pseudo classes, from:
-- https://developer.mozilla.org/en-US/docs/CSS/Pseudo-classes

-- * Pseudo elements

after, before, firstLetter, firstLine, selection, backdrop :: Refinement

after :: Refinement
after       = Refinement
"::after"
before :: Refinement
before      = Refinement
"::before"
firstLetter :: Refinement
firstLetter = Refinement
"::first-letter"
firstLine :: Refinement
firstLine   = Refinement
"::first-line"
selection :: Refinement
selection   = Refinement
"::selection"
backdrop :: Refinement
backdrop    = Refinement
"::backdrop"

-- * Pseudo classes
link, visited, active, hover, focus, firstChild, lastChild :: Refinement

link :: Refinement
link       = Refinement
":link"
visited :: Refinement
visited    = Refinement
":visited"
active :: Refinement
active     = Refinement
":active"
hover :: Refinement
hover      = Refinement
":hover"
focus :: Refinement
focus      = Refinement
":focus"
firstChild :: Refinement
firstChild = Refinement
":first-child"
lastChild :: Refinement
lastChild  = Refinement
":last-child"

checked, default_, disabled, empty, enabled, firstOfType, indeterminate,
  inRange, invalid, lastOfType, onlyChild, onlyOfType, optional,
  outOfRange, required, root, target, valid :: Refinement

checked :: Refinement
checked       = Refinement
":checked"
default_ :: Refinement
default_      = Refinement
":default"
disabled :: Refinement
disabled      = Refinement
":disabled"
empty :: Refinement
empty         = Refinement
":empty"
enabled :: Refinement
enabled       = Refinement
":enabled"
firstOfType :: Refinement
firstOfType   = Refinement
":first-of-type"
indeterminate :: Refinement
indeterminate = Refinement
":indeterminate"
inRange :: Refinement
inRange       = Refinement
":in-range"
invalid :: Refinement
invalid       = Refinement
":invalid"
lastOfType :: Refinement
lastOfType    = Refinement
":last-of-type"
onlyChild :: Refinement
onlyChild     = Refinement
":only-child"
onlyOfType :: Refinement
onlyOfType    = Refinement
":only-of-type"
optional :: Refinement
optional      = Refinement
":optional"
outOfRange :: Refinement
outOfRange    = Refinement
":out-of-range"
required :: Refinement
required      = Refinement
":required"
root :: Refinement
root          = Refinement
":root"
target :: Refinement
target        = Refinement
":target"
valid :: Refinement
valid         = Refinement
":valid"

lang, nthChild, nthLastChild, nthLastOfType, nthOfType :: Text -> Refinement

lang :: Text -> Refinement
lang          Text
n = Text -> [Text] -> Refinement
func Text
"lang"             [Text
n]
nthChild :: Text -> Refinement
nthChild      Text
n = Text -> [Text] -> Refinement
func Text
"nth-child"        [Text
n]
nthLastChild :: Text -> Refinement
nthLastChild  Text
n = Text -> [Text] -> Refinement
func Text
"nth-last-child"   [Text
n]
nthLastOfType :: Text -> Refinement
nthLastOfType Text
n = Text -> [Text] -> Refinement
func Text
"nth-last-of-type" [Text
n]
nthOfType :: Text -> Refinement
nthOfType     Text
n = Text -> [Text] -> Refinement
func Text
"nth-of-type"      [Text
n]

not :: Selector -> Refinement
not :: Selector -> Refinement
not Selector
r = Text -> [Text] -> Refinement
func Text
"not" [Text -> Text
Lazy.toStrict (Selector -> Text
renderSelector Selector
r)]