{-# LINE 2 "./Media/Streaming/GStreamer/Core/Event.chs" #-}
-- GIMP Toolkit (GTK) Binding for Haskell: binding to gstreamer -*-haskell-*-
--
-- Author : Peter Gavin
-- Created: 1-Apr-2007
--
-- Copyright (c) 2007 Peter Gavin
--
-- This library is free software: you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation, either version 3 of
-- the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this program. If not, see
-- <http:
--
-- GStreamer, the C library which this Haskell library depends on, is
-- available under LGPL Version 2. The documentation included with
-- this library is based on the original GStreamer documentation.
--
-- |
-- Maintainer : gtk2hs-devel\@lists.sourceforge.net
-- Stability : alpha
-- Portability : portable (depends on GHC)
--
-- An object describing events that are passed up and down a pipeline.
module Media.Streaming.GStreamer.Core.Event (

-- * Detail

  -- | An 'Event' is a message that is passed up and down a pipeline.
  --
  -- There are a number of predefined events and functions returning
  -- events. To send an event an application will usually use
  -- 'Media.Streaming.GStreamer.Core.Element.elementSendEvent', and
  -- elements will use
  -- 'Media.Streaming.GStreamer.Core.Pad.padSendEvent' or
  -- 'Media.Streaming.GStreamer.Core.padPushEvent'.
  --
  --

-- * Types
  Event,
  EventClass,
  EventType(..),
  SeekFlags(..),
  SeekType(..),

-- * Event Operations
  eventType,
  eventNewCustom,
  eventNewEOS,
  eventNewFlushStart,
  eventNewFlushStop,

  eventNewLatency,

  eventNewNavigation,
  eventNewNewSegment,
  eventNewNewSegmentFull,
  eventNewQOS,
  eventNewSeek,
  eventNewTag,
  eventParseBufferSize,

  eventParseLatency,

  eventParseNewSegment,
  eventParseNewSegmentFull,
  eventParseQOS,
  eventParseSeek,
  eventParseTag,
  eventTypeGetName,
  eventTypeGetFlags,
  ) where


import Control.Monad (liftM)
import Media.Streaming.GStreamer.Core.Types
{-# LINE 86 "./Media/Streaming/GStreamer/Core/Event.chs" #-}
import System.Glib.FFI
import System.Glib.GObject
import System.Glib.UTFString
import System.Glib.GError


{-# LINE 92 "./Media/Streaming/GStreamer/Core/Event.chs" #-}

eventType :: EventClass event
          => event
          -> EventType
eventType event =
    cToEnum $ unsafePerformIO $ withMiniObject (toEvent event) cEventType
foreign import ccall unsafe "_hs_gst_event_type"
    cEventType :: Ptr Event
               -> IO (CInt)
{-# LINE 101 "./Media/Streaming/GStreamer/Core/Event.chs" #-}

eventNewCustom :: EventType
               -> Structure
               -> IO Event
eventNewCustom eventType structure =
    (\arg1 (Structure arg2) -> withForeignPtr arg2 $ \argPtr2 ->gst_event_new_custom arg1 argPtr2) (cFromEnum eventType)
                                structure >>=
        takeMiniObject

eventNewEOS, eventNewFlushStart, eventNewFlushStop :: IO Event
eventNewEOS = gst_event_new_eos >>= takeMiniObject
eventNewFlushStart = gst_event_new_flush_start >>= takeMiniObject
eventNewFlushStop = gst_event_new_flush_stop >>= takeMiniObject


eventNewLatency :: ClockTime
                -> IO Event
eventNewLatency latency =
    gst_event_new_latency (fromIntegral latency) >>=
        takeMiniObject


eventNewNavigation :: Structure
                   -> IO Event
eventNewNavigation structure =
    (\(Structure arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_event_new_navigation argPtr1) structure >>=
        takeMiniObject

eventNewNewSegment :: Bool
                   -> Double
                   -> Format
                   -> Int64
                   -> Int64
                   -> Int64
                   -> IO Event
eventNewNewSegment update rate format start stop position =
    gst_event_new_new_segment (fromBool update)
                                     (realToFrac rate)
                                     (fromIntegral $ fromFormat format)
                                     (fromIntegral start)
                                     (fromIntegral stop)
                                     (fromIntegral position) >>=
        takeMiniObject

eventNewNewSegmentFull :: Bool
                       -> Double
                       -> Double
                       -> Format
                       -> Int64
                       -> Int64
                       -> Int64
                       -> IO Event
eventNewNewSegmentFull update appliedRate rate format start stop position =
    gst_event_new_new_segment_full (fromBool update)
                                          (realToFrac rate)
                                          (realToFrac appliedRate)
                                          (fromIntegral $ fromFormat format)
                                          (fromIntegral start)
                                          (fromIntegral stop)
                                          (fromIntegral position) >>=
        takeMiniObject

eventNewQOS :: Double
            -> ClockTimeDiff
            -> ClockTime
            -> IO Event
eventNewQOS proportion diff timestamp =
    gst_event_new_qos (realToFrac proportion)
                             (fromIntegral diff)
                             (fromIntegral timestamp) >>=
        takeMiniObject

eventNewSeek :: Double
             -> Format
             -> [SeekFlags]
             -> SeekType
             -> Int64
             -> SeekType
             -> Int64
             -> IO Event
eventNewSeek rate format flags startType start stopType stop =
    gst_event_new_seek (realToFrac rate)
                              (fromIntegral $ fromFormat format)
                              (cFromFlags flags)
                              (cFromEnum startType)
                              (fromIntegral start)
                              (cFromEnum stopType)
                              (fromIntegral stop) >>=
        takeMiniObject

eventNewTag :: TagList
            -> IO Event
eventNewTag tagList =
    withTagList tagList (gst_event_new_tag . castPtr) >>=
        takeMiniObject

eventParseBufferSize :: EventClass event
                     => event
                     -> Maybe (Format, Int64, Int64, Bool)
eventParseBufferSize event | eventType event == EventBufferSize =
    Just $ unsafePerformIO $ alloca $ \formatPtr -> alloca $ \minSizePtr ->
        alloca $ \maxSizePtr -> alloca $ \asyncPtr ->
            do (\(Event arg1) arg2 arg3 arg4 arg5 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_buffer_size argPtr1 arg2 arg3 arg4 arg5) (toEvent event)
                                                  formatPtr
                                                  minSizePtr
                                                  maxSizePtr
                                                  asyncPtr
               format <- liftM (toFormat . fromIntegral) $ peek formatPtr
               minSize <- liftM fromIntegral $ peek minSizePtr
               maxSize <- liftM fromIntegral $ peek maxSizePtr
               async <- liftM toBool $ peek asyncPtr
               return (format, minSize, maxSize, async)
                           | otherwise = Nothing


eventParseLatency :: EventClass event
                  => event
                  -> Maybe ClockTime
eventParseLatency event | eventType event == EventLatency =
    Just $ unsafePerformIO $ alloca $ \latencyPtr ->
        do (\(Event arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_latency argPtr1 arg2) (toEvent event)
                                          latencyPtr
           liftM fromIntegral $ peek latencyPtr
                        | otherwise = Nothing


eventParseNewSegment :: EventClass event
                     => event
                     -> Maybe (Bool, Double, Format, Int64, Int64, Int64)
eventParseNewSegment event | eventType event == EventNewSegment =
    Just $ unsafePerformIO $ alloca $ \updatePtr ->
        alloca $ \ratePtr -> alloca $ \formatPtr ->
            alloca $ \startPtr -> alloca $ \stopPtr ->
                alloca $ \positionPtr ->
                    do (\(Event arg1) arg2 arg3 arg4 arg5 arg6 arg7 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_new_segment argPtr1 arg2 arg3 arg4 arg5 arg6 arg7) (toEvent event)
                                                          ratePtr
                                                          updatePtr
                                                          formatPtr
                                                          startPtr
                                                          stopPtr
                                                          positionPtr
                       update <- liftM toBool $ peek updatePtr
                       rate <- liftM realToFrac $ peek ratePtr
                       format <- liftM (toFormat . fromIntegral) $ peek formatPtr
                       start <- liftM fromIntegral $ peek startPtr
                       stop <- liftM fromIntegral $ peek stopPtr
                       position <- liftM fromIntegral $ peek positionPtr
                       return (update, rate, format, start, stop, position)
                           | otherwise = Nothing

eventParseNewSegmentFull :: EventClass event
                         => event
                         -> Maybe (Bool, Double, Double, Format, Int64, Int64, Int64)
eventParseNewSegmentFull event | eventType event == EventNewSegment =
    Just $ unsafePerformIO $ alloca $ \updatePtr ->
        alloca $ \ratePtr -> alloca $ \appliedRatePtr ->
            alloca $ \formatPtr -> alloca $ \startPtr ->
                alloca $ \stopPtr -> alloca $ \positionPtr ->
                    do (\(Event arg1) arg2 arg3 arg4 arg5 arg6 arg7 arg8 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_new_segment_full argPtr1 arg2 arg3 arg4 arg5 arg6 arg7 arg8) (toEvent event)
                                                               ratePtr
                                                               appliedRatePtr
                                                               updatePtr
                                                               formatPtr
                                                               startPtr
                                                               stopPtr
                                                               positionPtr
                       update <- liftM toBool $ peek updatePtr
                       rate <- liftM realToFrac $ peek ratePtr
                       appliedRate <- liftM realToFrac $ peek appliedRatePtr
                       format <- liftM (toFormat . fromIntegral) $ peek formatPtr
                       start <- liftM fromIntegral $ peek startPtr
                       stop <- liftM fromIntegral $ peek stopPtr
                       position <- liftM fromIntegral $ peek positionPtr
                       return (update, rate, appliedRate, format, start, stop, position)
                           | otherwise = Nothing

eventParseQOS :: EventClass event
              => event
              -> Maybe (Double, ClockTimeDiff, ClockTime)
eventParseQOS event | eventType event == EventQOS =
    Just $ unsafePerformIO $ alloca $ \proportionPtr ->
        alloca $ \diffPtr -> alloca $ \timestampPtr ->
            do (\(Event arg1) arg2 arg3 arg4 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_qos argPtr1 arg2 arg3 arg4) (toEvent event)
                                          proportionPtr
                                          diffPtr
                                          timestampPtr
               proportion <- liftM realToFrac $ peek proportionPtr
               diff <- liftM fromIntegral $ peek diffPtr
               timestamp <- liftM fromIntegral $ peek timestampPtr
               return (proportion, diff, timestamp)
                    | otherwise = Nothing

eventParseSeek :: EventClass event
               => event
               -> Maybe (Double, Format, [SeekFlags], SeekType, Int64, SeekType, Int64)
eventParseSeek event | eventType event == EventSeek =
    Just $ unsafePerformIO $ alloca $ \ratePtr ->
        alloca $ \formatPtr -> alloca $ \flagsPtr ->
            alloca $ \startTypePtr -> alloca $ \startPtr ->
                alloca $ \stopTypePtr -> alloca $ \stopPtr ->
                    do (\(Event arg1) arg2 arg3 arg4 arg5 arg6 arg7 arg8 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_seek argPtr1 arg2 arg3 arg4 arg5 arg6 arg7 arg8) (toEvent event)
                                                   ratePtr
                                                   formatPtr
                                                   flagsPtr
                                                   startTypePtr
                                                   startPtr
                                                   stopTypePtr
                                                   stopPtr
                       rate <- liftM realToFrac $ peek ratePtr
                       format <- liftM (toFormat . fromIntegral) $ peek formatPtr
                       flags <- liftM cToFlags $ peek flagsPtr
                       startType <- liftM cToEnum $ peek startTypePtr
                       start <- liftM fromIntegral $ peek startPtr
                       stopType <- liftM cToEnum $ peek stopTypePtr
                       stop <- liftM fromIntegral $ peek stopPtr
                       return (rate, format, flags, startType, start, stopType, stop)
                     | otherwise = Nothing

eventParseTag :: EventClass event
              => event
              -> Maybe TagList
eventParseTag event | eventType event == EventTag =
    Just $ unsafePerformIO $ alloca $ \tagListPtr ->
        do (\(Event arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gst_event_parse_tag argPtr1 arg2) (toEvent event) (castPtr tagListPtr)
           peek tagListPtr >>= peekTagList
                    | otherwise = Nothing

eventTypeGetName :: EventType
                 -> String
eventTypeGetName eventType =
    unsafePerformIO $
        gst_event_type_get_name (cFromEnum eventType) >>=
            peekUTFString

eventTypeGetFlags :: EventType
                  -> [EventTypeFlags]
eventTypeGetFlags =
    cToFlags . gst_event_type_get_flags . cFromEnum

foreign import ccall safe "gst_event_new_custom"
  gst_event_new_custom :: (CInt -> ((Ptr Structure) -> (IO (Ptr Event))))

foreign import ccall safe "gst_event_new_eos"
  gst_event_new_eos :: (IO (Ptr Event))

foreign import ccall safe "gst_event_new_flush_start"
  gst_event_new_flush_start :: (IO (Ptr Event))

foreign import ccall safe "gst_event_new_flush_stop"
  gst_event_new_flush_stop :: (IO (Ptr Event))

foreign import ccall safe "gst_event_new_latency"
  gst_event_new_latency :: (CULLong -> (IO (Ptr Event)))

foreign import ccall safe "gst_event_new_navigation"
  gst_event_new_navigation :: ((Ptr Structure) -> (IO (Ptr Event)))

foreign import ccall safe "gst_event_new_new_segment"
  gst_event_new_new_segment :: (CInt -> (CDouble -> (CInt -> (CLLong -> (CLLong -> (CLLong -> (IO (Ptr Event))))))))

foreign import ccall safe "gst_event_new_new_segment_full"
  gst_event_new_new_segment_full :: (CInt -> (CDouble -> (CDouble -> (CInt -> (CLLong -> (CLLong -> (CLLong -> (IO (Ptr Event)))))))))

foreign import ccall safe "gst_event_new_qos"
  gst_event_new_qos :: (CDouble -> (CLLong -> (CULLong -> (IO (Ptr Event)))))

foreign import ccall safe "gst_event_new_seek"
  gst_event_new_seek :: (CDouble -> (CInt -> (CInt -> (CInt -> (CLLong -> (CInt -> (CLLong -> (IO (Ptr Event)))))))))

foreign import ccall safe "gst_event_new_tag"
  gst_event_new_tag :: ((Ptr ()) -> (IO (Ptr Event)))

foreign import ccall safe "gst_event_parse_buffer_size"
  gst_event_parse_buffer_size :: ((Ptr Event) -> ((Ptr CInt) -> ((Ptr CLLong) -> ((Ptr CLLong) -> ((Ptr CInt) -> (IO ()))))))

foreign import ccall safe "gst_event_parse_latency"
  gst_event_parse_latency :: ((Ptr Event) -> ((Ptr CULLong) -> (IO ())))

foreign import ccall safe "gst_event_parse_new_segment"
  gst_event_parse_new_segment :: ((Ptr Event) -> ((Ptr CInt) -> ((Ptr CDouble) -> ((Ptr CInt) -> ((Ptr CLLong) -> ((Ptr CLLong) -> ((Ptr CLLong) -> (IO ()))))))))

foreign import ccall safe "gst_event_parse_new_segment_full"
  gst_event_parse_new_segment_full :: ((Ptr Event) -> ((Ptr CInt) -> ((Ptr CDouble) -> ((Ptr CDouble) -> ((Ptr CInt) -> ((Ptr CLLong) -> ((Ptr CLLong) -> ((Ptr CLLong) -> (IO ())))))))))

foreign import ccall safe "gst_event_parse_qos"
  gst_event_parse_qos :: ((Ptr Event) -> ((Ptr CDouble) -> ((Ptr CLLong) -> ((Ptr CULLong) -> (IO ())))))

foreign import ccall safe "gst_event_parse_seek"
  gst_event_parse_seek :: ((Ptr Event) -> ((Ptr CDouble) -> ((Ptr CInt) -> ((Ptr CInt) -> ((Ptr CInt) -> ((Ptr CLLong) -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO ())))))))))

foreign import ccall safe "gst_event_parse_tag"
  gst_event_parse_tag :: ((Ptr Event) -> ((Ptr (Ptr ())) -> (IO ())))

foreign import ccall safe "gst_event_type_get_name"
  gst_event_type_get_name :: (CInt -> (IO (Ptr CChar)))

foreign import ccall safe "gst_event_type_get_flags"
  gst_event_type_get_flags :: (CInt -> CInt)