-- | This module contains functions for serializing plugin
-- state to disk if it ever needs it. The State directory is
-- laid out in a certain hierarchy, so all plugins *must*
-- go through this interface.
module Infinity.State (
 putState,
 getState
) where
import Data.Binary
import Control.Monad
import System.FilePath
import System.Directory
import Infinity.Util

-- | This function takes the name of the plugin
-- and a value that must be an instance of Binary.
-- It simply falls back onto Data.Binary.encodeFile.
putState :: Binary a 
         => String -- ^ Name of the plugin, i.e. 'foo'
         -> a      -- ^ Actual value to be serialized to file
         -> IO ()
putState n v = do
  let file = stFile n
  whenM (doesFileExist file) $ removeFile file
  encodeFile file v



-- | This function retrieves a value from a state file.
-- It takes the name of the plugin and returns the data.
-- return either @Nothing@ when the state doesn't yet exist,
-- or @Just a@ with the /a/ being the value.
getState :: Binary a
         => String -- ^ Plugin name
         -> IO (Maybe a)
getState n = do
  let file = stFile n
  b <- doesFileExist file
  if b then decodeFile file >>= return . Just
   else return Nothing



-- Convenience function
stFile :: String -> FilePath
stFile n = joinPath ["State",(n++".st")]
