{-# LANGUAGE DeriveDataTypeable #-}
module Internal.Types
    ( DTree (..)
    , DElemType (..)
    , DAttr (..)
    ) where

import qualified Data.Text as T
import Data.Data
import qualified Data.Map as M

-- DOM tree: either a text node or an element with some children
data DTree = DText T.Text
           | DElem DElemType DAttr [DTree]
    deriving (Eq)

instance Show DTree where
    show (DText t) = T.unpack t
    show (DElem et attr ch) = open ++ children ++ close
        where
            open = "<" ++ show et ++ printedAttrs ++ ">"
            printedAttrs = let pa = show attr in
                if pa == "" then "" else " " ++ pa
            close = "</" ++ show et ++ ">"
            children = concatMap show ch

-- Supported HTML elements
data DElemType = DHtml
               | DBody
               | DDiv
               | DH1
               | DP
    deriving (Eq, Ord, Data, Typeable)

instance Show DElemType where
    show et = case et of
        DHtml -> "html"
        DBody -> "body"
        DDiv -> "div"
        DH1 -> "h1"
        DP -> "p"

-- HTML element attributes (key-value pairs)
newtype DAttr = DAttr { attributes :: M.Map T.Text T.Text }
    deriving (Eq)

instance Show DAttr where
    show (DAttr attr) =
        let fn (k, v) = T.unpack k ++ "=\"" ++ T.unpack v ++ "\""
        in unwords . map fn $ M.toList attr
