module Heist.Splices.Html where

------------------------------------------------------------------------------
import           Data.Maybe
import           Data.Text (Text)
import qualified Text.XmlHtml as X

------------------------------------------------------------------------------
import           Heist.Interpreted.Internal
import           Heist.Internal.Types.HeistState


------------------------------------------------------------------------------
-- | Name for the html splice.
htmlTag :: Text
htmlTag = "html"


------------------------------------------------------------------------------
-- | The html splice runs all children and then traverses the returned node
-- forest removing all head nodes.  Then it merges them all and prepends it to
-- the html tag's child list.
htmlImpl :: Monad n => Splice n
htmlImpl = do
    node <- getParamNode
    children <- runNodeList $ X.childNodes node
    let (heads, mnode) = extractHeads $ node { X.elementChildren = children }
        new (X.Element t a c) = X.Element t a $
            X.Element "head" [] heads : c
        new n = n
    stopRecursion
    return [maybe node new mnode]

------------------------------------------------------------------------------
-- | Extracts all heads from a node tree.
extractHeads :: X.Node
             -- ^ The root (html) node
             -> ([X.Node], Maybe X.Node)
             -- ^ A tuple of a list of head nodes and the original tree with
             --   heads removed.
extractHeads (X.Element t a c)
  | t == "head" = (c, Nothing)
  | otherwise   = (concat heads, Just $ X.Element t a (catMaybes mcs))
  where
    (heads, mcs) = unzip $ map extractHeads c
extractHeads n = ([], Just n)