{-# LINE 2 "./System/GIO/Volumes/Drive.chs" #-}
-- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*-
--
-- Author : Andy Stewart
-- Created: 30-Apirl-2010
--
-- Copyright (c) 2010 Andy Stewart
--
-- 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:
--
-- GIO, 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 GIO documentation.
--
-- | Maintainer : gtk2hs-devel@lists.sourceforge.net
-- Stability : alpha
-- Portability : portable (depends on GHC)
module System.GIO.Volumes.Drive (
-- * Details
--
-- | 'Drive' - this represent a piece of hardware connected to the machine. It's generally only created
-- for removable hardware or hardware with removable media.
--
-- 'Drive' is a container class for 'Volume' objects that stem from the same piece of media. As such,
-- 'Drive' abstracts a drive with (or without) removable media and provides operations for querying
-- whether media is available, determing whether media change is automatically detected and ejecting
-- the media.
--
-- If the 'Drive' reports that media isn't automatically detected, one can poll for media; typically one
-- should not do this periodically as a poll for media operation is potententially expensive and may
-- spin up the drive creating noise.
--
-- 'Drive' supports starting and stopping drives with authentication support for the former. This can be
-- used to support a diverse set of use cases including connecting/disconnecting iSCSI devices,
-- powering down external disk enclosures and starting/stopping multi-disk devices such as RAID
-- devices. Note that the actual semantics and side-effects of starting/ stopping a 'Drive' may vary
-- according to implementation. To choose the correct verbs in e.g. a file manager, use
-- 'driveGetStartStopType'.
--
-- For porting from GnomeVFS note that there is no equivalent of 'Drive' in that API.

-- * Types
    Drive(..),
    DriveClass,

-- * Enums,

    DriveStartStopType (..),
    DriveStartFlags (..),


-- * Methods
    driveGetName,
    driveGetIcon,
    driveHasVolumes,
    driveGetVolumes,
    driveCanEject,

    driveGetStartStopType,
    driveCanStart,
    driveCanStartDegraded,
    driveCanStop,

    driveCanPollForMedia,
    drivePollForMedia,
    driveHasMedia,
    driveIsMediaCheckAutomatic,
    driveIsMediaRemovable,

    driveEjectWithOperation,
    driveEjectWithOperationFinish,
    driveStart,
    driveStartFinish,
    driveStopFinish,

    driveEnumerateIdentifiers,
    driveGetIdentifier,

-- * Signals
    driveChanged,
    driveDisconnected,
    driveEjectButton,

    driveStopButton,

    ) where

import Control.Monad
import Data.Maybe (fromMaybe)
import System.GIO.Enums
import System.Glib.Attributes
import System.Glib.FFI
import System.Glib.Flags
import System.Glib.GError
import System.Glib.GList
import System.Glib.GObject
import System.Glib.Properties
import System.Glib.Signals
import System.Glib.UTFString
import System.GIO.Async.AsyncResult
{-# LINE 113 "./System/GIO/Volumes/Drive.chs" #-}
import System.GIO.Signals
{-# LINE 114 "./System/GIO/Volumes/Drive.chs" #-}
import System.GIO.Types
{-# LINE 115 "./System/GIO/Volumes/Drive.chs" #-}


{-# LINE 117 "./System/GIO/Volumes/Drive.chs" #-}

--------------------
-- Methods
-- | Gets the name of drive.
driveGetName :: (DriveClass drive, GlibString string) => drive
 -> IO string -- ^ returns the name for the given drive.
driveGetName drive =
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_get_name argPtr1) (toDrive drive)
  >>= readUTFString

-- | Gets the icon for drive.
driveGetIcon :: DriveClass drive => drive
 -> IO Icon -- ^ returns a 'Icon'.
driveGetIcon drive =
  wrapNewGObject mkIcon $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_get_icon argPtr1) (toDrive drive)

-- | Check if drive has any mountable volumes.
driveHasVolumes :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if the drive contains volumes, 'False' otherwise.
driveHasVolumes drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_has_volumes argPtr1) (toDrive drive)

-- | Get a list of mountable volumes for drive.
driveGetVolumes :: DriveClass drive => drive
 -> IO [Volume]
driveGetVolumes drive = do
  glistPtr <- (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_get_volumes argPtr1) (toDrive drive)
  volumePtrs <- fromGList glistPtr
  mapM (wrapNewGObject mkVolume . return) volumePtrs

-- | Checks if drive can be eject.
driveCanEject :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if the drive can be ejected.
driveCanEject drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_can_eject argPtr1) (toDrive drive)


-- | Gets a hint about how a drive can be started/stopped.
driveGetStartStopType :: DriveClass drive => drive
 -> IO DriveStartStopType -- ^ returns A value from the 'DriveStartStopType' enumeration.
driveGetStartStopType drive =
  liftM (toEnum . fromIntegral) $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_get_start_stop_type argPtr1) (toDrive drive)

