    {-# LANGUAGE CPP#-}
    {-# LANGUAGE OverloadedStrings #-}

    module SDL.Filesystem
      ( -- * Filesystem Paths
        getBasePath
      , getPrefPath
    ) where

    import Control.Exception
    import Control.Monad.IO.Class (MonadIO, liftIO)
    import Data.Text (Text)
    import Foreign.Marshal.Alloc
    import SDL.Internal.Exception
    import qualified Data.ByteString as BS
    import qualified Data.Text.Encoding as Text
    import qualified SDL.Raw.Filesystem as Raw

    #if !MIN_VERSION_base(4,8,0)
    import Control.Applicative
    #endif

    -- | An absolute path to the application data directory.
    --
    -- The path is guaranteed to end with a path separator.
    --
    -- Throws 'SDLException' on failure, or if the platform does not implement this
    -- functionality.
    getBasePath :: MonadIO m => m Text
    getBasePath :: forall (m :: Type -> Type). MonadIO m => m Text
    getBasePath = IO Text -> m Text
    forall a. IO a -> m a
    forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
    liftIO (IO Text -> m Text) -> IO Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ IO Text -> IO Text
    forall a. IO a -> IO a
    mask_ (IO Text -> IO Text) -> IO Text -> IO Text
    forall a b. (a -> b) -> a -> b
    $ do
      cpath <- Text -> Text -> IO (Ptr CChar) -> IO (Ptr CChar)
    forall (m :: Type -> Type) a.
    MonadIO m =>
    Text -> Text -> m (Ptr a) -> m (Ptr a)
    throwIfNull Text
    "SDL.Filesystem.getBasePath" Text
    "SDL_GetBasePath"
        IO (Ptr CChar)
    forall (m :: Type -> Type). MonadIO m => m (Ptr CChar)
    Raw.getBasePath
      finally (Text.decodeUtf8 <$> BS.packCString cpath) (free cpath)

    -- | A path to a unique per user and per application directory for the given
    -- organization and application name, intended for writing preferences and
    -- other personal files.
    --
    -- The path is guaranteed to end with a path separator.
    --
    -- You should assume the path returned by this function is the only safe place
    -- to write files to.
    --
    -- Throws 'SDLException' on failure.
    getPrefPath :: MonadIO m => Text -> Text -> m Text
    getPrefPath :: forall (m :: Type -> Type). MonadIO m => Text -> Text -> m Text
    getPrefPath Text
    organization Text
    application = IO Text -> m Text
    forall a. IO a -> m a
    forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
    liftIO (IO Text -> m Text) -> IO Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ IO Text -> IO Text
    forall a. IO a -> IO a
    mask_ (IO Text -> IO Text) -> IO Text -> IO Text
    forall a b. (a -> b) -> a -> b
    $ do
      cpath <- Text -> Text -> IO (Ptr CChar) -> IO (Ptr CChar)
    forall (m :: Type -> Type) a.
    MonadIO m =>
    Text -> Text -> m (Ptr a) -> m (Ptr a)
    throwIfNull Text
    "SDL.Filesystem.getPrefPath" Text
    "SDL_GetPrefPath" (IO (Ptr CChar) -> IO (Ptr CChar))
    -> IO (Ptr CChar) -> IO (Ptr CChar)
    forall a b. (a -> b) -> a -> b
    $
        ByteString -> (Ptr CChar -> IO (Ptr CChar)) -> IO (Ptr CChar)
    forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
    BS.useAsCString (Text -> ByteString
    Text.encodeUtf8 Text
    organization) ((Ptr CChar -> IO (Ptr CChar)) -> IO (Ptr CChar))
    -> (Ptr CChar -> IO (Ptr CChar)) -> IO (Ptr CChar)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CChar
    org ->
          ByteString -> (Ptr CChar -> IO (Ptr CChar)) -> IO (Ptr CChar)
    forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
    BS.useAsCString (Text -> ByteString
    Text.encodeUtf8 Text
    application) ((Ptr CChar -> IO (Ptr CChar)) -> IO (Ptr CChar))
    -> (Ptr CChar -> IO (Ptr CChar)) -> IO (Ptr CChar)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CChar
    app ->
            Ptr CChar -> Ptr CChar -> IO (Ptr CChar)
    forall (m :: Type -> Type).
    MonadIO m =>
    Ptr CChar -> Ptr CChar -> m (Ptr CChar)
    Raw.getPrefPath Ptr CChar
    org Ptr CChar
    app
      finally (Text.decodeUtf8 <$> BS.packCString cpath) (free cpath)