{-# LINE 2 "./Media/Streaming/GStreamer/Core/Pad.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)
module Media.Streaming.GStreamer.Core.Pad (

  Pad,
  PadClass,
  castToPad,
  gTypePad,

  PadFlags(..),

  PadDirection(..),
  PadLinkReturn(..),
  FlowReturn(..),
  ActivateMode(..),

  padGetFlags,
  padSetFlags,
  padUnsetFlags,
  padNew,
  padGetDirection,
  padGetParentElement,
  padLink,
  padUnlink,
  padIsLinked,
  padCanLink,
  padGetCaps,
  padGetAllowedCaps,
  padGetNegotiatedCaps,
  padGetPadTemplateCaps,
  padSetCaps,
  padGetPeer,
  padPeerGetCaps,
  padIsActive,
  padSetBlocked,
  padIsBlocked,

  padIsBlocking,

  padNewFromTemplate,
  padAcceptCaps,
  padProxyGetcaps,
  padFixateCaps,
  padPeerAcceptCaps,
  padSendEvent,
  padQuery,
  padQueryPosition,
  padQueryDuration,
  padQueryConvert,
  padQueryPeerPosition,
  padQueryPeerDuration,
  padQueryPeerConvert,
  padGetQueryTypes,
  onPadLinked,
  afterPadLinked,
  onPadRequestLink,
  afterPadRequestLink,
  onPadUnlinked,
  afterPadUnlinked,

  padCaps,
  padDirection,
  padTemplate,

  ) where

import Control.Monad (liftM)
import Data.Maybe (fromMaybe)
import Media.Streaming.GStreamer.Core.Types
{-# LINE 97 "./Media/Streaming/GStreamer/Core/Pad.chs" #-}
import Media.Streaming.GStreamer.Core.Signals
{-# LINE 98 "./Media/Streaming/GStreamer/Core/Pad.chs" #-}

import System.Glib.FFI
import System.Glib.UTFString
import System.Glib.GList
import System.Glib.Properties ( objectGetPropertyGObject )
import System.Glib.Attributes ( ReadAttr
                              , readAttr )
import System.Glib.Signals
{-# LINE 106 "./Media/Streaming/GStreamer/Core/Pad.chs" #-}


{-# LINE 108 "./Media/Streaming/GStreamer/Core/Pad.chs" #-}

padGetFlags :: PadClass padT
            => padT
            -> IO [PadFlags]
padGetFlags = mkObjectGetFlags

padSetFlags :: PadClass padT
            => padT
            -> [PadFlags]
            -> IO ()
padSetFlags = mkObjectSetFlags

padUnsetFlags :: PadClass padT
              => padT
              -> [PadFlags]
              -> IO ()
padUnsetFlags = mkObjectUnsetFlags

padNew :: String
       -> PadDirection
       -> IO Pad
padNew name direction =
    withUTFString name $ \cName ->
        gst_pad_new cName (fromIntegral $ fromEnum direction) >>=
            takeObject

padGetDirection :: PadClass pad
                => pad
                -> IO PadDirection
padGetDirection pad =
    liftM (toEnum . fromIntegral) $
        (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_direction argPtr1) $ toPad pad

padGetParentElement :: PadClass pad
                    => pad
                    -> IO Element
padGetParentElement pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_parent_element argPtr1) (toPad pad) >>=
        peekObject

padLink :: (PadClass srcpad, PadClass sinkpad)
        => srcpad
        -> sinkpad
        -> IO PadLinkReturn
padLink srcpad sinkpad =
    liftM (toEnum . fromIntegral) $
        (\(Pad arg1) (Pad arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_link argPtr1 argPtr2) (toPad srcpad) (toPad sinkpad)

padUnlink :: (PadClass srcpad, PadClass sinkpad)
          => srcpad
          -> sinkpad
          -> IO Bool
padUnlink srcpad sinkpad =
    liftM toBool $
        (\(Pad arg1) (Pad arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_unlink argPtr1 argPtr2) (toPad srcpad) (toPad sinkpad)

padIsLinked :: PadClass pad
            => pad
            -> IO Bool
padIsLinked pad =
    liftM toBool $
        (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_is_linked argPtr1) (toPad pad)

padCanLink :: (PadClass srcpad, PadClass sinkpad)
           => srcpad
           -> sinkpad
           -> IO Bool
padCanLink srcpad sinkpad =
    liftM toBool $
        (\(Pad arg1) (Pad arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_can_link argPtr1 argPtr2) (toPad srcpad) (toPad sinkpad)

padGetCaps :: PadClass pad
           => pad
           -> IO Caps
padGetCaps pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_caps argPtr1) (toPad pad) >>= takeCaps

padGetAllowedCaps :: PadClass pad
                  => pad
                  -> IO (Maybe Caps)
padGetAllowedCaps pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_allowed_caps argPtr1) (toPad pad) >>=
        maybePeek takeCaps

padGetNegotiatedCaps :: PadClass pad
                     => pad
                     -> IO (Maybe Caps)
padGetNegotiatedCaps pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_negotiated_caps argPtr1) (toPad pad) >>=
        maybePeek takeCaps

padGetPadTemplateCaps :: PadClass pad
                      => pad
                      -> IO Caps
padGetPadTemplateCaps pad =
    (liftM Caps $
         (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_pad_template_caps argPtr1) (toPad pad) >>=
             newForeignPtr_) >>=
        (\(Caps arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_caps_copy argPtr1) >>= takeCaps

padSetCaps :: PadClass pad
           => pad
           -> Maybe Caps
           -> IO Bool
padSetCaps pad caps =
    liftM toBool $ (\(Pad arg1) (Caps arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_set_caps argPtr1 argPtr2) (toPad pad) $
        fromMaybe (Caps nullForeignPtr) caps

padGetPeer :: PadClass pad
           => pad
           -> IO (Maybe Pad)
padGetPeer pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_peer argPtr1) (toPad pad) >>= maybePeek takeObject

padPeerGetCaps :: PadClass pad
               => pad
               -> IO (Maybe Caps)
padPeerGetCaps pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_peer_get_caps argPtr1) (toPad pad) >>= maybePeek takeCaps

padIsActive :: PadClass pad
            => pad
            -> IO Bool
padIsActive =
    (liftM toBool) . (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_is_active argPtr1) . toPad

padSetBlocked :: PadClass pad
              => pad
              -> Bool
              -> IO Bool
padSetBlocked pad blocked =
    liftM toBool $
        (\(Pad arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_set_blocked argPtr1 arg2) (toPad pad) (fromBool blocked)

padIsBlocked :: PadClass pad
             => pad
             -> IO Bool
padIsBlocked =
    (liftM toBool) . (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_is_blocked argPtr1) . toPad


padIsBlocking :: PadClass pad
              => pad
              -> IO Bool
padIsBlocking =
    (liftM toBool) . (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_is_blocking argPtr1) . toPad


padNewFromTemplate :: PadTemplateClass padTemplate
                   => padTemplate
                   -> String
                   -> IO (Maybe Pad)
padNewFromTemplate padTemplate name =
    withUTFString name $ \cName ->
        (\(PadTemplate arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_new_from_template argPtr1 arg2) (toPadTemplate padTemplate) cName >>=
            maybePeek takeObject

padAcceptCaps :: PadClass pad
              => pad
              -> Caps
              -> IO Bool
padAcceptCaps pad caps =
    liftM toBool $ (\(Pad arg1) (Caps arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_accept_caps argPtr1 argPtr2) (toPad pad) caps

padProxyGetcaps :: PadClass pad
                => pad
                -> IO Caps
padProxyGetcaps pad =
    (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_proxy_getcaps argPtr1) (toPad pad) >>= takeCaps

padFixateCaps :: PadClass pad
              => pad
              -> Caps
              -> IO Caps
padFixateCaps pad caps =
    do caps' <- (\(Caps arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_caps_copy argPtr1) caps >>= newForeignPtr_
       (\(Pad arg1) (Caps arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_fixate_caps argPtr1 argPtr2) (toPad pad) (Caps caps')
       withForeignPtr caps' takeCaps

padPeerAcceptCaps :: PadClass pad
                  => pad
                  -> Caps
                  -> IO Bool
padPeerAcceptCaps pad caps =
    liftM toBool $ (\(Pad arg1) (Caps arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_peer_accept_caps argPtr1 argPtr2) (toPad pad) caps

padSendEvent :: (PadClass pad, EventClass event)
             => pad
             -> event
             -> IO Bool
padSendEvent pad event =
    liftM toBool $
        giveMiniObject (toEvent event) $ (\(Pad arg1) (Event arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_send_event argPtr1 argPtr2) (toPad pad)

padQuery :: (PadClass pad, QueryClass query)
         => pad
         -> query
         -> IO (Maybe query)
padQuery pad query =
    do query' <- (\(MiniObject arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_mini_object_copy argPtr1) (toMiniObject query) >>=
                    newForeignPtr_ . castPtr
       success <- (\(Pad arg1) (Query arg2) -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->gst_pad_query argPtr1 argPtr2) (toPad pad) $ Query query'
       if toBool success
           then liftM Just $ withForeignPtr query' $ takeMiniObject . castPtr
           else return Nothing

padQueryPosition :: PadClass pad
                 => pad
                 -> IO (Maybe (Format, Int64))
padQueryPosition pad =
    alloca $ \formatPtr ->
        alloca $ \curPtr ->
            do success <- (\(Pad arg1) arg2 arg3 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_query_position argPtr1 arg2 arg3) (toPad pad) formatPtr curPtr
               if toBool success
                   then do format <- peek formatPtr
                           cur <- peek curPtr
                           return $ Just (toFormat $ fromIntegral format,
                                          fromIntegral cur)
                   else return Nothing

padQueryDuration :: PadClass pad
                 => pad
                 -> IO (Maybe (Format, Int64))
padQueryDuration pad =
    alloca $ \formatPtr ->
        alloca $ \durationPtr ->
            do success <- (\(Pad arg1) arg2 arg3 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_query_duration argPtr1 arg2 arg3) (toPad pad) formatPtr durationPtr
               if toBool success
                   then do format <- peek formatPtr
                           duration <- peek durationPtr
                           return $ Just (toFormat $ fromIntegral format,
                                          fromIntegral duration)
                   else return Nothing

padQueryConvert :: PadClass pad
                => pad
                -> Format
                -> Int64
                -> IO (Maybe (Format, Int64))
padQueryConvert pad srcFormat srcVal =
    alloca $ \destFormatPtr ->
        alloca $ \destValPtr ->
            do success <- (\(Pad arg1) arg2 arg3 arg4 arg5 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_query_convert argPtr1 arg2 arg3 arg4 arg5) (toPad pad)
                                                       (fromIntegral $ fromFormat srcFormat)
                                                       (fromIntegral srcVal)
                                                       destFormatPtr
                                                       destValPtr
               if toBool success
                   then do destFormat <- peek destFormatPtr
                           destVal <- peek destValPtr
                           return $ Just (toFormat $ fromIntegral destFormat,
                                          fromIntegral destVal)
                   else return Nothing

padQueryPeerPosition :: PadClass pad
                     => pad
                     -> IO (Maybe (Format, Int64))
padQueryPeerPosition pad =
    alloca $ \formatPtr ->
        alloca $ \curPtr ->
            do success <- (\(Pad arg1) arg2 arg3 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_query_peer_position argPtr1 arg2 arg3) (toPad pad) formatPtr curPtr
               if toBool success
                   then do format <- peek formatPtr
                           cur <- peek curPtr
                           return $ Just (toFormat $ fromIntegral format,
                                          fromIntegral cur)
                   else return Nothing

padQueryPeerDuration :: PadClass pad
                     => pad
                     -> IO (Maybe (Format, Int64))
padQueryPeerDuration pad =
    alloca $ \formatPtr ->
        alloca $ \durationPtr ->
            do success <- (\(Pad arg1) arg2 arg3 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_query_peer_duration argPtr1 arg2 arg3) (toPad pad) formatPtr durationPtr
               if toBool success
                   then do format <- peek formatPtr
                           duration <- peek durationPtr
                           return $ Just (toFormat $ fromIntegral format,
                                          fromIntegral duration)
                   else return Nothing

padQueryPeerConvert :: PadClass pad
                    => pad
                    -> Format
                    -> Int64
                    -> IO (Maybe (Format, Int64))
padQueryPeerConvert pad srcFormat srcVal =
    alloca $ \destFormatPtr ->
        alloca $ \destValPtr ->
            do success <- (\(Pad arg1) arg2 arg3 arg4 arg5 -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_query_peer_convert argPtr1 arg2 arg3 arg4 arg5) (toPad pad)
                                                            (fromIntegral $ fromFormat srcFormat)
                                                            (fromIntegral srcVal)
                                                            destFormatPtr
                                                            destValPtr
               if toBool success
                   then do destFormat <- peek destFormatPtr
                           destVal <- peek destValPtr
                           return $ Just (toFormat $ fromIntegral destFormat,
                                          fromIntegral destVal)
                   else return Nothing

padGetQueryTypes :: PadClass pad
                 => pad
                 -> IO [QueryType]
padGetQueryTypes pad =
    liftM (map (toEnum . fromIntegral)) $
        (\(Pad arg1) -> withForeignPtr arg1 $ \argPtr1 ->gst_pad_get_query_types argPtr1) (toPad pad) >>=
            peekArray0 0

onPadLinked, afterPadLinked :: (PadClass pad)
                            => pad
                            -> (Pad -> IO ())
                            -> IO (ConnectId pad)
onPadLinked =
    connect_OBJECT__NONE "linked" False
afterPadLinked =
    connect_OBJECT__NONE "linked" True

onPadRequestLink, afterPadRequestLink :: (PadClass pad)
                                      => pad
                                      -> IO ()
                                      -> IO (ConnectId pad)
onPadRequestLink =
    connect_NONE__NONE "request-link" False
afterPadRequestLink =
    connect_NONE__NONE "request-link" True

onPadUnlinked, afterPadUnlinked :: (PadClass pad)
                                => pad
                                -> (Pad -> IO ())
                                -> IO (ConnectId pad)
onPadUnlinked =
    connect_OBJECT__NONE "unlinked" False
afterPadUnlinked =
    connect_OBJECT__NONE "unlinked" True

padCaps :: PadClass pad
        => ReadAttr pad Caps
padCaps = readAttr
    padGetCaps

padDirection :: PadClass pad
             => ReadAttr pad PadDirection
padDirection = readAttr
    padGetDirection

padTemplate :: PadClass pad
            => ReadAttr pad PadTemplate
padTemplate = readAttr $
    objectGetPropertyGObject gst_pad_template_get_type
{-# LINE 459 "./Media/Streaming/GStreamer/Core/Pad.chs" #-}
                             "template"

padParentElement :: PadClass pad
                 => ReadAttr pad Element
padParentElement = readAttr
    padGetParentElement

padQueryTypes :: PadClass pad
              => ReadAttr pad [QueryType]
padQueryTypes = readAttr
    padGetQueryTypes

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

foreign import ccall safe "gst_pad_get_direction"
  gst_pad_get_direction :: ((Ptr Pad) -> (IO CInt))

foreign import ccall safe "gst_pad_get_parent_element"
  gst_pad_get_parent_element :: ((Ptr Pad) -> (IO (Ptr Element)))

foreign import ccall safe "gst_pad_link"
  gst_pad_link :: ((Ptr Pad) -> ((Ptr Pad) -> (IO CInt)))

foreign import ccall safe "gst_pad_unlink"
  gst_pad_unlink :: ((Ptr Pad) -> ((Ptr Pad) -> (IO CInt)))

foreign import ccall safe "gst_pad_is_linked"
  gst_pad_is_linked :: ((Ptr Pad) -> (IO CInt))

foreign import ccall safe "gst_pad_can_link"
  gst_pad_can_link :: ((Ptr Pad) -> ((Ptr Pad) -> (IO CInt)))

foreign import ccall safe "gst_pad_get_caps"
  gst_pad_get_caps :: ((Ptr Pad) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_pad_get_allowed_caps"
  gst_pad_get_allowed_caps :: ((Ptr Pad) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_pad_get_negotiated_caps"
  gst_pad_get_negotiated_caps :: ((Ptr Pad) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_pad_get_pad_template_caps"
  gst_pad_get_pad_template_caps :: ((Ptr Pad) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_caps_copy"
  gst_caps_copy :: ((Ptr Caps) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_pad_set_caps"
  gst_pad_set_caps :: ((Ptr Pad) -> ((Ptr Caps) -> (IO CInt)))

foreign import ccall safe "gst_pad_get_peer"
  gst_pad_get_peer :: ((Ptr Pad) -> (IO (Ptr Pad)))

foreign import ccall safe "gst_pad_peer_get_caps"
  gst_pad_peer_get_caps :: ((Ptr Pad) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_pad_is_active"
  gst_pad_is_active :: ((Ptr Pad) -> (IO CInt))

foreign import ccall safe "gst_pad_set_blocked"
  gst_pad_set_blocked :: ((Ptr Pad) -> (CInt -> (IO CInt)))

foreign import ccall safe "gst_pad_is_blocked"
  gst_pad_is_blocked :: ((Ptr Pad) -> (IO CInt))

foreign import ccall safe "gst_pad_is_blocking"
  gst_pad_is_blocking :: ((Ptr Pad) -> (IO CInt))

foreign import ccall safe "gst_pad_new_from_template"
  gst_pad_new_from_template :: ((Ptr PadTemplate) -> ((Ptr CChar) -> (IO (Ptr Pad))))

foreign import ccall safe "gst_pad_accept_caps"
  gst_pad_accept_caps :: ((Ptr Pad) -> ((Ptr Caps) -> (IO CInt)))

foreign import ccall safe "gst_pad_proxy_getcaps"
  gst_pad_proxy_getcaps :: ((Ptr Pad) -> (IO (Ptr Caps)))

foreign import ccall safe "gst_pad_fixate_caps"
  gst_pad_fixate_caps :: ((Ptr Pad) -> ((Ptr Caps) -> (IO ())))

foreign import ccall safe "gst_pad_peer_accept_caps"
  gst_pad_peer_accept_caps :: ((Ptr Pad) -> ((Ptr Caps) -> (IO CInt)))

foreign import ccall safe "gst_pad_send_event"
  gst_pad_send_event :: ((Ptr Pad) -> ((Ptr Event) -> (IO CInt)))

foreign import ccall safe "gst_mini_object_copy"
  gst_mini_object_copy :: ((Ptr MiniObject) -> (IO (Ptr MiniObject)))

foreign import ccall safe "gst_pad_query"
  gst_pad_query :: ((Ptr Pad) -> ((Ptr Query) -> (IO CInt)))

foreign import ccall safe "gst_pad_query_position"
  gst_pad_query_position :: ((Ptr Pad) -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO CInt))))

foreign import ccall safe "gst_pad_query_duration"
  gst_pad_query_duration :: ((Ptr Pad) -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO CInt))))

foreign import ccall safe "gst_pad_query_convert"
  gst_pad_query_convert :: ((Ptr Pad) -> (CInt -> (CLLong -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO CInt))))))

foreign import ccall safe "gst_pad_query_peer_position"
  gst_pad_query_peer_position :: ((Ptr Pad) -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO CInt))))

foreign import ccall safe "gst_pad_query_peer_duration"
  gst_pad_query_peer_duration :: ((Ptr Pad) -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO CInt))))

foreign import ccall safe "gst_pad_query_peer_convert"
  gst_pad_query_peer_convert :: ((Ptr Pad) -> (CInt -> (CLLong -> ((Ptr CInt) -> ((Ptr CLLong) -> (IO CInt))))))

foreign import ccall safe "gst_pad_get_query_types"
  gst_pad_get_query_types :: ((Ptr Pad) -> (IO (Ptr CInt)))

foreign import ccall safe "gst_pad_template_get_type"
  gst_pad_template_get_type :: CUInt