-- Produced by boxnd-gen; edit the generator, not this file.

module Box2D.Chain
  ( create
  , destroy
  , getWorld
  , getSegmentCount
  , getSegments
  , getSurfaceMaterialCount
  , setSurfaceMaterial
  , getSurfaceMaterial
  , getSurfaceMaterialInto
  , isValid
  )

  where

import Foreign
import Foreign.C.Types (CInt(..), CBool(..))
import Box2D.Id (BodyId(..), ChainId(..), ShapeId(..), WorldId(..))
import Box2D.Types (ChainDef, SurfaceMaterial)

foreign import ccall unsafe "b2CreateChain"
  c_b2CreateChain :: BodyId -> Ptr ChainDef -> IO ChainId

foreign import ccall unsafe "b2DestroyChain"
  c_b2DestroyChain :: ChainId -> IO ()

foreign import ccall unsafe "b2Chain_GetWorld"
  c_b2Chain_GetWorld :: ChainId -> IO WorldId

foreign import ccall unsafe "b2Chain_GetSegmentCount"
  c_b2Chain_GetSegmentCount :: ChainId -> IO CInt

foreign import ccall unsafe "b2Chain_GetSegments"
  c_b2Chain_GetSegments :: ChainId -> Ptr ShapeId -> CInt -> IO CInt

foreign import ccall unsafe "b2Chain_GetSurfaceMaterialCount"
  c_b2Chain_GetSurfaceMaterialCount :: ChainId -> IO CInt

foreign import ccall unsafe "b2Chain_SetSurfaceMaterial"
  c_b2Chain_SetSurfaceMaterial :: ChainId -> Ptr SurfaceMaterial -> CInt -> IO ()

foreign import ccall unsafe "hsg_b2Chain_GetSurfaceMaterial"
  c_b2Chain_GetSurfaceMaterial :: ChainId -> CInt -> Ptr SurfaceMaterial -> IO ()

foreign import ccall unsafe "b2Chain_IsValid"
  c_b2Chain_IsValid :: ChainId -> IO CBool

{- | Create a chain shape
See also b2ChainDef for details.

Binds @b2CreateChain@.
-}
create
  :: BodyId
  -> ChainDef
  -> IO ChainId
create :: BodyId -> ChainDef -> IO ChainId
create BodyId
a0 ChainDef
a1 =
  ChainDef -> (Ptr ChainDef -> IO ChainId) -> IO ChainId
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with ChainDef
a1 ((Ptr ChainDef -> IO ChainId) -> IO ChainId)
-> (Ptr ChainDef -> IO ChainId) -> IO ChainId
forall a b. (a -> b) -> a -> b
$ \Ptr ChainDef
p1 ->
  BodyId -> Ptr ChainDef -> IO ChainId
c_b2CreateChain BodyId
a0 Ptr ChainDef
p1

{- | Destroy a chain shape

Binds @b2DestroyChain@.
-}
destroy
  :: ChainId
  -> IO ()
destroy :: ChainId -> IO ()
destroy ChainId
a0 =
  ChainId -> IO ()
c_b2DestroyChain ChainId
a0

{- | Get the world that owns this chain shape

Binds @b2Chain_GetWorld@.
-}
getWorld
  :: ChainId
  -> IO WorldId
getWorld :: ChainId -> IO WorldId
getWorld ChainId
a0 =
  ChainId -> IO WorldId
c_b2Chain_GetWorld ChainId
a0

{- | Get the number of segments on this chain

Binds @b2Chain_GetSegmentCount@.
-}
getSegmentCount
  :: ChainId
  -> IO Int
getSegmentCount :: ChainId -> IO Int
getSegmentCount ChainId
a0 =
  CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ChainId -> IO CInt
c_b2Chain_GetSegmentCount ChainId
a0)

{- | Fill a user array with chain segment shape ids up to the specified capacity. Returns
the actual number of segments returned.

Binds @b2Chain_GetSegments@.
-}
getSegments
  :: ChainId
  -> Ptr ShapeId
  -- ^ @segmentArray@
  -> Int
  -- ^ @capacity@
  -> IO Int
