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

module Box2D.RecPlayer
  ( create
  , stepFrame
  , getWorldId
  , restart
  , seekFrame
  , getFrame
  , getInfo
  , isAtEnd
  , hasDiverged
  , getDivergeFrame
  , setKeyframePolicy
  , getKeyframeBudget
  , getKeyframeMinInterval
  , getKeyframeInterval
  , getKeyframeBytes
  , destroy
  , drawFrameQueries
  , getFrameQueryCount
  , getFrameQuery
  , getFrameQueryHit
  , getBodyCount
  , getBodyId
  )

  where

import Foreign
import Foreign.C.Types (CInt(..), CBool(..), CSize(..))
import Box2D.Id (BodyId(..), WorldId(..))
import Box2D.Tags (DebugDraw, RecPlayer, RecPlayerInfo, RecQueryHit, RecQueryInfo)

foreign import ccall unsafe "b2RecPlayer_Create"
  c_b2RecPlayer_Create :: Ptr () -> CInt -> CInt -> IO (Ptr RecPlayer)

foreign import ccall safe "b2RecPlayer_StepFrame"
  c_b2RecPlayer_StepFrame :: Ptr RecPlayer -> IO CBool

foreign import ccall unsafe "b2RecPlayer_GetWorldId"
  c_b2RecPlayer_GetWorldId :: Ptr RecPlayer -> IO WorldId

foreign import ccall unsafe "b2RecPlayer_Restart"
  c_b2RecPlayer_Restart :: Ptr RecPlayer -> IO ()

foreign import ccall unsafe "b2RecPlayer_SeekFrame"
  c_b2RecPlayer_SeekFrame :: Ptr RecPlayer -> CInt -> IO ()

foreign import ccall unsafe "b2RecPlayer_GetFrame"
  c_b2RecPlayer_GetFrame :: Ptr RecPlayer -> IO CInt

foreign import ccall unsafe "hsg_b2RecPlayer_GetInfo"
  c_b2RecPlayer_GetInfo :: Ptr RecPlayer -> Ptr RecPlayerInfo -> IO ()

foreign import ccall unsafe "b2RecPlayer_IsAtEnd"
  c_b2RecPlayer_IsAtEnd :: Ptr RecPlayer -> IO CBool

foreign import ccall unsafe "b2RecPlayer_HasDiverged"
  c_b2RecPlayer_HasDiverged :: Ptr RecPlayer -> IO CBool

foreign import ccall unsafe "b2RecPlayer_GetDivergeFrame"
  c_b2RecPlayer_GetDivergeFrame :: Ptr RecPlayer -> IO CInt

foreign import ccall unsafe "b2RecPlayer_SetKeyframePolicy"
  c_b2RecPlayer_SetKeyframePolicy :: Ptr RecPlayer -> CSize -> CInt -> IO ()

foreign import ccall unsafe "b2RecPlayer_GetKeyframeBudget"
  c_b2RecPlayer_GetKeyframeBudget :: Ptr RecPlayer -> IO CSize

foreign import ccall unsafe "b2RecPlayer_GetKeyframeMinInterval"
  c_b2RecPlayer_GetKeyframeMinInterval :: Ptr RecPlayer -> IO CInt

foreign import ccall unsafe "b2RecPlayer_GetKeyframeInterval"
  c_b2RecPlayer_GetKeyframeInterval :: Ptr RecPlayer -> IO CInt

foreign import ccall unsafe "b2RecPlayer_GetKeyframeBytes"
  c_b2RecPlayer_GetKeyframeBytes :: Ptr RecPlayer -> IO CSize

foreign import ccall unsafe "b2RecPlayer_Destroy"
  c_b2RecPlayer_Destroy :: Ptr RecPlayer -> IO ()

foreign import ccall unsafe "b2RecPlayer_DrawFrameQueries"
  c_b2RecPlayer_DrawFrameQueries :: Ptr RecPlayer -> Ptr DebugDraw -> CInt -> IO ()

foreign import ccall unsafe "b2RecPlayer_GetFrameQueryCount"
  c_b2RecPlayer_GetFrameQueryCount :: Ptr RecPlayer -> IO CInt

foreign import ccall unsafe "hsg_b2RecPlayer_GetFrameQuery"
  c_b2RecPlayer_GetFrameQuery :: Ptr RecPlayer -> CInt -> Ptr RecQueryInfo -> IO ()

