{-# LINE 2 "./Media/Streaming/GStreamer/Core/ElementFactory.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)
--
-- A factory for creating 'Element's.
module Media.Streaming.GStreamer.Core.ElementFactory (

-- * Detail

  -- | 'ElementFactory' is used to create instances of 'Element's.
  --
  -- Use 'elementFactoryFind' and 'elementFactoryCreate' to create
  -- element instances, or use 'elementFactoryMake' as a convenient
  -- shortcut.

-- * Types
  ElementFactory,
  ElementFactoryClass,
  castToElementFactory,
  gTypeElementFactory,

-- * ElementFactory Operations
  elementFactoryFind,
  elementFactoryGetElementType,
  elementFactoryGetLongname,
  elementFactoryGetKlass,
  elementFactoryGetDescription,
  elementFactoryGetAuthor,
  elementFactoryGetNumPadTemplates,
  elementFactoryGetURIType,
  elementFactoryGetURIProtocols,

  elementFactoryHasInterface,

  elementFactoryCreate,
  elementFactoryMake,
  elementFactoryCanSinkCaps,
  elementFactoryCanSrcCaps,
  elementFactoryGetPadTemplates

  ) where

import Control.Monad ( liftM )
import Data.Maybe ( fromMaybe )
import System.Glib.FFI
import System.Glib.UTFString ( withUTFString
                             , peekUTFString
                             , peekUTFStringArray0 )
import System.Glib.GType ( GType )
import System.Glib.GList ( readGList )
import Media.Streaming.GStreamer.Core.Types
{-# LINE 79 "./Media/Streaming/GStreamer/Core/ElementFactory.chs" #-}


{-# LINE 81 "./Media/Streaming/GStreamer/Core/ElementFactory.chs" #-}

-- | Search for an element factory with the given name.
elementFactoryFind :: String -- ^ @name@ - the name of the desired factory
                   -> IO (Maybe ElementFactory) -- ^ the factory if found, otherwise 'Nothing'
elementFactoryFind name =
    withUTFString name gst_element_factory_find >>= maybePeek takeObject

-- | Get the 'GType' for elements managed by the given factory. The type
-- can only be retrieved if the element factory is loaded, which can
-- be assured with
-- 'Media.Streaming.GStreamer.Core.PluginFeature.pluginFeatureLoad'.
elementFactoryGetElementType :: (ElementFactoryClass elementFactory)
                             => elementFactory -- ^ @factory@ - an element factory
                             -> IO (Maybe GType) -- ^ the type of elements managed
                                                 -- by the factory, or 'Nothing' if
                                                 -- the factory is not loaded
elementFactoryGetElementType factory =
    do gtype <- (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_element_type argPtr1) (toElementFactory factory)
       if gtype == 0
          then return $ Just $ fromIntegral gtype
          else return Nothing

-- | Get the long name for the given factory.
elementFactoryGetLongname :: (ElementFactoryClass elementFactory)
                          => elementFactory -- ^ @factory@ - an element factory
                          -> IO String -- ^ the factory's long name
elementFactoryGetLongname factory =
    (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_longname argPtr1) (toElementFactory factory) >>=
        peekUTFString

-- | Get the class for the given factory.
elementFactoryGetKlass :: (ElementFactoryClass elementFactory)
                       => elementFactory -- ^ @factory@ - an element factory
                       -> IO String -- ^ the factory's class
elementFactoryGetKlass factory =
    (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_klass argPtr1) (toElementFactory factory) >>=
        peekUTFString

-- | Get the description for the given factory.
elementFactoryGetDescription :: (ElementFactoryClass elementFactory)
                             => elementFactory -- ^ @factory@ - an element factory
                             -> IO String -- ^ the factory's description
elementFactoryGetDescription factory =
    (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_description argPtr1) (toElementFactory factory) >>=
        peekUTFString

-- | Get the author of the given factory.
elementFactoryGetAuthor :: (ElementFactoryClass elementFactory)
                        => elementFactory -- ^ @factory@ - an element factory
                        -> IO String -- ^ the factory's author
elementFactoryGetAuthor factory =
    (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_author argPtr1) (toElementFactory factory) >>=
        peekUTFString

-- | Get the number of 'PadTemplate's provided by the given factory.
elementFactoryGetNumPadTemplates :: (ElementFactoryClass elementFactory)
                                 => elementFactory -- ^ @factory@ - an element factory
                                 -> IO Word -- ^ the number of 'PadTemplate's
elementFactoryGetNumPadTemplates factory =
    liftM fromIntegral $
        (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_num_pad_templates argPtr1) $ toElementFactory factory

-- | Get the type of URIs supported by the given factory.
elementFactoryGetURIType :: (ElementFactoryClass elementFactory)
                         => elementFactory -- ^ @factory@ - an element factory
                         -> IO Int -- ^ the type of URIs supported by the factory
elementFactoryGetURIType factory =
    liftM fromIntegral $
        (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_uri_type argPtr1) $ toElementFactory factory

-- | Get the list of protocols supported by the given factory.
elementFactoryGetURIProtocols :: (ElementFactoryClass elementFactory)
                              => elementFactory -- ^ @factory@ - an element factory
                              -> IO [String] -- ^ the supported protocols
elementFactoryGetURIProtocols factory =
    (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_uri_protocols argPtr1) (toElementFactory factory) >>=
        liftM (fromMaybe []) . maybePeek peekUTFStringArray0


-- | Check if the given factory implements the interface with the given name.
--
-- Since 0.10.14.
elementFactoryHasInterface :: (ElementFactoryClass elementFactory)
                           => elementFactory -- ^ @factory@ - an element factory
                           -> String -- ^ @name@ - the interface name
                           -> IO Bool -- ^ true if the interface is implemented
elementFactoryHasInterface factory name =
    liftM toBool .
        withUTFString name .
        (\(ElementFactory arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_has_interface argPtr1 arg2) .
        toElementFactory $
        factory


-- | Create a new element of the type supplied by the given
-- factory. It will be given the name supplied.
elementFactoryCreate :: (ElementFactoryClass elementFactory)
                     => elementFactory -- ^ @factory@ - an element factory
                     -> String -- ^ @name@ - the new element's name
                     -> IO (Maybe Element) -- ^ the new element if it could be created,
                                           -- otherwise 'Nothing'
elementFactoryCreate factory name =
    withUTFString name $ \cName ->
        (\(ElementFactory arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_create argPtr1 arg2) (toElementFactory factory) cName >>=
            maybePeek takeObject

-- | Create a new element of the type supplied by the named
-- factory.
elementFactoryMake :: String -- ^ @factoryName@ - the name of an element factory
                   -> Maybe String -- ^ @name@ - the new element's name, or
                                         -- 'Nothing' generate a unique name
                   -> IO (Maybe Element) -- ^ the new element if it could be created,
                                         -- otherwise 'Nothing'
elementFactoryMake factoryName name =
    withUTFString factoryName $ \cFactoryName ->
        maybeWith withUTFString name $ \cName ->
            gst_element_factory_make cFactoryName cName >>=
                maybePeek takeObject

-- | Check if the given factory can sink the given capabilities.
elementFactoryCanSinkCaps :: (ElementFactoryClass elementFactory)
                          => elementFactory -- ^ @factory@ - an element factory
                          -> Caps -- ^ @caps@ - the capabilities to check for
                          -> IO Bool -- ^ 'True' if @factory@ can sink the given capabilities
elementFactoryCanSinkCaps factory caps =
    liftM toBool $ (\(ElementFactory arg1) (Caps arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_element_factory_can_sink_caps argPtr1 argPtr2) (toElementFactory factory) caps

-- | Check if the given factory can source the given capabilities.
elementFactoryCanSrcCaps :: (ElementFactoryClass elementFactory)
                         => elementFactory -- ^ @factory@ - an element factory
                         -> Caps -- ^ @caps@ - the capabilities to check for
                         -> IO Bool -- ^ 'True' if @factory@ can source the given capabilities
elementFactoryCanSrcCaps factory caps =
    liftM toBool $ (\(ElementFactory arg1) (Caps arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_element_factory_can_src_caps argPtr1 argPtr2) (toElementFactory factory) caps

-- | Get the pad templates provided by the given factory.
elementFactoryGetPadTemplates :: (ElementFactoryClass elementFactory)
                              => elementFactory -- ^ @factory@ - an element factory
                              -> IO [PadTemplate] -- ^ the provided pad templates
elementFactoryGetPadTemplates =
    (\(ElementFactory arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_element_factory_get_static_pad_templates argPtr1) . toElementFactory >=>
        readGList >=> mapM staticPadTemplateGet
    where infixr 8 >=>
          a >=> b = \x -> a x >>= b

foreign import ccall safe "gst_element_factory_find"
  gst_element_factory_find :: ((Ptr CChar) -> (IO (Ptr ElementFactory)))

foreign import ccall safe "gst_element_factory_get_element_type"
  gst_element_factory_get_element_type :: ((Ptr ElementFactory) -> (IO CUInt))

foreign import ccall safe "gst_element_factory_get_longname"
  gst_element_factory_get_longname :: ((Ptr ElementFactory) -> (IO (Ptr CChar)))

foreign import ccall safe "gst_element_factory_get_klass"
  gst_element_factory_get_klass :: ((Ptr ElementFactory) -> (IO (Ptr CChar)))

foreign import ccall safe "gst_element_factory_get_description"
  gst_element_factory_get_description :: ((Ptr ElementFactory) -> (IO (Ptr CChar)))

foreign import ccall safe "gst_element_factory_get_author"
  gst_element_factory_get_author :: ((Ptr ElementFactory) -> (IO (Ptr CChar)))

foreign import ccall safe "gst_element_factory_get_num_pad_templates"
  gst_element_factory_get_num_pad_templates :: ((Ptr ElementFactory) -> (IO CUInt))

foreign import ccall safe "gst_element_factory_get_uri_type"
  gst_element_factory_get_uri_type :: ((Ptr ElementFactory) -> (IO CInt))

foreign import ccall safe "gst_element_factory_get_uri_protocols"
  gst_element_factory_get_uri_protocols :: ((Ptr ElementFactory) -> (IO (Ptr (Ptr CChar))))

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

foreign import ccall safe "gst_element_factory_create"
  gst_element_factory_create :: ((Ptr ElementFactory) -> ((Ptr CChar) -> (IO (Ptr Element))))

foreign import ccall safe "gst_element_factory_make"
  gst_element_factory_make :: ((Ptr CChar) -> ((Ptr CChar) -> (IO (Ptr Element))))

foreign import ccall safe "gst_element_factory_can_sink_caps"
  gst_element_factory_can_sink_caps :: ((Ptr ElementFactory) -> ((Ptr Caps) -> (IO CInt)))

foreign import ccall safe "gst_element_factory_can_src_caps"
  gst_element_factory_can_src_caps :: ((Ptr ElementFactory) -> ((Ptr Caps) -> (IO CInt)))

foreign import ccall safe "gst_element_factory_get_static_pad_templates"
  gst_element_factory_get_static_pad_templates :: ((Ptr ElementFactory) -> (IO (Ptr ())))