{-# OPTIONS -Wall #-}
module Raylib.Util (c'free, pop, popCArray, withArray2D, configsToBitflag) where

import Raylib.Types (ConfigFlag)
import Foreign (Ptr, Storable (peek), castPtr, newArray, free, peekArray)
import Control.Monad (forM_)
import Data.Bits ((.|.))
-- Internal utility functions


foreign import ccall "stdlib.h free" c'free :: Ptr () -> IO ()

pop :: (Storable a) => Ptr a -> IO a
pop :: forall a. Storable a => Ptr a -> IO a
pop Ptr a
ptr = do
    a
val <- forall a. Storable a => Ptr a -> IO a
peek Ptr a
ptr
    Ptr () -> IO ()
c'free forall a b. (a -> b) -> a -> b
$ forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr
    forall (m :: * -> *) a. Monad m => a -> m a
return a
val

popCArray :: (Storable a) => Int -> Ptr a -> IO [a]
popCArray :: forall a. Storable a => Int -> Ptr a -> IO [a]
popCArray Int
count Ptr a
ptr = do
    [a]
str <- forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
count Ptr a
ptr
    Ptr () -> IO ()
c'free forall a b. (a -> b) -> a -> b
$ forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr
    forall (m :: * -> *) a. Monad m => a -> m a
return [a]
str

withArray2D :: (Storable a) => [[a]] -> (Ptr (Ptr a) -> IO b) -> IO b
withArray2D :: forall a b. Storable a => [[a]] -> (Ptr (Ptr a) -> IO b) -> IO b
withArray2D [[a]]
arr Ptr (Ptr a) -> IO b
func = do
    [Ptr a]
arrays <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. Storable a => [a] -> IO (Ptr a)
newArray [[a]]
arr
    Ptr (Ptr a)
ptr <- forall a. Storable a => [a] -> IO (Ptr a)
newArray [Ptr a]
arrays
    b
res <- Ptr (Ptr a) -> IO b
func Ptr (Ptr a)
ptr
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Ptr a]
arrays forall a. Ptr a -> IO ()
free
    forall a. Ptr a -> IO ()
free Ptr (Ptr a)
ptr
    forall (m :: * -> *) a. Monad m => a -> m a
return b
res

configsToBitflag :: [ConfigFlag] -> Integer
configsToBitflag :: [ConfigFlag] -> Integer
configsToBitflag = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {a}. Enum a => a -> Int -> Int
folder (forall a. Enum a => Int -> a
toEnum Int
0) 
    where folder :: a -> Int -> Int
folder a
a Int
b = (forall a. Enum a => a -> Int
fromEnum a
a) forall a. Bits a => a -> a -> a
.|. Int
b