-- GENERATED by C->Haskell Compiler, version 0.16.0 Crystal Seed, 24 Jan 2009 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./Algebra/Geometric/Polygon.chs" #-}{-# LANGUAGE ForeignFunctionInterface #-}

-- Polygon.chs

-- hgeometric: A geometric library with bindings to GPC.
-- Polygon.chs is part of hgeometric.

-- Copyright 2007, 2009 Marco TĂșlio Gontijo e Silva
-- Copyright 2007, 2009 Rafael Cunha de Almeida

-- See LICENSE

-- | 'Polygon' data type.
module Algebra.Geometric.Polygon (Polygon (PolygonC, polygonSet)) where


import Data.Set hiding (map)
import Control.Monad
import Foreign
import Foreign.C

import Algebra.Geometric.Area
import Algebra.Geometric.Contour


{-# LINE 26 "./Algebra/Geometric/Polygon.chs" #-}

-- | A 'Polygon', which support holes and disjoint areas. Each 'Bool' in the
-- tuple tells if the 'Contour' is the border of a hole ('True') or of a
-- 'Polygon' ('False').
newtype Polygon = PolygonC {polygonSet :: Set (Bool, Contour)} deriving Show

type CContour = Ptr (Contour)
{-# LINE 33 "./Algebra/Geometric/Polygon.chs" #-}

instance Storable Polygon where
    sizeOf _ = 12
{-# LINE 36 "./Algebra/Geometric/Polygon.chs" #-}

    alignment _ = alignment (undefined :: Int)

    peek cPolygon =
        (PolygonC . fromList) `liftM`
        do
        numContours <-
            fromIntegral `liftM` (\ptr -> do {peekByteOff ptr 0 ::IO CInt}) cPolygon

        cHoles <- (\ptr -> do {peekByteOff ptr 4 ::IO (Ptr CInt)}) cPolygon
        holes <- peekArray numContours cHoles

        cContours <- (\ptr -> do {peekByteOff ptr 8 ::IO (CContour)}) cPolygon
        contours <- peekArray numContours cContours

        return $ zip (map toBool holes) contours

    poke cPolygon (PolygonC polygon) =
        do
        (\ptr val -> do {pokeByteOff ptr 0 (val::CInt)}) cPolygon $ fromIntegral $ size polygon

        cHoles <- newArray $ map fromBool holes
        (\ptr val -> do {pokeByteOff ptr 4 (val::(Ptr CInt))}) cPolygon cHoles

        cContours <- newArray contours
        (\ptr val -> do {pokeByteOff ptr 8 (val::(CContour))}) cPolygon cContours

        where (holes, contours) = unzip $ toList polygon

instance Area Polygon where
    area (PolygonC polygon) =
        sum $ map signal $ toList polygon
        where
        signal (False, contour) = area contour
        signal (True, contour) = negate $ area contour