module SDL.Raw.Filesystem (
  -- * Filesystem Paths
  getBasePath,
  getPrefPath,

  -- * File I/O Abstraction
  allocRW,
  freeRW,
  rwFromConstMem,
  rwFromFP,
  rwFromFile,
  rwFromMem,
  rwClose,
  rwRead,
  rwSeek,
  rwTell,
  rwWrite,
  readBE16,
  readBE32,
  readBE64,
  readLE16,
  readLE32,
  readLE64,
  writeBE16,
  writeBE32,
  writeBE64,
  writeLE16,
  writeLE32,
  writeLE64
) where

import Control.Monad.IO.Class
import Data.Int
import Data.Word
import Foreign.C.String
import Foreign.C.Types
import Foreign.Ptr
import SDL.Raw.Types

foreign import ccall "SDL.h SDL_GetBasePath" getBasePathFFI :: IO CString
foreign import ccall "SDL.h SDL_GetPrefPath" getPrefPathFFI :: CString -> CString -> IO CString

foreign import ccall "SDL.h SDL_AllocRW" allocRWFFI :: IO (Ptr RWops)
foreign import ccall "SDL.h SDL_FreeRW" freeRWFFI :: Ptr RWops -> IO ()
foreign import ccall "SDL.h SDL_RWFromConstMem" rwFromConstMemFFI :: Ptr () -> CInt -> IO (Ptr RWops)
foreign import ccall "SDL.h SDL_RWFromFP" rwFromFPFFI :: Ptr () -> Bool -> IO (Ptr RWops)
foreign import ccall "SDL.h SDL_RWFromFile" rwFromFileFFI :: CString -> CString -> IO (Ptr RWops)
foreign import ccall "SDL.h SDL_RWFromMem" rwFromMemFFI :: Ptr () -> CInt -> IO (Ptr RWops)
foreign import ccall "sdlhelper.h SDLHelper_RWclose" rwCloseFFI :: Ptr RWops -> IO CInt
foreign import ccall "sdlhelper.h SDLHelper_RWread" rwReadFFI :: Ptr RWops -> Ptr () -> CSize -> CSize -> IO CSize
foreign import ccall "sdlhelper.h SDLHelper_RWseek" rwSeekFFI :: Ptr RWops -> Int64 -> CInt -> IO Int64
foreign import ccall "sdlhelper.h SDLHelper_RWtell" rwTellFFI :: Ptr RWops -> IO Int64
foreign import ccall "sdlhelper.h SDLHelper_RWwrite" rwWriteFFI :: Ptr RWops -> Ptr () -> CSize -> CSize -> IO CSize
foreign import ccall "SDL.h SDL_ReadBE16" readBE16FFI :: Ptr RWops -> IO Word16
foreign import ccall "SDL.h SDL_ReadBE32" readBE32FFI :: Ptr RWops -> IO Word32
foreign import ccall "SDL.h SDL_ReadBE64" readBE64FFI :: Ptr RWops -> IO Word64
foreign import ccall "SDL.h SDL_ReadLE16" readLE16FFI :: Ptr RWops -> IO Word16
foreign import ccall "SDL.h SDL_ReadLE32" readLE32FFI :: Ptr RWops -> IO Word32
foreign import ccall "SDL.h SDL_ReadLE64" readLE64FFI :: Ptr RWops -> IO Word64
foreign import ccall "SDL.h SDL_WriteBE16" writeBE16FFI :: Ptr RWops -> Word16 -> IO CSize
foreign import ccall "SDL.h SDL_WriteBE32" writeBE32FFI :: Ptr RWops -> Word32 -> IO CSize
foreign import ccall "SDL.h SDL_WriteBE64" writeBE64FFI :: Ptr RWops -> Word64 -> IO CSize
foreign import ccall "SDL.h SDL_WriteLE16" writeLE16FFI :: Ptr RWops -> Word16 -> IO CSize
foreign import ccall "SDL.h SDL_WriteLE32" writeLE32FFI :: Ptr RWops -> Word32 -> IO CSize
foreign import ccall "SDL.h SDL_WriteLE64" writeLE64FFI :: Ptr RWops -> Word64 -> IO CSize

