{-- TerraHS - Interface between TerraLib and Haskell

(c) Sergio Costa (INPE) - Setembro, 2005

This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General
Public License 2.1 as published by the Free Software Foundation
(http://www.opensource.org/licenses/gpl-license.php)
--}

{- | A module for supporting a TePoint TerraLib class

TePoint: A class for handling 2D Points.

More information - <http://www.terralib.org>
-}
module TerraHS.TerraLib.TePoint
(
-- * The @TePoint@ type
TePoint (..),

-- * The @TePointPtr@ type
TePointPtr,

-- * The @TePointSet@ type
TePointSet (..),

-- * The @TePointSetPtr@ type
TePointSetPtr,

-- ** Operations on @TePoint@
x, y,

-- ** Operations on @TePointSet@
getListPoint,
)
where

import Foreign
import Foreign.C.String
import qualified Foreign.Ptr (Ptr)

import TerraHS.Misc.Object

import TerraHS.TerraLib.TeCoord2D

-- | The type  @TePoint@ represents 2D Points.
data TePoint = TePoint TeCoord2D deriving (Eq,Show,Ord)

-- | The type @TePointPtr@ is a pointer to @TePoint@
type TePointPtr = Foreign.Ptr.Ptr TePoint

-- | The type  @TePointSet@ represents  a sets of 2D Points.
data TePointSet = TePointSet [TePoint]

-- | The type @TePointSetPtr@ is a pointer to @TePointSet@
type TePointSetPtr = Foreign.Ptr.Ptr TePointSet

-- | Returns the X componente of the coordinate
x :: TePoint -> Double
x (TePoint coord ) = ( cx coord )

-- | Returns the Y componente of the coordinate
y :: TePoint -> Double
y (TePoint coord ) = ( cy coord )

-- | Returns a @TePoint@ list
getListPoint :: TePointSet -> [TePoint]
getListPoint (TePointSet ps) = ps

pointId :: TePointPtr -> String -> IO ()
pointId ptr str = newCString str >>= (tepoint_setobjectid ptr) >>= return

instance Pointer TePoint where

new pt = tepoint_new (x pt) (y pt) >>= return

delete ptr = (tepoint_destroy ptr)

fromPointer ptr = (tepoint_getx ptr ) >>= \x -> (tepoint_gety ptr ) >>= \y -> return (TePoint (x, y))

instance Pointer TePointSet where
new (TePointSet []) = tepointset_new
new (TePointSet xs) = do
ptr <- TerraHS.Misc.Object.new (TePointSet [])
tepointSetAdd ptr xs 0
return ptr
where
tepointSetAdd ptr [] _ = error "erro"
tepointSetAdd ptr [x] i = TerraHS.Misc.Object.new x >>= \pt -> pointId pt (show i)  >> tepointset_addtepoint ptr pt
tepointSetAdd ptr (x:xs) i = TerraHS.Misc.Object.new x >>= \pt -> pointId pt (show i)  >> tepointset_addtepoint ptr pt >> tepointSetAdd ptr xs (i+1)

delete ptr = (tepointset_destroy ptr)

instance Size TePointSet where

size ptr = (tepointset_size ptr)

instance Element TePointSet TePoint where

getElement ptr i = tepointset_gettepoint ptr i >>= fromPointer >>= return

---------------- TePoint ----------------------------------------------------
foreign import stdcall unsafe "c_tepoint_new" tepoint_new :: Double -> Double ->  Prelude.IO TePointPtr
foreign import stdcall unsafe "c_tepoint_destroy" tepoint_destroy :: TePointPtr -> Prelude.IO ()
foreign import stdcall unsafe "c_tepoint_getx" tepoint_getx :: TePointPtr -> Prelude.IO Double
foreign import stdcall unsafe "c_tepoint_gety" tepoint_gety :: TePointPtr -> Prelude.IO Double

---------------- TePointSet ----------------------------------------------------
foreign import stdcall unsafe "c_tepointset_new" tepointset_new :: Prelude.IO TePointSetPtr
foreign import stdcall unsafe "c_tepointset_destroy" tepointset_destroy :: TePointSetPtr -> Prelude.IO ()
foreign import stdcall unsafe "c_tepointset_size" tepointset_size :: TePointSetPtr -> Prelude.IO Int32
foreign import stdcall unsafe "c_tepointset_gettepoint" tepointset_gettepoint :: TePointSetPtr -> Int32 -> Prelude.IO TePointPtr
foreign import stdcall unsafe "c_tepoint_getobjectid" tepoint_getobjectid :: TePointPtr -> Prelude.IO CString
foreign import stdcall unsafe "c_tepoint_setobjectid" tepoint_setobjectid :: TePointPtr -> CString -> Prelude.IO ()
foreign import stdcall unsafe "c_tepointset_addtepoint" tepointset_addtepoint :: TePointSetPtr -> TePointPtr -> Prelude.IO ()