{-# LINE 1 "Sound/RtMidi/Foreign.hsc" #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE ForeignFunctionInterface #-}

-- | FFI defs for RtMidi
module Sound.RtMidi.Foreign
  ( Wrapper (..)
  , Api (..)
  , ApiInternal
  , toApi
  , fromApi
  , rtmidi_api_display_name
  , rtmidi_api_name
  , rtmidi_close_port
  , rtmidi_compiled_api_by_name
  , rtmidi_get_compiled_api
  , rtmidi_get_port_count
  , rtmidi_get_port_name
  , rtmidi_in_cancel_callback
  , rtmidi_in_create
  , rtmidi_in_create_default
  , rtmidi_in_free
  , rtmidi_in_get_current_api
  , rtmidi_in_get_message
  , rtmidi_in_ignore_types
  , rtmidi_in_set_callback
  , rtmidi_open_port
  , rtmidi_open_virtual_port
  , rtmidi_out_create
  , rtmidi_out_create_default
  , rtmidi_out_free
  , rtmidi_out_get_current_api
  , rtmidi_out_send_message
  ) where



import Control.DeepSeq (NFData)
import Foreign (FunPtr, Ptr, Storable (..))
import Foreign.C (CDouble (..), CInt (..), CString, CSize, CUChar, CUInt (..))
import GHC.Generics (Generic)

data Wrapper = Wrapper
  { ptr :: !(Ptr ())
  , dat :: !(Ptr ())
  , ok  :: !Bool
  , msg :: !CString
  } deriving stock (Eq, Show, Generic)
    deriving anyclass (NFData)

instance Storable Wrapper where
  sizeOf _ = (32)
{-# LINE 52 "Sound/RtMidi/Foreign.hsc" #-}
  alignment _ = 8
{-# LINE 53 "Sound/RtMidi/Foreign.hsc" #-}
  poke ptr (Wrapper a b c d) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr a
{-# LINE 55 "Sound/RtMidi/Foreign.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr b
{-# LINE 56 "Sound/RtMidi/Foreign.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 16) ptr c
{-# LINE 57 "Sound/RtMidi/Foreign.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 24) ptr d
{-# LINE 58 "Sound/RtMidi/Foreign.hsc" #-}
  peek ptr = do
    a <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
{-# LINE 60 "Sound/RtMidi/Foreign.hsc" #-}
    b <- (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
{-# LINE 61 "Sound/RtMidi/Foreign.hsc" #-}
    c <- (\hsc_ptr -> peekByteOff hsc_ptr 16) ptr
{-# LINE 62 "Sound/RtMidi/Foreign.hsc" #-}
    d <- (\hsc_ptr -> peekByteOff hsc_ptr 24) ptr
{-# LINE 63 "Sound/RtMidi/Foreign.hsc" #-}
    pure (Wrapper a b c d)

-- | Enum of RtMidi-supported APIs
data Api
  = UnspecifiedApi
  | CoreMidiApi
  | AlsaApi
  | JackApi
  | MultimediaApi
  | DummyApi
  deriving stock (Eq, Show, Ord, Enum, Bounded, Generic)
  deriving anyclass (NFData)

-- A parameter we'll be de/serializing from the 'Api' enum.
newtype ApiInternal = ApiInternal { unApiInternal :: CInt } deriving newtype (Storable)

toApi :: ApiInternal -> Api
toApi = toEnum . fromIntegral . unApiInternal

fromApi :: Api -> ApiInternal
fromApi = ApiInternal . fromIntegral . fromEnum

foreign import ccall "rtmidi_c.h rtmidi_api_display_name"
  rtmidi_api_display_name :: ApiInternal -> IO CString

foreign import ccall "rtmidi_c.h rtmidi_api_name"
  rtmidi_api_name :: ApiInternal -> IO CString

foreign import ccall "rtmidi_c.h rtmidi_close_port"
  rtmidi_close_port :: Ptr Wrapper -> IO ()

foreign import ccall "rtmidi_c.h rtmidi_compiled_api_by_name"
  rtmidi_compiled_api_by_name :: CString -> IO ApiInternal

foreign import ccall "rtmidi_c.h rtmidi_get_compiled_api"
  rtmidi_get_compiled_api :: Ptr ApiInternal -> CUInt -> IO CInt

foreign import ccall "rtmidi_c.h rtmidi_get_port_count"
  rtmidi_get_port_count :: Ptr Wrapper -> IO CUInt

foreign import ccall "rtmidi_c.h rtmidi_get_port_name"
  rtmidi_get_port_name :: Ptr Wrapper -> CUInt -> CString -> Ptr CInt -> IO CInt

foreign import ccall "rtmidi_c.h rtmidi_in_cancel_callback"
  rtmidi_in_cancel_callback :: Ptr Wrapper -> IO ()

foreign import ccall "rtmidi_c.h rtmidi_in_create"
  rtmidi_in_create :: ApiInternal -> CString -> CUInt -> IO (Ptr Wrapper)

foreign import ccall "rtmidi_c.h rtmidi_in_create_default"
  rtmidi_in_create_default :: IO (Ptr Wrapper)

foreign import ccall "rtmidi_c.h &rtmidi_in_free"
  rtmidi_in_free :: FunPtr (Ptr Wrapper -> IO ())

foreign import ccall "rtmidi_c.h rtmidi_in_get_current_api"
  rtmidi_in_get_current_api :: Ptr Wrapper -> IO ApiInternal

foreign import ccall "rtmidi_c.h rtmidi_in_get_message"
  rtmidi_in_get_message :: Ptr Wrapper -> Ptr (Ptr CUChar) -> Ptr CSize -> IO CDouble

foreign import ccall "rtmidi_c.h rtmidi_in_ignore_types"
  rtmidi_in_ignore_types :: Ptr Wrapper -> Bool -> Bool -> Bool -> IO ()

foreign import ccall "rtmidi_c.h rtmidi_in_set_callback"
  rtmidi_in_set_callback :: Ptr Wrapper -> FunPtr (CDouble -> Ptr CUChar -> CInt -> Ptr () -> IO ()) -> Ptr () -> IO ()

foreign import ccall "rtmidi_c.h rtmidi_open_port"
  rtmidi_open_port :: Ptr Wrapper -> CUInt -> CString -> IO ()

foreign import ccall "rtmidi_c.h rtmidi_open_virtual_port"
  rtmidi_open_virtual_port :: Ptr Wrapper -> CString -> IO ()

foreign import ccall "rtmidi_c.h rtmidi_out_create"
  rtmidi_out_create :: ApiInternal -> CString -> IO (Ptr Wrapper)

foreign import ccall "rtmidi_c.h rtmidi_out_create_default"
  rtmidi_out_create_default :: IO (Ptr Wrapper)

foreign import ccall "rtmidi_c.h &rtmidi_out_free"
  rtmidi_out_free :: FunPtr (Ptr Wrapper -> IO ())

foreign import ccall "rtmidi_c.h rtmidi_out_get_current_api"
  rtmidi_out_get_current_api :: Ptr Wrapper -> IO ApiInternal

foreign import ccall "rtmidi_c.h rtmidi_out_send_message"
  rtmidi_out_send_message :: Ptr Wrapper -> Ptr CUChar -> CInt -> IO CInt