getBasePath :: MonadIO m => m CString
getBasePath = liftIO getBasePathFFI
{-# INLINE getBasePath #-}

getPrefPath :: MonadIO m => CString -> CString -> m CString
getPrefPath v1 v2 = liftIO $ getPrefPathFFI v1 v2
{-# INLINE getPrefPath #-}

allocRW :: MonadIO m => m (Ptr RWops)
allocRW = liftIO allocRWFFI
{-# INLINE allocRW #-}

freeRW :: MonadIO m => Ptr RWops -> m ()
freeRW v1 = liftIO $ freeRWFFI v1
{-# INLINE freeRW #-}

rwFromConstMem :: MonadIO m => Ptr () -> CInt -> m (Ptr RWops)
rwFromConstMem v1 v2 = liftIO $ rwFromConstMemFFI v1 v2
{-# INLINE rwFromConstMem #-}

rwFromFP :: MonadIO m => Ptr () -> Bool -> m (Ptr RWops)
rwFromFP v1 v2 = liftIO $ rwFromFPFFI v1 v2
{-# INLINE rwFromFP #-}

rwFromFile :: MonadIO m => CString -> CString -> m (Ptr RWops)
rwFromFile v1 v2 = liftIO $ rwFromFileFFI v1 v2
{-# INLINE rwFromFile #-}

rwFromMem :: MonadIO m => Ptr () -> CInt -> m (Ptr RWops)
rwFromMem v1 v2 = liftIO $ rwFromMemFFI v1 v2
{-# INLINE rwFromMem #-}

rwClose :: MonadIO m => Ptr RWops -> m CInt
rwClose v1 = liftIO $ rwCloseFFI v1
{-# INLINE rwClose #-}

rwRead :: MonadIO m => Ptr RWops -> Ptr () -> CSize -> CSize -> m CSize
rwRead v1 v2 v3 v4 = liftIO $ rwReadFFI v1 v2 v3 v4
{-# INLINE rwRead #-}

rwSeek :: MonadIO m => Ptr RWops -> Int64 -> CInt -> m Int64
rwSeek v1 v2 v3 = liftIO $ rwSeekFFI v1 v2 v3
{-# INLINE rwSeek #-}

rwTell :: MonadIO m => Ptr RWops -> m Int64
rwTell v1 = liftIO $ rwTellFFI v1
{-# INLINE rwTell #-}

rwWrite :: MonadIO m => Ptr RWops -> Ptr () -> CSize -> CSize -> m CSize
rwWrite v1 v2 v3 v4 = liftIO $ rwWriteFFI v1 v2 v3 v4
{-# INLINE rwWrite #-}

readBE16 :: MonadIO m => Ptr RWops -> m Word16
readBE16 v1 = liftIO $ readBE16FFI v1
{-# INLINE readBE16 #-}

readBE32 :: MonadIO m => Ptr RWops -> m Word32
readBE32 v1 = liftIO $ readBE32FFI v1
{-# INLINE readBE32 #-}

readBE64 :: MonadIO m => Ptr RWops -> m Word64
readBE64 v1 = liftIO $ readBE64FFI v1
{-# INLINE readBE64 #-}

readLE16 :: MonadIO m => Ptr RWops -> m Word16
readLE16 v1 = liftIO $ readLE16FFI v1
{-# INLINE readLE16 #-}

readLE32 :: MonadIO m => Ptr RWops -> m Word32
readLE32 v1 = liftIO $ readLE32FFI v1
{-# INLINE readLE32 #-}

readLE64 :: MonadIO m => Ptr RWops -> m Word64
readLE64 v1 = liftIO $ readLE64FFI v1
{-# INLINE readLE64 #-}

writeBE16 :: MonadIO m => Ptr RWops -> Word16 -> m CSize
writeBE16 v1 v2 = liftIO $ writeBE16FFI v1 v2
{-# INLINE writeBE16 #-}

writeBE32 :: MonadIO m => Ptr RWops -> Word32 -> m CSize
writeBE32 v1 v2 = liftIO $ writeBE32FFI v1 v2
{-# INLINE writeBE32 #-}

writeBE64 :: MonadIO m => Ptr RWops -> Word64 -> m CSize
writeBE64 v1 v2 = liftIO $ writeBE64FFI v1 v2
{-# INLINE writeBE64 #-}

writeLE16 :: MonadIO m => Ptr RWops -> Word16 -> m CSize
writeLE16 v1 v2 = liftIO $ writeLE16FFI v1 v2
{-# INLINE writeLE16 #-}

writeLE32 :: MonadIO m => Ptr RWops -> Word32 -> m CSize
writeLE32 v1 v2 = liftIO $ writeLE32FFI v1 v2
{-# INLINE writeLE32 #-}

writeLE64 :: MonadIO m => Ptr RWops -> Word64 -> m CSize
writeLE64 v1 v2 = liftIO $ writeLE64FFI v1 v2
{-# INLINE writeLE64 #-}