{-# OPTIONS -Wall #-}
{-# LANGUAGE TemplateHaskell #-}

-- | Bindings to @rcamera@ (raylib.h)
module Raylib.Core.Camera
  ( -- * High level
    updateCamera,
    updateCameraPro,

    -- * Native
    c'updateCamera,
    c'updateCameraPro,
  )
where

import Foreign (Ptr, Storable (peek))
import Foreign.C (CFloat (..), CInt (..))
import GHC.IO (unsafePerformIO)
import Raylib.Internal.Foreign (withFreeable)
import Raylib.Internal.TH (genNative)
import Raylib.Types (Camera3D, CameraMode, Vector3)

$( genNative
     [ ("c'updateCamera", "UpdateCamera_", "rl_bindings.h", [t|Ptr Camera3D -> CInt -> IO ()|], False),
       ("c'updateCameraPro", "UpdateCameraPro_", "rl_bindings.h", [t|Ptr Camera3D -> Ptr Vector3 -> Ptr Vector3 -> CFloat -> IO ()|], False)
     ]
 )

updateCamera :: Camera3D -> CameraMode -> IO Camera3D
updateCamera :: Camera3D -> CameraMode -> IO Camera3D
updateCamera Camera3D
camera CameraMode
mode =
  Camera3D -> (Ptr Camera3D -> IO Camera3D) -> IO Camera3D
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable
    Camera3D
camera
    ( \Ptr Camera3D
c -> do
        Ptr Camera3D -> CInt -> IO ()
c'updateCamera Ptr Camera3D
c (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ CameraMode -> Int
forall a. Enum a => a -> Int
fromEnum CameraMode
mode)
        Ptr Camera3D -> IO Camera3D
forall a. Storable a => Ptr a -> IO a
peek Ptr Camera3D
c
    )

updateCameraPro :: Camera3D -> Vector3 -> Vector3 -> Float -> Camera3D
updateCameraPro :: Camera3D -> Vector3 -> Vector3 -> Float -> Camera3D
updateCameraPro Camera3D
camera Vector3
movement Vector3
rotation Float
zoom =
  IO Camera3D -> Camera3D
forall a. IO a -> a
unsafePerformIO (IO Camera3D -> Camera3D) -> IO Camera3D -> Camera3D
forall a b. (a -> b) -> a -> b
$
    Camera3D -> (Ptr Camera3D -> IO Camera3D) -> IO Camera3D
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable
      Camera3D
camera
      ( \Ptr Camera3D
c -> do
          Vector3 -> (Ptr Vector3 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector3
movement (\Ptr Vector3
m -> Vector3 -> (Ptr Vector3 -> IO ()) -> IO ()
forall a b.
(Freeable a, Storable a) =>
a -> (Ptr a -> IO b) -> IO b
withFreeable Vector3
rotation (\Ptr Vector3
r -> Ptr Camera3D -> Ptr Vector3 -> Ptr Vector3 -> CFloat -> IO ()
c'updateCameraPro Ptr Camera3D
c Ptr Vector3
m Ptr Vector3
r (Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
zoom)))
          Ptr Camera3D -> IO Camera3D
forall a. Storable a => Ptr a -> IO a
peek Ptr Camera3D
c
      )