{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc)

The 'GI.Gst.Interfaces.URIHandler.URIHandler' is an interface that is implemented by Source and Sink
'GI.Gst.Objects.Element.Element' to unify handling of URI.

An application can use the following functions to quickly get an element
that handles the given URI for reading or writing
('GI.Gst.Objects.Element.elementMakeFromUri').

Source and Sink plugins should implement this interface when possible.
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Gst.Interfaces.URIHandler
    (

-- * Exported types
    URIHandler(..)                          ,
    noURIHandler                            ,
    IsURIHandler                            ,


 -- * Methods
-- ** getProtocols #method:getProtocols#

#if ENABLE_OVERLOADING
    URIHandlerGetProtocolsMethodInfo        ,
#endif
    uRIHandlerGetProtocols                  ,


-- ** getUri #method:getUri#

#if ENABLE_OVERLOADING
    URIHandlerGetUriMethodInfo              ,
#endif
    uRIHandlerGetUri                        ,


-- ** getUriType #method:getUriType#

#if ENABLE_OVERLOADING
    URIHandlerGetUriTypeMethodInfo          ,
#endif
    uRIHandlerGetUriType                    ,


-- ** setUri #method:setUri#

#if ENABLE_OVERLOADING
    URIHandlerSetUriMethodInfo              ,
#endif
    uRIHandlerSetUri                        ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.GI.Base.Properties as B.Properties
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL

import {-# SOURCE #-} qualified GI.Gst.Enums as Gst.Enums

-- interface URIHandler 
-- | Memory-managed wrapper type.
newtype URIHandler = URIHandler (ManagedPtr URIHandler)
-- | A convenience alias for `Nothing` :: `Maybe` `URIHandler`.
noURIHandler :: Maybe URIHandler
noURIHandler = Nothing

#if ENABLE_OVERLOADING
type instance O.SignalList URIHandler = URIHandlerSignalList
type URIHandlerSignalList = ('[ ] :: [(Symbol, *)])

#endif

-- | Type class for types which implement `URIHandler`.
class ManagedPtrNewtype a => IsURIHandler a
instance IsURIHandler URIHandler
-- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
instance WrappedPtr URIHandler where
    wrappedPtrCalloc = return nullPtr
    wrappedPtrCopy = return
    wrappedPtrFree = Nothing


#if ENABLE_OVERLOADING
type family ResolveURIHandlerMethod (t :: Symbol) (o :: *) :: * where
    ResolveURIHandlerMethod "getProtocols" o = URIHandlerGetProtocolsMethodInfo
    ResolveURIHandlerMethod "getUri" o = URIHandlerGetUriMethodInfo
    ResolveURIHandlerMethod "getUriType" o = URIHandlerGetUriTypeMethodInfo
    ResolveURIHandlerMethod "setUri" o = URIHandlerSetUriMethodInfo
    ResolveURIHandlerMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveURIHandlerMethod t URIHandler, O.MethodInfo info URIHandler p) => OL.IsLabel t (URIHandler -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

#endif

-- method URIHandler::get_protocols
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "handler", argType = TInterface (Name {namespace = "Gst", name = "URIHandler"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "A #GstURIHandler.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TCArray True (-1) (-1) (TBasicType TUTF8))
-- throws : False
-- Skip return : False

foreign import ccall "gst_uri_handler_get_protocols" gst_uri_handler_get_protocols ::
    Ptr URIHandler ->                       -- handler : TInterface (Name {namespace = "Gst", name = "URIHandler"})
    IO (Ptr CString)

{- |
Gets the list of protocols supported by /@handler@/. This list may not be
modified.
-}
uRIHandlerGetProtocols ::
    (B.CallStack.HasCallStack, MonadIO m, IsURIHandler a) =>
    a
    {- ^ /@handler@/: A 'GI.Gst.Interfaces.URIHandler.URIHandler'. -}
    -> m (Maybe [T.Text])
    {- ^ __Returns:__ the
    supported protocols.  Returns 'Nothing' if the /@handler@/ isn\'t
    implemented properly, or the /@handler@/ doesn\'t support any
    protocols. -}
uRIHandlerGetProtocols handler = liftIO $ do
    handler' <- unsafeManagedPtrCastPtr handler
    result <- gst_uri_handler_get_protocols handler'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- unpackZeroTerminatedUTF8CArray result'
        return result''
    touchManagedPtr handler
    return maybeResult

#if ENABLE_OVERLOADING
data URIHandlerGetProtocolsMethodInfo
instance (signature ~ (m (Maybe [T.Text])), MonadIO m, IsURIHandler a) => O.MethodInfo URIHandlerGetProtocolsMethodInfo a signature where
    overloadedMethod _ = uRIHandlerGetProtocols

#endif

-- method URIHandler::get_uri
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "handler", argType = TInterface (Name {namespace = "Gst", name = "URIHandler"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "A #GstURIHandler", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TUTF8)
-- throws : False
-- Skip return : False

foreign import ccall "gst_uri_handler_get_uri" gst_uri_handler_get_uri ::
    Ptr URIHandler ->                       -- handler : TInterface (Name {namespace = "Gst", name = "URIHandler"})
    IO CString

{- |
Gets the currently handled URI.
-}
uRIHandlerGetUri ::
    (B.CallStack.HasCallStack, MonadIO m, IsURIHandler a) =>
    a
    {- ^ /@handler@/: A 'GI.Gst.Interfaces.URIHandler.URIHandler' -}
    -> m (Maybe T.Text)
    {- ^ __Returns:__ the URI currently handled by
  the /@handler@/.  Returns 'Nothing' if there are no URI currently
  handled. The returned string must be freed with 'GI.GLib.Functions.free' when no
  longer needed. -}
uRIHandlerGetUri handler = liftIO $ do
    handler' <- unsafeManagedPtrCastPtr handler
    result <- gst_uri_handler_get_uri handler'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- cstringToText result'
        freeMem result'
        return result''
    touchManagedPtr handler
    return maybeResult

#if ENABLE_OVERLOADING
data URIHandlerGetUriMethodInfo
instance (signature ~ (m (Maybe T.Text)), MonadIO m, IsURIHandler a) => O.MethodInfo URIHandlerGetUriMethodInfo a signature where
    overloadedMethod _ = uRIHandlerGetUri

#endif

-- method URIHandler::get_uri_type
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "handler", argType = TInterface (Name {namespace = "Gst", name = "URIHandler"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "A #GstURIHandler.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "URIType"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_uri_handler_get_uri_type" gst_uri_handler_get_uri_type ::
    Ptr URIHandler ->                       -- handler : TInterface (Name {namespace = "Gst", name = "URIHandler"})
    IO CUInt

{- |
Gets the type of the given URI handler
-}
uRIHandlerGetUriType ::
    (B.CallStack.HasCallStack, MonadIO m, IsURIHandler a) =>
    a
    {- ^ /@handler@/: A 'GI.Gst.Interfaces.URIHandler.URIHandler'. -}
    -> m Gst.Enums.URIType
    {- ^ __Returns:__ the 'GI.Gst.Enums.URIType' of the URI handler.
Returns @/GST_URI_UNKNOWN/@ if the /@handler@/ isn\'t implemented correctly. -}
uRIHandlerGetUriType handler = liftIO $ do
    handler' <- unsafeManagedPtrCastPtr handler
    result <- gst_uri_handler_get_uri_type handler'
    let result' = (toEnum . fromIntegral) result
    touchManagedPtr handler
    return result'

#if ENABLE_OVERLOADING
data URIHandlerGetUriTypeMethodInfo
instance (signature ~ (m Gst.Enums.URIType), MonadIO m, IsURIHandler a) => O.MethodInfo URIHandlerGetUriTypeMethodInfo a signature where
    overloadedMethod _ = uRIHandlerGetUriType

#endif

-- method URIHandler::set_uri
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "handler", argType = TInterface (Name {namespace = "Gst", name = "URIHandler"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "A #GstURIHandler", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "uri", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "URI to set", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TBoolean)
-- throws : True
-- Skip return : False

foreign import ccall "gst_uri_handler_set_uri" gst_uri_handler_set_uri ::
    Ptr URIHandler ->                       -- handler : TInterface (Name {namespace = "Gst", name = "URIHandler"})
    CString ->                              -- uri : TBasicType TUTF8
    Ptr (Ptr GError) ->                     -- error
    IO CInt

{- |
Tries to set the URI of the given handler.
-}
uRIHandlerSetUri ::
    (B.CallStack.HasCallStack, MonadIO m, IsURIHandler a) =>
    a
    {- ^ /@handler@/: A 'GI.Gst.Interfaces.URIHandler.URIHandler' -}
    -> T.Text
    {- ^ /@uri@/: URI to set -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
uRIHandlerSetUri handler uri = liftIO $ do
    handler' <- unsafeManagedPtrCastPtr handler
    uri' <- textToCString uri
    onException (do
        _ <- propagateGError $ gst_uri_handler_set_uri handler' uri'
        touchManagedPtr handler
        freeMem uri'
        return ()
     ) (do
        freeMem uri'
     )

#if ENABLE_OVERLOADING
data URIHandlerSetUriMethodInfo
instance (signature ~ (T.Text -> m ()), MonadIO m, IsURIHandler a) => O.MethodInfo URIHandlerSetUriMethodInfo a signature where
    overloadedMethod _ = uRIHandlerSetUri

#endif