------------------------------------------------------------------------
-- |
-- Module      :  ALife.Creatur.Tools.AgentNamer
-- Copyright   :  (c) Amy de Buitléir 2012-2013
-- License     :  BSD-style
-- Maintainer  :  amy@nualeargais.ie
-- Stability   :  experimental
-- Portability :  portable
--
-- Assigns a unique ID upon request. IDs generated by an @AgentNamer@ 
-- are guaranteed to be unique within a given universe, across all 
-- simulation runs.
--
------------------------------------------------------------------------
{-# LANGUAGE UnicodeSyntax #-}
module ALife.Creatur.AgentNamer
  (
    AgentNamer(..),
    SimpleAgentNamer,
    mkSimpleAgentNamer
  ) where

import ALife.Creatur (AgentId)
import ALife.Creatur.Counter (PersistentCounter, current, increment,
  mkPersistentCounter)
import ALife.Creatur.Util (stateMap)
import Control.Monad.State (StateT, get, gets)

class AgentNamer n where
  -- | Assign a unique ID using the supplied prefix.
  genName  StateT n IO AgentId

data SimpleAgentNamer = SimpleAgentNamer 
  {
    prefix  String,
    counter  PersistentCounter
  }

mkSimpleAgentNamer  String  FilePath  SimpleAgentNamer
mkSimpleAgentNamer s f = SimpleAgentNamer s $ mkPersistentCounter f

withCounter  StateT PersistentCounter IO x  StateT SimpleAgentNamer IO x
withCounter runProgram = do
  u  get
  stateMap (\c  u {counter=c}) counter runProgram

instance AgentNamer SimpleAgentNamer where
  genName = do
    p  gets prefix
    k  withCounter (increment >> current)
    return $ p ++ show k