foreign import ccall unsafe "hsg_b2RecPlayer_GetFrameQueryHit"
  c_b2RecPlayer_GetFrameQueryHit :: Ptr RecPlayer -> CInt -> CInt -> Ptr RecQueryHit -> IO ()

foreign import ccall unsafe "b2RecPlayer_GetBodyCount"
  c_b2RecPlayer_GetBodyCount :: Ptr RecPlayer -> IO CInt

foreign import ccall unsafe "b2RecPlayer_GetBodyId"
  c_b2RecPlayer_GetBodyId :: Ptr RecPlayer -> CInt -> IO BodyId

{- | Open a recording for incremental playback and replay up to the first step. The player copies
the bytes, so you may free or destroy the source buffer immediately after this call.

Returns: A player handle, or NULL if the recording is malformed

Binds @b2RecPlayer_Create@.
-}
create
  :: Ptr ()
  -- ^ @data@: Recorded bytes, e.g. from b2Recording_GetData or a loaded file
  -> Int
  -- ^ @size@: Number of recorded bytes
  -> Int
  -- ^ @workerCount@: Worker count for the replay world. 0 uses the serial single-worker fallback.
  -> IO (Ptr RecPlayer)
create :: Ptr () -> Int -> Int -> IO (Ptr RecPlayer)
create Ptr ()
a0 Int
a1 Int
a2 =
  Ptr () -> CInt -> CInt -> IO (Ptr RecPlayer)
c_b2RecPlayer_Create Ptr ()
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a2)

{- | Advance the replay by one recorded step.

Returns: true if a step executed, false once the end of the recording is reached

Binds @b2RecPlayer_StepFrame@.
-}
stepFrame
  :: Ptr RecPlayer
  -> IO Bool
stepFrame :: Ptr RecPlayer -> IO Bool
stepFrame Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CBool
c_b2RecPlayer_StepFrame Ptr RecPlayer
a0)

{- | Get the id of the replayed world.

Binds @b2RecPlayer_GetWorldId@.
-}
getWorldId
  :: Ptr RecPlayer
  -> IO WorldId
getWorldId :: Ptr RecPlayer -> IO WorldId
getWorldId Ptr RecPlayer
a0 =
  Ptr RecPlayer -> IO WorldId
c_b2RecPlayer_GetWorldId Ptr RecPlayer
a0

{- | Rewind the player to the first step, recreating the replay world from the file.

Binds @b2RecPlayer_Restart@.
-}
restart
  :: Ptr RecPlayer
  -> IO ()
restart :: Ptr RecPlayer -> IO ()
restart Ptr RecPlayer
a0 =
  Ptr RecPlayer -> IO ()
c_b2RecPlayer_Restart Ptr RecPlayer
a0

{- | Seek to a recorded step. Seeking backward rewinds and re-runs from the start, so the
cost grows with the target frame. Clamps to the recording bounds.

Binds @b2RecPlayer_SeekFrame@.
-}
seekFrame
  :: Ptr RecPlayer
  -> Int
  -- ^ @targetFrame@
  -> IO ()
seekFrame :: Ptr RecPlayer -> Int -> IO ()
seekFrame Ptr RecPlayer
a0 Int
a1 =
  Ptr RecPlayer -> CInt -> IO ()
c_b2RecPlayer_SeekFrame Ptr RecPlayer
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1)

{- | Get the number of steps replayed so far.

Binds @b2RecPlayer_GetFrame@.
-}
getFrame
  :: Ptr RecPlayer
  -> IO Int
getFrame :: Ptr RecPlayer -> IO Int
getFrame Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CInt
c_b2RecPlayer_GetFrame Ptr RecPlayer
a0)

{- | Get static metadata for the recording (frame count, recorded tuning, time).

Binds @b2RecPlayer_GetInfo@.
-}
getInfo
  :: Ptr RecPlayer
  -> Ptr RecPlayerInfo
  -- ^ Result buffer.
  -> IO ()
getInfo :: Ptr RecPlayer -> Ptr RecPlayerInfo -> IO ()
getInfo Ptr RecPlayer
a0 Ptr RecPlayerInfo
out =
  Ptr RecPlayer -> Ptr RecPlayerInfo -> IO ()
c_b2RecPlayer_GetInfo Ptr RecPlayer
a0 Ptr RecPlayerInfo
out

