{-# LINE 1 "Network/Libev.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LINE 2 "Network/Libev.hsc" #-}
module Network.Libev
    ( evDefaultLoop
    , evLoopNew
    , evLoop
    , evUnloop
    , evLoopDestroy
    -- ev_io
    , mkEvIo
    , mkEvTimer
    , mkIoCallback
    , mkTimerCallback
    , IoCallback -- (..)
    , evIoInit
    , evIoStart
    , evIoStop
    -- ev_timer
    , evTimerInit
    , evTimerStart
    , evTimerStop
    -- events
    , ev_read
    , ev_write
    , c_accept
    , c_close
    , c_read
    , c_write
    )
    where
import Prelude hiding (repeat)
import System.IO
import Foreign
import Foreign.C


{-# LINE 36 "Network/Libev.hsc" #-}

-- * Marhsaled Data Types

type CEventType = CInt

ev_read   :: CEventType
ev_read   =  1
ev_write  :: CEventType
ev_write  =  2

{-# LINE 45 "Network/Libev.hsc" #-}

data EvLoop       = EvLoop
type EvLoopPtr    = Ptr EvLoop

data EvWatcher    = EvWatcher
type EvWatcherPtr = Ptr EvWatcher

data EvIo         = EvIo { fd :: CInt, events :: CInt }
type EvIoPtr      = Ptr EvIo

data EvTimer      = EvTimer { repeat :: Double }
type EvTimerPtr   = Ptr EvTimer

instance Storable EvWatcher where
    sizeOf    _ = ((20))
{-# LINE 60 "Network/Libev.hsc" #-}
    alignment _ = alignment (undefined :: CInt)

instance Storable EvIo where
    sizeOf    _ = (32)
{-# LINE 64 "Network/Libev.hsc" #-}
    alignment _ = alignment (undefined :: CInt)
    peek ptr    = do
      fd'       <- ((\hsc_ptr -> peekByteOff hsc_ptr 24)) ptr
{-# LINE 67 "Network/Libev.hsc" #-}
      events'   <- ((\hsc_ptr -> peekByteOff hsc_ptr 28)) ptr
{-# LINE 68 "Network/Libev.hsc" #-}
      return EvIo { fd = fd', events = events' }
    poke ptr (EvIo fd' events') = do
      ((\hsc_ptr -> pokeByteOff hsc_ptr 24)) ptr fd'
{-# LINE 71 "Network/Libev.hsc" #-}
      ((\hsc_ptr -> pokeByteOff hsc_ptr 28)) ptr events'
{-# LINE 72 "Network/Libev.hsc" #-}

instance Storable EvTimer where
    sizeOf    _ = ((36))
{-# LINE 75 "Network/Libev.hsc" #-}
    alignment _ = alignment (undefined :: CInt)
    peek ptr    = do
      repeat'   <- ((\hsc_ptr -> peekByteOff hsc_ptr 28)) ptr
{-# LINE 78 "Network/Libev.hsc" #-}
      return EvTimer { repeat = repeat' }
    poke ptr (EvTimer repeat') = do
      ((\hsc_ptr -> pokeByteOff hsc_ptr 28)) ptr repeat'
{-# LINE 81 "Network/Libev.hsc" #-}

-- * Low-level C functions

type IoCallback = EvLoopPtr -> EvIoPtr -> CInt -> IO ()
type TimerCallback = EvLoopPtr -> EvTimerPtr -> CInt -> IO ()

foreign import ccall unsafe "wev_default_loop" evDefaultLoop :: CInt -> IO EvLoopPtr
foreign import ccall "wev_loop" evLoop :: EvLoopPtr -> CInt -> IO ()
foreign import ccall "wev_unloop" evUnloop :: EvLoopPtr -> CInt -> IO ()
foreign import ccall unsafe "wev_loop_new" evLoopNew :: CUInt -> IO EvLoopPtr
foreign import ccall unsafe "wev_loop_destroy" evLoopDestroy :: EvLoopPtr -> IO ()

foreign import ccall unsafe "wev_io_init" evIoInit :: EvIoPtr -> FunPtr IoCallback -> CInt -> CInt -> IO ()
foreign import ccall unsafe "wev_io_start" evIoStart :: EvLoopPtr -> EvIoPtr -> IO ()
foreign import ccall unsafe "wev_io_stop" evIoStop :: EvLoopPtr -> EvIoPtr -> IO ()

foreign import ccall unsafe "wev_timer_init" evTimerInit :: EvTimerPtr -> FunPtr TimerCallback -> CFloat -> CFloat -> IO ()
foreign import ccall unsafe "wev_timer_start" evTimerStart :: EvLoopPtr -> EvTimerPtr -> IO ()
foreign import ccall unsafe "wev_timer_stop" evTimerStop :: EvLoopPtr -> EvTimerPtr -> IO ()

foreign import ccall unsafe "unistd.h close" c_close :: CInt -> IO (CInt)
foreign import ccall unsafe "unistd.h read" c_read :: CInt -> CString -> CSize -> IO (CSize)
foreign import ccall unsafe "unistd.h write" c_write :: CInt -> CString -> CSize -> IO (CSize)
foreign import ccall unsafe "c_accept" c_accept :: CInt -> IO (CInt)

-- callback wrappers
foreign import ccall "wrapper" mkIoCallback :: IoCallback -> IO (FunPtr IoCallback)
foreign import ccall "wrapper" mkTimerCallback :: IoCallback -> IO (FunPtr TimerCallback)

-- mem allocators
-- foreign import ccall unsafe "wmkevio" mkEvIo :: IO (EvIoPtr)
-- foreign import ccall unsafe "wfreeevio" freeEvIo :: EvIoPtr -> IO ()

mkEvIo :: IO (EvIoPtr)
mkEvIo = malloc

mkEvTimer :: IO (EvTimerPtr)
mkEvTimer = malloc