{-#LANGUAGE GeneralizedNewtypeDeriving #-}
{-#LANGUAGE StandaloneDeriving #-}
{-#LANGUAGE CPP #-}
module Text.Tamper.DOM.AttribList
( AttribList
, attribLookup
, attribLookupDef
, attribDelete
, attribInsert
, attribItems
)
where

import Data.Monoid
import Data.Maybe
import Safe
#if MIN_VERSION_containers(0,5,0)
import qualified Data.Map.Strict as Map
import Data.Map.Strict (Map)
#else
import qualified Data.Map as Map
import Data.Map (Map)
#endif

newtype AttribList t = AttribList { unAttribList :: Map t t }

deriving instance (Show t) => Show (AttribList t)
deriving instance (Eq t) => Eq (AttribList t)
deriving instance (Ord t) => Ord (AttribList t)
deriving instance (Ord t) => Monoid (AttribList t)

attribLookup :: (Ord t) => t -> AttribList t -> Maybe t
attribLookup name = Map.lookup name . unAttribList

attribLookupDef :: (Ord t) => t -> t -> AttribList t -> t
attribLookupDef name def = fromMaybe def . attribLookup name

-- | "Lift" an operation on a list of attributes to an operation on an AttribList
attribLift :: (Map t t -> Map t t) -> AttribList t -> AttribList t
attribLift f = AttribList . f . unAttribList

attribDelete :: (Ord t) => t -> AttribList t -> AttribList t
attribDelete = attribLift . Map.delete

attribInsert :: (Ord t) => t -> t -> AttribList t -> AttribList t
attribInsert name value = attribLift $ Map.insert name value

attribItems :: AttribList t -> [(t, t)]
attribItems = Map.toList . unAttribList