{- | Returns true once the end of the recording has been reached.

Binds @b2RecPlayer_IsAtEnd@.
-}
isAtEnd
  :: Ptr RecPlayer
  -> IO Bool
isAtEnd :: Ptr RecPlayer -> IO Bool
isAtEnd Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CBool
c_b2RecPlayer_IsAtEnd Ptr RecPlayer
a0)

{- | Returns true if a recorded state hash failed to reproduce, meaning replay diverged.

Binds @b2RecPlayer_HasDiverged@.
-}
hasDiverged
  :: Ptr RecPlayer
  -> IO Bool
hasDiverged :: Ptr RecPlayer -> IO Bool
hasDiverged Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CBool
c_b2RecPlayer_HasDiverged Ptr RecPlayer
a0)

{- | Get the first step at which replay diverged, or -1 if it has not diverged.

Binds @b2RecPlayer_GetDivergeFrame@.
-}
getDivergeFrame
  :: Ptr RecPlayer
  -> IO Int
getDivergeFrame :: Ptr RecPlayer -> IO Int
getDivergeFrame Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CInt
c_b2RecPlayer_GetDivergeFrame Ptr RecPlayer
a0)

{- | Tune the keyframe ring used to speed up backward seeking. A keyframe is a periodic snapshot the
player restores from instead of replaying from the start, trading memory for seek speed.

Binds @b2RecPlayer_SetKeyframePolicy@.
-}
setKeyframePolicy
  :: Ptr RecPlayer
  -- ^ @player@: the recording player
  -> CSize
  -- ^ @budgetBytes@: Memory cap for the kept snapshots. The spacing widens to stay under it.
  -> Int
  -- ^ @minIntervalFrames@: Finest spacing between keyframes, in frames. A zero budget or a non-positive interval keeps that value. Clears the existing ring, so call b2RecPlayer_Restart afterward to repopulate it under the new policy.
  -> IO ()
setKeyframePolicy :: Ptr RecPlayer -> CSize -> Int -> IO ()
setKeyframePolicy Ptr RecPlayer
a0 CSize
a1 Int
a2 =
  Ptr RecPlayer -> CSize -> CInt -> IO ()
c_b2RecPlayer_SetKeyframePolicy Ptr RecPlayer
a0 CSize
a1 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a2)

{- | Get the keyframe memory budget in bytes.

Binds @b2RecPlayer_GetKeyframeBudget@.
-}
getKeyframeBudget
  :: Ptr RecPlayer
  -> IO CSize
getKeyframeBudget :: Ptr RecPlayer -> IO CSize
getKeyframeBudget Ptr RecPlayer
a0 =
  Ptr RecPlayer -> IO CSize
c_b2RecPlayer_GetKeyframeBudget Ptr RecPlayer
a0

{- | Get the finest keyframe spacing in frames.

Binds @b2RecPlayer_GetKeyframeMinInterval@.
-}
getKeyframeMinInterval
  :: Ptr RecPlayer
  -> IO Int
getKeyframeMinInterval :: Ptr RecPlayer -> IO Int
getKeyframeMinInterval Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CInt
c_b2RecPlayer_GetKeyframeMinInterval Ptr RecPlayer
a0)

{- | Get the current keyframe spacing in frames. Starts at the min interval and doubles as the ring
evicts to stay under budget, so it reflects the effective backward-seek granularity right now.

Binds @b2RecPlayer_GetKeyframeInterval@.
-}
getKeyframeInterval
  :: Ptr RecPlayer
  -> IO Int
getKeyframeInterval :: Ptr RecPlayer -> IO Int
getKeyframeInterval Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CInt
c_b2RecPlayer_GetKeyframeInterval Ptr RecPlayer
a0)

{- | Get the memory currently held by keyframe snapshots, in bytes.

Binds @b2RecPlayer_GetKeyframeBytes@.
-}
getKeyframeBytes
  :: Ptr RecPlayer
  -> IO CSize
getKeyframeBytes :: Ptr RecPlayer -> IO CSize
getKeyframeBytes Ptr RecPlayer
a0 =
  Ptr RecPlayer -> IO CSize
c_b2RecPlayer_GetKeyframeBytes Ptr RecPlayer
a0

{- | Close a player and free its replay world and file buffer.

Binds @b2RecPlayer_Destroy@.
-}
destroy
  :: Ptr RecPlayer
  -> IO ()
destroy :: Ptr RecPlayer -> IO ()
destroy Ptr RecPlayer
a0 =
  Ptr RecPlayer -> IO ()
