{-# LANGUAGE GeneralizedNewtypeDeriving, RankNTypes #-}
-- | General content types and operations.
module Game.LambdaHack.Common.KindOps
  ( Id(Id), Ops(..)
  ) where

import Prelude ()

import Game.LambdaHack.Common.Prelude

import Data.Binary

import Game.LambdaHack.Common.Misc
import Game.LambdaHack.Common.Random

-- | Content identifiers for the content type @c@.
newtype Id c = Id Word16
  deriving (Show, Eq, Ord, Enum, Bounded, Binary)

-- | Content operations for the content of type @a@.
data Ops a = Ops
  { okind         :: !(Id a -> a)  -- ^ content element at given id
  , ouniqGroup    :: !(GroupName a -> Id a)
                                   -- ^ the id of the unique member of
                                   --   a singleton content group
  , opick         :: !(GroupName a -> (a -> Bool) -> Rnd (Maybe (Id a)))
                                   -- ^ pick a random id belonging to a group
                                   --   and satisfying a predicate
  , ofoldrWithKey :: !(forall b. (Id a -> a -> b -> b) -> b -> b)
                                   -- ^ fold over all content elements of @a@
  , ofoldlWithKey' :: !(forall b. (b -> Id a -> a -> b) -> b -> b)
                                   -- ^ fold strictly over all content @a@
  , ofoldlGroup'  :: !(forall b.
                     GroupName a -> (b -> Int -> Id a -> a -> b) -> b -> b)
                                   -- ^ fold over the given group only
  , olength       :: !Int          -- ^ size of content @a@
  }