module System.FileSystem.Class
 ( FSMonad (..)
 , modifyFS
 , apgetFS
   ) where

import System.FileSystem.Types
--
import Control.Applicative ((<$>))
-- MTL Monad transformers
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.RWS
import Control.Monad.Error
import Control.Monad.List
import Control.Monad.Cont

class (Functor m, Monad m) => FSMonad m where
 getFS :: m FSState
 putFS :: FSState -> m ()

instance (Functor m, Monad m) => FSMonad (FST m) where
 getFS = WrapFST get
 putFS = WrapFST . put

modifyFS :: FSMonad m => InApp FSState -> m ()
modifyFS f = getFS >>= putFS . f

apgetFS :: FSMonad m => (FSState -> a) -> m a
apgetFS = (<$> getFS)

--

instance FSMonad m => FSMonad (ReaderT r m) where
 getFS = lift getFS
 putFS = lift . putFS

instance (Monoid w, FSMonad m) => FSMonad (WriterT w m) where
 getFS = lift getFS
 putFS = lift . putFS

instance FSMonad m => FSMonad (StateT s m) where
 getFS = lift getFS
 putFS = lift . putFS

instance (Monoid w, FSMonad m) => FSMonad (RWST r w s m) where
 getFS = lift getFS
 putFS = lift . putFS

instance (Error e, FSMonad m) => FSMonad (ErrorT e m) where
 getFS = lift getFS
 putFS = lift . putFS

instance FSMonad m => FSMonad (ListT m) where
 getFS = lift getFS
 putFS = lift . putFS

instance FSMonad m => FSMonad (ContT r m) where
 getFS = lift getFS
 putFS = lift . putFS