 
 module Bindings.GDAL.Internal (
     Datatype (..)
-  , Access (..)
   , ColorInterpretation (..)
   , PaletteInterpretation (..)
   , GDALException

  , DriverOptions
  , MajorObject
  , Dataset
  , Band
  , Driver
  , ColorTable

        else f rBand

foreign import ccall unsafe "gdal.h GDALGetRasterBand" getRasterBand
        :: (Ptr (Dataset a)) -> (CInt -> (IO ((Band a))))


bandDatatype :: Band a -> Datatype
bandDatatype band = toEnumC . getDatatype_ $ band

foreign import ccall unsafe "gdal.h GDALGetRasterDataType" getDatatype_
   :: Band a -> CInt


bandBlockSize :: Band a -> (Int,Int)
bandBlockSize band = unsafePerformIO $ alloca $ \xPtr -> alloca $ \yPtr -> do
   -- unsafePerformIO is safe here since the block size cant change once
   -- a dataset is created
   getBlockSize_ band xPtr yPtr
   liftA2 (,) (liftM fromIntegral $ peek xPtr) (liftM fromIntegral $ peek yPtr)

foreign import ccall unsafe "gdal.h GDALGetBlockSize" getBlockSize_
    :: Band a -> Ptr CInt -> Ptr CInt -> IO ()


bandBlockLen :: Band a -> Int
bandBlockLen = uncurry (*) . bandBlockSize

bandSize :: Band a -> (Int, Int)
bandSize band
  = (fromIntegral . getXSize_ $ band, fromIntegral . getYSize_ $ band)

foreign import ccall unsafe "gdal.h GDALGetRasterBandXSize" getXSize_
  :: Band a -> CInt

foreign import ccall unsafe "gdal.h GDALGetRasterBandYSize" getYSize_
  :: Band a -> CInt


bandNodataValue :: Band a -> IO (Maybe Double)
bandNodataValue b = alloca $ \p -> do
   value <- liftM realToFrac $ getNodata_ b p
   hasNodata <- liftM toBool $ peek p
   return (if hasNodata then Just value else Nothing)
   
foreign import ccall unsafe "gdal.h GDALGetRasterNoDataValue" getNodata_
   :: Band a -> Ptr CInt -> IO CDouble
   

setBandNodataValue :: RWBand -> Double -> IO ()
setBandNodataValue b v = throwIfError "could not set nodata" $
                            setNodata_ b (realToFrac v)

foreign import ccall safe "gdal.h GDALSetRasterNoDataValue" setNodata_
    :: RWBand -> CDouble -> IO CInt


fillBand :: RWBand -> Double -> Double -> IO ()
fillBand b r i = throwIfError "could not fill band" $
    fillRaster_ b (realToFrac r) (realToFrac i)

foreign import ccall safe "gdal.h GDALFillRaster" fillRaster_
    :: RWBand -> CDouble -> CDouble -> IO CInt


class HasDatatype a where
    datatype :: a -> Datatype