getSegments :: ChainId -> Ptr ShapeId -> Int -> IO Int
getSegments ChainId
a0 Ptr ShapeId
a1 Int
a2 =
  CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ChainId -> Ptr ShapeId -> CInt -> IO CInt
c_b2Chain_GetSegments ChainId
a0 Ptr ShapeId
a1 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a2))

{- | Get the number of materials used on this chain. Must be 1 or the number of segments.

Binds @b2Chain_GetSurfaceMaterialCount@.
-}
getSurfaceMaterialCount
  :: ChainId
  -> IO Int
getSurfaceMaterialCount :: ChainId -> IO Int
getSurfaceMaterialCount ChainId
a0 =
  CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ChainId -> IO CInt
c_b2Chain_GetSurfaceMaterialCount ChainId
a0)

{- | Set a chain material. If the chain has only one material, this material is applied to all
segments. Otherwise it is applied to a single segment.

Binds @b2Chain_SetSurfaceMaterial@.
-}
setSurfaceMaterial
  :: ChainId
  -> SurfaceMaterial
  -> Int
  -- ^ @materialIndex@
  -> IO ()
setSurfaceMaterial :: ChainId -> SurfaceMaterial -> Int -> IO ()
setSurfaceMaterial ChainId
a0 SurfaceMaterial
a1 Int
a2 =
  SurfaceMaterial -> (Ptr SurfaceMaterial -> IO ()) -> IO ()
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with SurfaceMaterial
a1 ((Ptr SurfaceMaterial -> IO ()) -> IO ())
-> (Ptr SurfaceMaterial -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr SurfaceMaterial
p1 ->
  ChainId -> Ptr SurfaceMaterial -> CInt -> IO ()
c_b2Chain_SetSurfaceMaterial ChainId
a0 Ptr SurfaceMaterial
p1 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a2)

{- | Get a chain material by index.

Binds @b2Chain_GetSurfaceMaterial@.
-}
getSurfaceMaterial
  :: ChainId
  -> Int
  -- ^ @materialIndex@
  -> IO SurfaceMaterial
getSurfaceMaterial :: ChainId -> Int -> IO SurfaceMaterial
getSurfaceMaterial ChainId
a0 Int
a1 =
  (Ptr SurfaceMaterial -> IO SurfaceMaterial) -> IO SurfaceMaterial
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr SurfaceMaterial -> IO SurfaceMaterial) -> IO SurfaceMaterial)
-> (Ptr SurfaceMaterial -> IO SurfaceMaterial)
-> IO SurfaceMaterial
forall a b. (a -> b) -> a -> b
$ \Ptr SurfaceMaterial
pOut -> ChainId -> CInt -> Ptr SurfaceMaterial -> IO ()
c_b2Chain_GetSurfaceMaterial ChainId
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1) Ptr SurfaceMaterial
pOut IO () -> IO SurfaceMaterial -> IO SurfaceMaterial
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr SurfaceMaterial -> IO SurfaceMaterial
forall a. Storable a => Ptr a -> IO a
peek Ptr SurfaceMaterial
pOut

-- | Like 'getSurfaceMaterial', but the result is written into a caller-supplied buffer.
getSurfaceMaterialInto
  :: ChainId
  -> Int
  -- ^ @materialIndex@
  -> Ptr SurfaceMaterial
  -- ^ Result buffer.
  -> IO ()
getSurfaceMaterialInto :: ChainId -> Int -> Ptr SurfaceMaterial -> IO ()
getSurfaceMaterialInto ChainId
a0 Int
a1 Ptr SurfaceMaterial
out =
  ChainId -> CInt -> Ptr SurfaceMaterial -> IO ()
c_b2Chain_GetSurfaceMaterial ChainId
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1) Ptr SurfaceMaterial
out

{- | Chain identifier validation. Provides validation for up to 64K allocations.

Binds @b2Chain_IsValid@.
-}
isValid
  :: ChainId
  -> IO Bool
isValid :: ChainId -> IO Bool
isValid ChainId
a0 =
  CBool -> Bool
forall a. (Eq a, Num a) => a -> Bool
toBool (CBool -> Bool) -> IO CBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ChainId -> IO CBool
c_b2Chain_IsValid ChainId
a0)