 import Data.Complex (Complex(..))
 import Data.Maybe (isJust)
 import Data.Proxy (Proxy(..))
-import Data.Typeable (Typeable, typeOf)
+import Data.Typeable (Typeable)
 import Data.Word (Word8, Word16, Word32)
 import Data.Vector.Storable (Vector, unsafeFromForeignPtr0, unsafeToForeignPtr0)
 import Foreign.C.String (withCString, CString, peekCString)


{#pointer GDALDatasetH as Dataset foreign newtype nocode#}

data ReadOnly
data ReadWrite
newtype Dataset a t = Dataset (ForeignPtr (Dataset a t), Mutex)

unDataset :: Dataset a t -> ForeignPtr (Dataset a t)
unDataset (Dataset (d, _)) = d

checkType :: forall t a. GDALType a => Dataset t a -> IO (Dataset t a)
checkType ds
  | datasetBandCount ds > 0 = withBand ds 1 $ \b ->
      if datatype (Proxy :: Proxy a) == bandDatatype b
        then return ds
        else throw InvalidType
  | otherwise = return ds

{-
data SomeDataset t = forall a. GDALType a => SomeDataset (Dataset t a)

openAnyReadOnly :: FilePath -> IO (SomeDataset ReadOnly)
openAnyReadOnly p = withCString p $ \p' ->
  open_ p' (fromEnumC GA_ReadOnly) >>= (fmap SomeDataset . newDatasetHandle)

openAnyReadWrite :: FilePath -> IO (SomeDataset ReadWrite)
openAnyReadWrite p = withCString p $ \p' ->
  open_ p' (fromEnumC GA_Update) >>= (fmap SomeDataset . newDatasetHandle)
-}

foreign import ccall safe "gdal.h GDALOpen" open_
   :: CString -> CInt -> IO (Ptr (Dataset a t))


createCopy' :: GDALType a
  => Driver -> String -> (Dataset t a) -> Bool -> DriverOptions
  -> ProgressFun -> IO (RWDataset a)
createCopy' driver path dataset strict options progressFun = do
  d <- driverByName driver
  withCString path $ \p ->
