{-# LINE 1 "src/Client/CApi/Types.hsc" #-}
{-# Language ForeignFunctionInterface, RecordWildCards #-}
{-# LINE 2 "src/Client/CApi/Types.hsc" #-}

{-|
Module      : Client.CApi.Types
Description : Marshaling support for C API
Copyright   : (c) Eric Mertens, 2016
License     : ISC
Maintainer  : emertens@gmail.com

Marshaling types and functions for the C API

-}


{-# LINE 15 "src/Client/CApi/Types.hsc" #-}

module Client.CApi.Types
  ( -- * Extension record
    FgnExtension(..)
  , StartExtension
  , StopExtension
  , ProcessMessage
  , ProcessCommand

  -- * Strings
  , FgnStringLen(..)

  -- * Messages
  , FgnMsg(..)

  -- * Commands
  , FgnCmd(..)

  -- * Function pointer calling
  , Dynamic
  , runStartExtension
  , runStopExtension
  , runProcessMessage
  , runProcessCommand

  -- * report message codes
  , MessageCode(..), normalMessage, errorMessage

  -- * process message results
  , MessageResult(..), passMessage, dropMessage
  ) where

import Foreign.C
import Foreign.Ptr
import Foreign.Storable

-- | Tag for describing the kind of message to display in the client
-- as used in `glirc_print`.
--
-- @enum message_code;@
newtype MessageCode = MessageCode CInt deriving Eq
normalMessage :: MessageCode
normalMessage = MessageCode 0
errorMessage :: MessageCode
errorMessage = MessageCode 1

{-# LINE 57 "src/Client/CApi/Types.hsc" #-}

-- | Result used to determine what to do after processing a message with
-- the 'ProcessMessage' callback.
--
-- @enum process_result;@
newtype MessageResult = MessageResult CInt deriving Eq
passMessage :: MessageResult
passMessage = MessageResult 0
dropMessage :: MessageResult
dropMessage = MessageResult 1

{-# LINE 64 "src/Client/CApi/Types.hsc" #-}

--

-- | @typedef void *start(void *glirc, const char *path);@
type StartExtension =
  Ptr ()      {- ^ api token                   -} ->
  CString     {- ^ path to extension           -} ->
  IO (Ptr ()) {- ^ initialized extension state -}

-- | @typedef void stop(void *glirc, void *S);@
type StopExtension =
  Ptr () {- ^ api token       -} ->
  Ptr () {- ^ extension state -} ->
  IO ()

-- | @typedef enum process_result process_message(void *glirc, void *S, const struct glirc_message *);@
type ProcessMessage =
  Ptr ()     {- ^ api token       -} ->
  Ptr ()     {- ^ extention state -} ->
  Ptr FgnMsg {- ^ message to send -} ->
  IO MessageResult

-- | @typedef void process_command(void *glirc, void *S, const struct glirc_command *);@
type ProcessCommand =
  Ptr ()     {- ^ api token       -} ->
  Ptr ()     {- ^ extension state -} ->
  Ptr FgnCmd {- ^ command         -} ->
  IO ()

-- | Type of dynamic function pointer wrappers.
type Dynamic a = FunPtr a -> a

foreign import ccall "dynamic" runStartExtension :: Dynamic StartExtension
foreign import ccall "dynamic" runStopExtension  :: Dynamic StopExtension
foreign import ccall "dynamic" runProcessMessage :: Dynamic ProcessMessage
foreign import ccall "dynamic" runProcessCommand :: Dynamic ProcessCommand

------------------------------------------------------------------------

-- | @struct glirc_extension;@
data FgnExtension = FgnExtension
  { fgnStart   :: FunPtr StartExtension -- ^ Optional startup callback
  , fgnStop    :: FunPtr StopExtension  -- ^ Optional shutdown callback
  , fgnMessage :: FunPtr ProcessMessage -- ^ Optional message received callback
  , fgnCommand :: FunPtr ProcessCommand -- ^ Optional client command callback
  , fgnName    :: CString               -- ^ Null-terminated name
  , fgnMajorVersion, fgnMinorVersion :: CInt -- ^ extension version
  }

instance Storable FgnExtension where
  alignment _ = (8)
{-# LINE 115 "src/Client/CApi/Types.hsc" #-}
  sizeOf    _ = (48)
{-# LINE 116 "src/Client/CApi/Types.hsc" #-}
  peek p      = FgnExtension
            <$> ((\hsc_ptr -> peekByteOff hsc_ptr 16)) p
{-# LINE 118 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 24)) p
{-# LINE 119 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 32)) p
{-# LINE 120 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 40)) p
{-# LINE 121 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 122 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p
{-# LINE 123 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 12)) p
{-# LINE 124 "src/Client/CApi/Types.hsc" #-}
  poke p FgnExtension{..} =
             do ((\hsc_ptr -> pokeByteOff hsc_ptr 16)) p fgnStart
{-# LINE 126 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 24)) p fgnStop
{-# LINE 127 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 32)) p fgnMessage
{-# LINE 128 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 40)) p fgnCommand
{-# LINE 129 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p fgnName
{-# LINE 130 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p fgnMajorVersion
{-# LINE 131 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 12)) p fgnMinorVersion
{-# LINE 132 "src/Client/CApi/Types.hsc" #-}

------------------------------------------------------------------------

-- | @struct glirc_message@
data FgnMsg = FgnMsg
  { fmNetwork    :: FgnStringLen
  , fmPrefixNick :: FgnStringLen
  , fmPrefixUser :: FgnStringLen
  , fmPrefixHost :: FgnStringLen
  , fmCommand    :: FgnStringLen
  , fmParams     :: Ptr FgnStringLen -- ^ array
  , fmParamN     :: CSize            -- ^ array length
  , fmTagKeys    :: Ptr FgnStringLen -- ^ array
  , fmTagVals    :: Ptr FgnStringLen -- ^ array
  , fmTagN       :: CSize            -- ^ array length
  }

instance Storable FgnMsg where
  alignment _ = (8)
{-# LINE 151 "src/Client/CApi/Types.hsc" #-}
  sizeOf    _ = (120)
{-# LINE 152 "src/Client/CApi/Types.hsc" #-}
  peek p      = FgnMsg
            <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 154 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 16)) p
{-# LINE 155 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 32)) p
{-# LINE 156 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 48)) p
{-# LINE 157 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 64)) p
{-# LINE 158 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 80)) p
{-# LINE 159 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 88)) p
{-# LINE 160 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 96)) p
{-# LINE 161 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 104)) p
{-# LINE 162 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 112)) p
{-# LINE 163 "src/Client/CApi/Types.hsc" #-}

  poke p FgnMsg{..} =
             do ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p fmNetwork
{-# LINE 166 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 16)) p fmPrefixNick
{-# LINE 167 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 32)) p fmPrefixUser
{-# LINE 168 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 48)) p fmPrefixHost
{-# LINE 169 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 64)) p fmCommand
{-# LINE 170 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 80)) p fmParams
{-# LINE 171 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 88)) p fmParamN
{-# LINE 172 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 96)) p fmTagKeys
{-# LINE 173 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 104)) p fmTagVals
{-# LINE 174 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 112)) p fmTagN
{-# LINE 175 "src/Client/CApi/Types.hsc" #-}

------------------------------------------------------------------------

-- | @struct glirc_command@
data FgnCmd = FgnCmd
  { fcParams  :: Ptr FgnStringLen -- ^ array
  , fcParamN  :: CSize            -- ^ array length
  }

instance Storable FgnCmd where
  alignment _ = (8)
{-# LINE 186 "src/Client/CApi/Types.hsc" #-}
  sizeOf    _ = (16)
{-# LINE 187 "src/Client/CApi/Types.hsc" #-}
  peek p      = FgnCmd
            <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 189 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p
{-# LINE 190 "src/Client/CApi/Types.hsc" #-}

  poke p FgnCmd{..} =
             do ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p fcParams
{-# LINE 193 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p fcParamN
{-# LINE 194 "src/Client/CApi/Types.hsc" #-}

------------------------------------------------------------------------

-- | @struct glirc_string@
data FgnStringLen = FgnStringLen !CString !CSize

instance Storable FgnStringLen where
  alignment _ = (8)
{-# LINE 202 "src/Client/CApi/Types.hsc" #-}
  sizeOf    _ = (16)
{-# LINE 203 "src/Client/CApi/Types.hsc" #-}
  peek p      = FgnStringLen
            <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 205 "src/Client/CApi/Types.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p
{-# LINE 206 "src/Client/CApi/Types.hsc" #-}
  poke p (FgnStringLen x y) =
             do ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p x
{-# LINE 208 "src/Client/CApi/Types.hsc" #-}
                ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p y
{-# LINE 209 "src/Client/CApi/Types.hsc" #-}