module Data.VHD.Bitmap
	( Bitmap (..)
	, bitmapGet
	, bitmapSet
	, bitmapSetRange
	, bitmapClear
	) where

import Foreign.Ptr
import Foreign.Storable
import Data.Word
import Data.Bits

data Bitmap = Bitmap (Ptr Word8)

bitmapGet :: Bitmap -> Int -> IO Bool
bitmapGet (Bitmap ptr) n = test `fmap` peekByteOff ptr offset
	where
		test :: Word8 -> Bool
		test = flip testBit (7-bit)
		(offset, bit) = n `divMod` 8

bitmapModify :: Bitmap -> Int -> (Int -> Word8 -> Word8) -> IO ()
bitmapModify (Bitmap bptr) n f = peek ptr >>= poke ptr . f (7-bit)
	where
		ptr = bptr `plusPtr` offset
		(offset, bit) = n `divMod` 8

bitmapSet :: Bitmap -> Int -> IO ()
bitmapSet bitmap n = bitmapModify bitmap n (flip setBit)

bitmapSetRange :: Bitmap -> Int -> Int -> IO ()
bitmapSetRange bitmap start end
	| start < end = bitmapSet bitmap start >> bitmapSetRange bitmap (start + 1) end
	| otherwise   = return ()

bitmapClear :: Bitmap -> Int -> IO ()
bitmapClear bitmap n = bitmapModify bitmap n (flip clearBit)