-- | Checks if a drive can be started.
driveCanStart :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if the drive can be started, 'False' otherwise.
driveCanStart drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_can_start argPtr1) (toDrive drive)

-- | Checks if a drive can be started degraded.
driveCanStartDegraded :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if the drive can be started degraded, 'False' otherwise.
driveCanStartDegraded drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_can_start_degraded argPtr1) (toDrive drive)

-- | Checks if a drive can be stoped.
driveCanStop :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if the drive can be stoped, 'False' otherwise.
driveCanStop drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_can_stop argPtr1) (toDrive drive)


-- | Checks if a drive can be polled for media changes.
driveCanPollForMedia :: DriveClass drive => drive
 -> IO Bool
driveCanPollForMedia drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_can_poll_for_media argPtr1) (toDrive drive)

-- | Asynchronously polls drive to see if media has been inserted or removed.
--
-- When the operation is finished, callback will be called. You can then call
-- 'drivePollForMediaFinish' to obtain the result of the operation.
drivePollForMedia :: DriveClass drive => drive
 -> Maybe Cancellable
 -> AsyncReadyCallback
 -> IO ()
drivePollForMedia drive cancellable callback = do
      cCallback <- marshalAsyncReadyCallback callback
      (\(Drive arg1) (Cancellable arg2) arg3 arg4 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->g_drive_poll_for_media argPtr1 argPtr2 arg3 arg4)
{-# LINE 204 "./System/GIO/Volumes/Drive.chs" #-}
        (toDrive drive)
        (fromMaybe (Cancellable nullForeignPtr) cancellable)
        cCallback
        (castFunPtrToPtr cCallback)

-- | Finishes an operation started with 'drivePollForMedia' on a drive.
--
-- Throws a 'GError' if an error occurs.
drivePollForMediaFinish :: DriveClass drive => drive
 -> AsyncResult -- ^ @result@ a 'AsyncResult'.
 -> IO ()
drivePollForMediaFinish drive result =
    propagateGError (\gErrorPtr -> do
                       (\(Drive arg1) (AsyncResult arg2) arg3 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->g_drive_poll_for_media_finish argPtr1 argPtr2 arg3)
{-# LINE 218 "./System/GIO/Volumes/Drive.chs" #-}
                          (toDrive drive)
                          result
                          gErrorPtr
                       return ())

-- | Checks if the drive has media. Note that the OS may not be polling the drive for media changes; see
-- 'driveIsMediaCheckAutomatic' for more details.
driveHasMedia :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if drive has media, 'False' otherwise.
driveHasMedia drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_has_media argPtr1) (toDrive drive)

-- | Checks if drive is capabable of automatically detecting media changes.
driveIsMediaCheckAutomatic :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if the drive is capabable of automatically detecting media changes, 'False' otherwise.
driveIsMediaCheckAutomatic drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_is_media_check_automatic argPtr1) (toDrive drive)

-- | Checks if the drive supports removable media.
driveIsMediaRemovable :: DriveClass drive => drive
 -> IO Bool -- ^ returns 'True' if drive supports removable media, 'False' otherwise.
driveIsMediaRemovable drive =
  liftM toBool $
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_is_media_removable argPtr1) (toDrive drive)


