{-# LINE 1 "src/SFML/Graphics/Rect.hsc" #-}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
{-# LINE 2 "src/SFML/Graphics/Rect.hsc" #-}
module SFML.Graphics.Rect
(
    FloatRect(..)
,   IntRect(..)
,   Rect(..)
,   floatRectContains
,   intRectContains
)
where


import Control.Applicative ((<$>), (<*>))
import Foreign.C.Types
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Utils (with)
import Foreign.Ptr (Ptr)
import Foreign.Storable
import System.IO.Unsafe


{-# LINE 22 "src/SFML/Graphics/Rect.hsc" #-}


sizeInt = (4)
{-# LINE 25 "src/SFML/Graphics/Rect.hsc" #-}
sizeFloat = (4)
{-# LINE 26 "src/SFML/Graphics/Rect.hsc" #-}


-- | Utility class for manipulating rectangles.
data FloatRect = FloatRect
    { fleft   :: Float
    , ftop    :: Float
    , fwidth  :: Float
    , fheight :: Float
    }


instance Storable FloatRect where
    sizeOf _ = 4 * sizeFloat
    alignment _ = alignment (undefined :: CFloat)

    peek ptr = FloatRect
            <$> fmap realToFrac ((\hsc_ptr -> peekByteOff hsc_ptr 0) ptr :: IO CFloat)
{-# LINE 43 "src/SFML/Graphics/Rect.hsc" #-}
            <*> fmap realToFrac ((\hsc_ptr -> peekByteOff hsc_ptr 4) ptr :: IO CFloat)
{-# LINE 44 "src/SFML/Graphics/Rect.hsc" #-}
            <*> fmap realToFrac ((\hsc_ptr -> peekByteOff hsc_ptr 8) ptr :: IO CFloat)
{-# LINE 45 "src/SFML/Graphics/Rect.hsc" #-}
            <*> fmap realToFrac ((\hsc_ptr -> peekByteOff hsc_ptr 12) ptr :: IO CFloat)
{-# LINE 46 "src/SFML/Graphics/Rect.hsc" #-}

    poke ptr (FloatRect l t w h) = do
        (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (realToFrac l :: CFloat)
{-# LINE 49 "src/SFML/Graphics/Rect.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr (realToFrac t :: CFloat)
{-# LINE 50 "src/SFML/Graphics/Rect.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr (realToFrac w :: CFloat)
{-# LINE 51 "src/SFML/Graphics/Rect.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 12) ptr (realToFrac h :: CFloat)
{-# LINE 52 "src/SFML/Graphics/Rect.hsc" #-}


-- | Utility class for manipulating rectangles.
data IntRect = IntRect
    { ileft   :: Int
    , itop    :: Int
    , iwidth  :: Int
    , iheight :: Int
    }


instance Storable IntRect where
    sizeOf _ = 4 * sizeInt
    alignment _ = alignment (undefined :: CInt)

    peek ptr = IntRect
            <$> fmap fromIntegral ((\hsc_ptr -> peekByteOff hsc_ptr 0) ptr   :: IO CInt)
{-# LINE 69 "src/SFML/Graphics/Rect.hsc" #-}
            <*> fmap fromIntegral ((\hsc_ptr -> peekByteOff hsc_ptr 4) ptr    :: IO CInt)
{-# LINE 70 "src/SFML/Graphics/Rect.hsc" #-}
            <*> fmap fromIntegral ((\hsc_ptr -> peekByteOff hsc_ptr 8) ptr  :: IO CInt)
{-# LINE 71 "src/SFML/Graphics/Rect.hsc" #-}
            <*> fmap fromIntegral ((\hsc_ptr -> peekByteOff hsc_ptr 12) ptr :: IO CInt)
{-# LINE 72 "src/SFML/Graphics/Rect.hsc" #-}

    poke ptr (IntRect l t w h) = do
        (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (fromIntegral l :: CInt)
{-# LINE 75 "src/SFML/Graphics/Rect.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr (fromIntegral t :: CInt)
{-# LINE 76 "src/SFML/Graphics/Rect.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr (fromIntegral w :: CInt)
{-# LINE 77 "src/SFML/Graphics/Rect.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 12) ptr (fromIntegral h :: CInt)
{-# LINE 78 "src/SFML/Graphics/Rect.hsc" #-}


-- | Check if a point is inside a rectangle's area.
floatRectContains
    :: Float -- ^ X coordinate of the point to test
    -> Float -- ^ Y coordinate of the point to test
    -> FloatRect -- ^ Rectangle to test
    -> Bool

floatRectContains x y r = unsafeDupablePerformIO $ fmap (/=0) . with r $ \ptr -> sfFloatRect_contains ptr x y

foreign import ccall unsafe "sfFloatRect_contains"
    sfFloatRect_contains :: Ptr FloatRect -> Float -> Float -> IO CInt

--CSFML_GRAPHICS_API sfBool sfFloatRect_contains(const sfFloatRect* rect, float x, float y);


-- | Check if a point is inside a rectangle's area.
intRectContains
    :: Int -- ^ X coordinate of the point to test
    -> Int -- ^ Y coordinate of the point to test
    -> IntRect -- ^ Rectangle to test
    -> Bool

intRectContains x y r = unsafeDupablePerformIO $ fmap (/=0) . with r $
    \ptr -> sfIntRect_contains ptr (fromIntegral x) (fromIntegral y)

foreign import ccall unsafe "sfIntRect_contains"
    sfIntRect_contains :: Ptr IntRect -> CInt -> CInt -> IO CInt

--CSFML_GRAPHICS_API sfBool sfIntRect_contains(const sfIntRect* rect, int x, int y);


class Rect a where
    -- | Check intersection between two rectangles.
    intersectRect
        :: a -- ^ First rectangle to test
        -> a -- ^ Second rectangle to test
        -> Maybe a -- ^ Overlapping rect


instance Rect FloatRect where

    intersectRect r1 r2 = unsafeDupablePerformIO $
        alloca $ \ptr1 ->
        alloca $ \ptr2 ->
        alloca $ \ptrOut -> do
        poke ptr1 r1
        poke ptr2 r2
        result <- sfFloatRect_intersects ptr1 ptr2 ptrOut
        case result of
            0 -> return Nothing
            _ -> peek ptrOut >>= return . Just


foreign import ccall unsafe "sfFloatRect_intersects"
    sfFloatRect_intersects :: Ptr FloatRect -> Ptr FloatRect -> Ptr FloatRect -> IO CInt

--CSFML_GRAPHICS_API sfBool sfFloatRect_intersects(const sfFloatRect* rect1, const sfFloatRect* rect2, sfFloatRect* intersection);


instance Rect IntRect where

    intersectRect r1 r2 = unsafeDupablePerformIO $
        alloca $ \ptr1 ->
        alloca $ \ptr2 ->
        alloca $ \ptrOut -> do
        poke ptr1 r1
        poke ptr2 r2
        result <- sfIntRect_intersects ptr1 ptr2 ptrOut
        case result of
            0 -> return Nothing
            _ -> peek ptrOut >>= return . Just


foreign import ccall unsafe "sfIntRect_intersects"
    sfIntRect_intersects :: Ptr IntRect -> Ptr IntRect -> Ptr IntRect -> IO CInt

--CSFML_GRAPHICS_API sfBool sfIntRect_intersects(const sfIntRect* rect1, const sfIntRect* rect2, sfIntRect* intersection);