 import Control.Applicative (Applicative(..), (<$>), liftA2)
 import Control.Exception (Exception(..))
 import Control.DeepSeq (NFData(..))
-import Control.Monad (liftM2, when, (>=>), (<=<), forever)
+import Control.Monad (liftM2, when, (>=>), forever)
+import Control.Monad.Catch (MonadThrow, throwM)
 import Control.Monad.Trans (lift)
 import Control.Monad.IO.Class (MonadIO(liftIO))
 

  {#call unsafe GetFileList as ^#} .
  unDataset

datasetProjection :: MonadIO m => Dataset s a t -> m (Maybe SpatialReference)
datasetProjection
  = liftIO
  .  (maybeSpatialReferenceFromCString <=< {#call GetProjectionRef as ^#})
  . unDataset

datasetProjectionWkt :: MonadIO m => Dataset s a t -> m (Maybe ByteString)
datasetProjectionWkt ds = liftIO $ do
  p <- {#call GetProjectionRef as ^#} (unDataset ds)
  if p == nullPtr then return Nothing else Just <$> packCString p

setDatasetProjection :: SpatialReference -> RWDataset s a -> GDAL s ()
setDatasetProjection srs = setDatasetProjectionWkt (srsToWkt srs)

bandGeotransform :: MonadIO m => Band s a t -> m (Maybe Geotransform)
bandGeotransform = datasetGeotransform . unsafeBandDataset

bandProjection :: (MonadThrow m, MonadIO m) => Band s a t -> m (Maybe SpatialReference)
bandProjection = datasetProjection . unsafeBandDataset