c_b2RecPlayer_Destroy Ptr RecPlayer
a0

{- | Draw spatial queries recorded during the most recently replayed frame.
Call after b2World_Draw so queries are layered on top of the world.

Binds @b2RecPlayer_DrawFrameQueries@.
-}
drawFrameQueries
  :: Ptr RecPlayer
  -- ^ @player@: A valid player handle
  -> Ptr DebugDraw
  -- ^ @draw@: Debug draw callbacks. NULL draw function pointers are skipped.
  -> Int
  -- ^ @queryIndex@: Index into the frame\'s queries to draw, or -1 to draw all of them.
  -> IO ()
drawFrameQueries :: Ptr RecPlayer -> Ptr DebugDraw -> Int -> IO ()
drawFrameQueries Ptr RecPlayer
a0 Ptr DebugDraw
a1 Int
a2 =
  Ptr RecPlayer -> Ptr DebugDraw -> CInt -> IO ()
c_b2RecPlayer_DrawFrameQueries Ptr RecPlayer
a0 Ptr DebugDraw
a1 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a2)

{- | Get the number of spatial queries recorded for the most recently replayed frame.

Binds @b2RecPlayer_GetFrameQueryCount@.
-}
getFrameQueryCount
  :: Ptr RecPlayer
  -> IO Int
getFrameQueryCount :: Ptr RecPlayer -> IO Int
getFrameQueryCount Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CInt
c_b2RecPlayer_GetFrameQueryCount Ptr RecPlayer
a0)

{- | Get a recorded query from the most recently replayed frame by index.

Binds @b2RecPlayer_GetFrameQuery@.
-}
getFrameQuery
  :: Ptr RecPlayer
  -> Int
  -- ^ @index@
  -> Ptr RecQueryInfo
  -- ^ Result buffer.
  -> IO ()
getFrameQuery :: Ptr RecPlayer -> Int -> Ptr RecQueryInfo -> IO ()
getFrameQuery Ptr RecPlayer
a0 Int
a1 Ptr RecQueryInfo
out =
  Ptr RecPlayer -> CInt -> Ptr RecQueryInfo -> IO ()
c_b2RecPlayer_GetFrameQuery Ptr RecPlayer
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1) Ptr RecQueryInfo
out

{- | Get one result of a recorded query from the most recently replayed frame.

Binds @b2RecPlayer_GetFrameQueryHit@.
-}
getFrameQueryHit
  :: Ptr RecPlayer
  -> Int
  -- ^ @queryIndex@
  -> Int
  -- ^ @hitIndex@
  -> Ptr RecQueryHit
  -- ^ Result buffer.
  -> IO ()
getFrameQueryHit :: Ptr RecPlayer -> Int -> Int -> Ptr RecQueryHit -> IO ()
getFrameQueryHit Ptr RecPlayer
a0 Int
a1 Int
a2 Ptr RecQueryHit
out =
  Ptr RecPlayer -> CInt -> CInt -> Ptr RecQueryHit -> IO ()
c_b2RecPlayer_GetFrameQueryHit Ptr RecPlayer
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a2) Ptr RecQueryHit
out

{- | Get the number of body slots tracked for the outliner. This is the creation-order span and
includes holes for destroyed bodies, so it only grows as the replay advances.

Binds @b2RecPlayer_GetBodyCount@.
-}
getBodyCount
  :: Ptr RecPlayer
  -> IO Int
getBodyCount :: Ptr RecPlayer -> IO Int
getBodyCount Ptr RecPlayer
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
<$> (Ptr RecPlayer -> IO CInt
c_b2RecPlayer_GetBodyCount Ptr RecPlayer
a0)

{- | Get a tracked body by creation ordinal. Returns b2_nullBodyId for a destroyed slot, an ordinal not
yet reached at the current frame, or an out-of-range index. Validate with b2Body_IsValid.

Binds @b2RecPlayer_GetBodyId@.
-}
getBodyId
  :: Ptr RecPlayer
  -> Int
  -- ^ @index@
  -> IO BodyId
getBodyId :: Ptr RecPlayer -> Int -> IO BodyId
getBodyId Ptr RecPlayer
a0 Int
a1 =
  Ptr RecPlayer -> CInt -> IO BodyId
c_b2RecPlayer_GetBodyId Ptr RecPlayer
a0 (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
a1)