-- | Ejects a drive. This is an asynchronous operation, and is finished by calling
-- 'driveEjectWithOperationFinish' with the drive and 'AsyncResult' data returned in the callback.
driveEjectWithOperation :: DriveClass drive
 => drive
 -> [MountUnmountFlags] -- ^ @flags@ flags affecting the unmount if required for eject
 -> Maybe MountOperation -- ^ @mountOperation@ a 'MountOperation' or 'Nothing' to avoid user interaction.
 -> Maybe Cancellable -- ^ @cancellable@ optional 'Cancellable' object, 'Nothing' to ignore.
 -> AsyncReadyCallback -- ^ @callback@ a 'AsyncReadyCallback'
 -> IO ()
driveEjectWithOperation drive flags mountOperation cancellable callback = do
      cCallback <- marshalAsyncReadyCallback callback
      (\(Drive arg1) arg2 (MountOperation arg3) (Cancellable arg4) arg5 arg6 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg3 $ \argPtr3 ->withForeignPtr arg4 $ \argPtr4 ->g_drive_eject_with_operation argPtr1 arg2 argPtr3 argPtr4 arg5 arg6)
{-# LINE 258 "./System/GIO/Volumes/Drive.chs" #-}
        (toDrive drive)
        ((fromIntegral . fromFlags) flags)
        (fromMaybe (MountOperation nullForeignPtr) mountOperation)
        (fromMaybe (Cancellable nullForeignPtr) cancellable)
        cCallback
        (castFunPtrToPtr cCallback)

-- | Finishes ejecting a drive. If any errors occurred during the operation, error will be set to contain
-- the errors and 'False' will be returned.
--
-- Throws a 'GError' if an error occurs.
driveEjectWithOperationFinish :: DriveClass drive
 => drive
 -> AsyncResult -- ^ @result@ a 'AsyncResult'.
 -> IO ()
driveEjectWithOperationFinish drive result =
    propagateGError (\gErrorPtr -> do
                        (\(Drive arg1) (AsyncResult arg2) arg3 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->g_drive_eject_with_operation_finish argPtr1 argPtr2 arg3)
{-# LINE 276 "./System/GIO/Volumes/Drive.chs" #-}
                           (toDrive drive)
                           result
                           gErrorPtr
                        return ())

-- | Asynchronously starts a drive.
--
-- When the operation is finished, callback will be called. You can then call 'driveStartFinish' to
-- obtain the result of the operation.
driveStart :: DriveClass drive
 => drive
 -> [DriveStartFlags] -- ^ @flags@ flags affecting the start operation.
 -> Maybe MountOperation -- ^ @mountOperation@ a 'MountOperation' or 'Nothing' to avoid user interaction.
 -> Maybe Cancellable -- ^ @cancellable@ optional 'Cancellable' object, 'Nothing' to ignore.
 -> AsyncReadyCallback -- ^ @callback@ a 'AsyncReadyCallback'
 -> IO ()
driveStart drive flags mountOperation cancellable callback = do
      cCallback <- marshalAsyncReadyCallback callback
      (\(Drive arg1) arg2 (MountOperation arg3) (Cancellable arg4) arg5 arg6 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg3 $ \argPtr3 ->withForeignPtr arg4 $ \argPtr4 ->g_drive_start argPtr1 arg2 argPtr3 argPtr4 arg5 arg6)
{-# LINE 295 "./System/GIO/Volumes/Drive.chs" #-}
        (toDrive drive)
        ((fromIntegral . fromFlags) flags)
        (fromMaybe (MountOperation nullForeignPtr) mountOperation)
        (fromMaybe (Cancellable nullForeignPtr) cancellable)
        cCallback
        (castFunPtrToPtr cCallback)

-- | Finishes starting a drive.
--
-- Throws a 'GError' if an error occurs.
driveStartFinish :: DriveClass drive
 => drive
 -> AsyncResult -- ^ @result@ a 'AsyncResult'.
 -> IO ()
driveStartFinish drive result =
    propagateGError (\gErrorPtr -> do
                       (\(Drive arg1) (AsyncResult arg2) arg3 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->g_drive_start_finish argPtr1 argPtr2 arg3)
{-# LINE 312 "./System/GIO/Volumes/Drive.chs" #-}
                           (toDrive drive)
                           result
                           gErrorPtr
                       return ())

-- | Asynchronously stops a drive.
--
-- When the operation is finished, callback will be called. You can then call 'driveStopFinish' to
-- obtain the result of the operation.
driveStop :: DriveClass drive
 => drive
 -> [MountUnmountFlags] -- ^ @flags@ flags affecting the stop operation.
 -> Maybe MountOperation -- ^ @mountOperation@ a 'MountOperation' or 'Nothing' to avoid user interaction.
 -> Maybe Cancellable -- ^ @cancellable@ optional 'Cancellable' object, 'Nothing' to ignore.
 -> AsyncReadyCallback -- ^ @callback@ a 'AsyncReadyCallback'
 -> IO ()
driveStop drive flags mountOperation cancellable callback = do
      cCallback <- marshalAsyncReadyCallback callback
      (\(Drive arg1) arg2 (MountOperation arg3) (Cancellable arg4) arg5 arg6 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg3 $ \argPtr3 ->withForeignPtr arg4 $ \argPtr4 ->g_drive_stop argPtr1 arg2 argPtr3 argPtr4 arg5 arg6)
{-# LINE 331 "./System/GIO/Volumes/Drive.chs" #-}
        (toDrive drive)
        ((fromIntegral . fromFlags) flags)
        (fromMaybe (MountOperation nullForeignPtr) mountOperation)
        (fromMaybe (Cancellable nullForeignPtr) cancellable)
        cCallback
        (castFunPtrToPtr cCallback)

-- | Finishes stoping a drive.
--
-- Throws a 'GError' if an error occurs.
driveStopFinish :: DriveClass drive
 => drive
 -> AsyncResult -- ^ @result@ a 'AsyncResult'.
 -> IO ()
driveStopFinish drive result =
    propagateGError (\gErrorPtr -> do
                        (\(Drive arg1) (AsyncResult arg2) arg3 -> withForeignPtr arg1 $ \argPtr1 ->withForeignPtr arg2 $ \argPtr2 ->g_drive_stop_finish argPtr1 argPtr2 arg3)
{-# LINE 348 "./System/GIO/Volumes/Drive.chs" #-}
                             (toDrive drive)
                             result
                             gErrorPtr
                        return ())


-- | Gets the kinds of identifiers that drive has. Use 'driveGetIdentifer' to obtain the
-- identifiers themselves.
driveEnumerateIdentifiers :: (DriveClass drive, GlibString string) => drive
                           -> IO [string]
driveEnumerateIdentifiers drive =
  (\(Drive arg1) -> withForeignPtr arg1 $ \argPtr1 ->g_drive_enumerate_identifiers argPtr1) (toDrive drive)
  >>= readUTFStringArray0

-- | Gets the identifier of the given kind for drive. See the introduction for more information about
-- drive identifiers.
driveGetIdentifier :: (DriveClass drive, GlibString string) => drive
                    -> string -- ^ @kind@ the kind of identifier to return
                    -> IO string
driveGetIdentifier drive kind =
  withUTFString kind $ \ kindPtr ->
  (\(Drive arg1) arg2 -> withForeignPtr arg1 $ \argPtr1 ->g_drive_get_identifier argPtr1 arg2) (toDrive drive) kindPtr
  >>= readUTFString

--------------------
-- Signals
-- | Emitted when a drive changes.
driveChanged :: DriveClass drive => Signal drive (Drive -> IO ())
driveChanged = Signal (connect_OBJECT__NONE "drive-changed")

-- | Emitted when a drive changes.
driveDisconnected :: DriveClass drive => Signal drive (Drive -> IO ())
driveDisconnected = Signal (connect_OBJECT__NONE "drive-disconnected")

-- | Emitted when the eject button is pressed on drive.
driveEjectButton :: DriveClass drive => Signal drive (Drive -> IO ())
driveEjectButton = Signal (connect_OBJECT__NONE "drive-eject-button")


-- | Emitted when the stop button is pressed on drive.
driveStopButton :: DriveClass drive => Signal drive (Drive -> IO ())
driveStopButton = Signal (connect_OBJECT__NONE "drive-stop-button")

foreign import ccall safe "g_drive_get_name"
  g_drive_get_name :: ((Ptr Drive) -> (IO (Ptr CChar)))

foreign import ccall safe "g_drive_get_icon"
  g_drive_get_icon :: ((Ptr Drive) -> (IO (Ptr Icon)))

foreign import ccall safe "g_drive_has_volumes"
  g_drive_has_volumes :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_get_volumes"
  g_drive_get_volumes :: ((Ptr Drive) -> (IO (Ptr ())))

foreign import ccall safe "g_drive_can_eject"
  g_drive_can_eject :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_get_start_stop_type"
  g_drive_get_start_stop_type :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_can_start"
  g_drive_can_start :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_can_start_degraded"
  g_drive_can_start_degraded :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_can_stop"
  g_drive_can_stop :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_can_poll_for_media"
  g_drive_can_poll_for_media :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_poll_for_media"
  g_drive_poll_for_media :: ((Ptr Drive) -> ((Ptr Cancellable) -> ((FunPtr ((Ptr ()) -> ((Ptr AsyncResult) -> ((Ptr ()) -> (IO ()))))) -> ((Ptr ()) -> (IO ())))))

foreign import ccall safe "g_drive_poll_for_media_finish"
  g_drive_poll_for_media_finish :: ((Ptr Drive) -> ((Ptr AsyncResult) -> ((Ptr (Ptr ())) -> (IO CInt))))

foreign import ccall safe "g_drive_has_media"
  g_drive_has_media :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_is_media_check_automatic"
  g_drive_is_media_check_automatic :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_is_media_removable"
  g_drive_is_media_removable :: ((Ptr Drive) -> (IO CInt))

foreign import ccall safe "g_drive_eject_with_operation"
  g_drive_eject_with_operation :: ((Ptr Drive) -> (CInt -> ((Ptr MountOperation) -> ((Ptr Cancellable) -> ((FunPtr ((Ptr ()) -> ((Ptr AsyncResult) -> ((Ptr ()) -> (IO ()))))) -> ((Ptr ()) -> (IO ())))))))

foreign import ccall safe "g_drive_eject_with_operation_finish"
  g_drive_eject_with_operation_finish :: ((Ptr Drive) -> ((Ptr AsyncResult) -> ((Ptr (Ptr ())) -> (IO CInt))))

foreign import ccall safe "g_drive_start"
  g_drive_start :: ((Ptr Drive) -> (CInt -> ((Ptr MountOperation) -> ((Ptr Cancellable) -> ((FunPtr ((Ptr ()) -> ((Ptr AsyncResult) -> ((Ptr ()) -> (IO ()))))) -> ((Ptr ()) -> (IO ())))))))

foreign import ccall safe "g_drive_start_finish"
  g_drive_start_finish :: ((Ptr Drive) -> ((Ptr AsyncResult) -> ((Ptr (Ptr ())) -> (IO CInt))))

foreign import ccall safe "g_drive_stop"
  g_drive_stop :: ((Ptr Drive) -> (CInt -> ((Ptr MountOperation) -> ((Ptr Cancellable) -> ((FunPtr ((Ptr ()) -> ((Ptr AsyncResult) -> ((Ptr ()) -> (IO ()))))) -> ((Ptr ()) -> (IO ())))))))

foreign import ccall safe "g_drive_stop_finish"
  g_drive_stop_finish :: ((Ptr Drive) -> ((Ptr AsyncResult) -> ((Ptr (Ptr ())) -> (IO CInt))))

foreign import ccall safe "g_drive_enumerate_identifiers"
  g_drive_enumerate_identifiers :: ((Ptr Drive) -> (IO (Ptr (Ptr CChar))))

foreign import ccall safe "g_drive_get_identifier"
  g_drive_get_identifier :: ((Ptr Drive) -> ((Ptr CChar) -> (IO (Ptr CChar))))