{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module H3.Internal.FFI
  ( degsToRads
  , radsToDegs
  , getResolution
  , getBaseCellNumber
  , isValidCell
  , isResClassIII
  , isPentagon
  , hsGetIcosahedronFaces
  , hsPolygonToCells 
  , hsGetRes0Cells
  , hsGetPentagons
  , hsGridDisk
  , hsGridDiskUnsafe
  , hsGridDiskDistances 
  , hsGridDiskDistancesSafe 
  , hsGridDiskDistancesUnsafe
  , hsGridRingUnsafe
  , hsGridPathCells
  , hsCellToChildren
  , hsCompactCells 
  , hsUncompactCells 
  , isValidDirectedEdge
  , hsDirectedEdgeToCells
  , hsOriginToDirectedEdges
  , hsCellToVertexes 
  , isValidVertex
  ) where

import Data.Int (Int64)
import Data.Word (Word32)
import System.IO.Unsafe (unsafePerformIO)
import Foreign.C.Types (CInt, CLong)
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable(peek))
import Foreign.Marshal.Alloc (alloca, free)
import Foreign.Marshal.Array (allocaArray, withArray, peekArray, callocArray, withArray, withArrayLen)
import H3.Internal.H3Api 
  ( H3Index
  , H3Error
  , CGeoPolygon
  , newCGeoPolygonPtr 
  , destroyCGeoPolygonPtr 
  , GeoPolygon
  )


-- |degsToRads converts from degrees to radians.
foreign import capi "h3/h3api.h degsToRads" degsToRads :: Double -> Double

-- |radsToDegs converts from radians to degrees
foreign import capi "h3/h3api.h radsToDegs" radsToDegs :: Double -> Double

-- Inspection

-- | Returns the resolution of the index.
foreign import capi "h3/h3api.h getResolution" getResolution :: H3Index -> Int

-- | Returns the base cell number of the index.
foreign import capi "h3/h3api.h getBaseCellNumber" getBaseCellNumber :: H3Index -> Int

-- | isValidCell returns non-zero if this is a valid H3 cell index
foreign import capi "h3/h3api.h isValidCell" isValidCell :: H3Index -> Int

-- | Returns non-zero if this index has a resolution with Class III orientation.
foreign import capi "h3/h3api.h isResClassIII" isResClassIII :: H3Index -> Int

-- | Returns non-zero if this index represents a pentagonal cell.
foreign import capi "h3/h3api.h isPentagon" isPentagon :: H3Index -> Int

foreign import capi "h3/h3api.h maxFaceCount" c_maxFaceCount :: H3Index -> Ptr CInt -> IO H3Error

foreign import capi "h3/h3api.h getIcosahedronFaces" c_getIcosahedronFaces :: H3Index -> Ptr CInt -> IO H3Error

hsGetIcosahedronFaces :: H3Index -> (H3Error, [Int])
hsGetIcosahedronFaces :: H3Index -> (H3Error, [Int])
hsGetIcosahedronFaces H3Index
h3index = 
  IO (H3Error, [Int]) -> (H3Error, [Int])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [Int]) -> (H3Error, [Int]))
-> IO (H3Error, [Int]) -> (H3Error, [Int])
forall a b. (a -> b) -> a -> b
$ (Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int]))
-> (Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int])
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
countptr -> do
    H3Error
h3error <- H3Index -> Ptr CInt -> IO H3Error
c_maxFaceCount H3Index
h3index Ptr CInt
countptr
    if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      Int
count <- CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
countptr
      Int -> (Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
count ((Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int]))
-> (Ptr CInt -> IO (H3Error, [Int])) -> IO (H3Error, [Int])
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
facesptr -> do
        H3Error
out3error <- H3Index -> Ptr CInt -> IO H3Error
c_getIcosahedronFaces H3Index
h3index Ptr CInt
facesptr
        if H3Error
out3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
        then do
          [Int]
faces <- (CInt -> Int) -> [CInt] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([CInt] -> [Int]) -> IO [CInt] -> IO [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Ptr CInt -> IO [CInt]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
count Ptr CInt
facesptr
          (H3Error, [Int]) -> IO (H3Error, [Int])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
out3error, [Int]
faces)
        else (H3Error, [Int]) -> IO (H3Error, [Int])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
out3error, [])
    else (H3Error, [Int]) -> IO (H3Error, [Int])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])


-- Regions


foreign import capi "h3/h3api.h maxPolygonToCellsSize" cMaxPolygonToCellsSize :: Ptr CGeoPolygon -> Int -> Word32 -> Ptr CLong -> IO H3Error

foreign import capi "h3/h3api.h polygonToCells" cPolygonToCells :: Ptr CGeoPolygon -> Int -> Word32 -> Ptr H3Index -> IO H3Error

hsPolygonToCellsIO :: GeoPolygon -> Int -> Word32 -> IO (H3Error, [H3Index])
hsPolygonToCellsIO :: GeoPolygon -> Int -> H3Error -> IO (H3Error, [H3Index])
hsPolygonToCellsIO GeoPolygon
poly Int
res H3Error
flags = do
  Ptr CGeoPolygon
cpolyPtr <- GeoPolygon -> IO (Ptr CGeoPolygon)
newCGeoPolygonPtr GeoPolygon
poly
  (H3Error
h3error, CLong
size) <- (Ptr CLong -> IO (H3Error, CLong)) -> IO (H3Error, CLong)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CLong -> IO (H3Error, CLong)) -> IO (H3Error, CLong))
-> (Ptr CLong -> IO (H3Error, CLong)) -> IO (H3Error, CLong)
forall a b. (a -> b) -> a -> b
$ \Ptr CLong
resultPtr -> do
    H3Error
h3error <- Ptr CGeoPolygon -> Int -> H3Error -> Ptr CLong -> IO H3Error
cMaxPolygonToCellsSize Ptr CGeoPolygon
cpolyPtr Int
res H3Error
flags Ptr CLong
resultPtr
    CLong
result <- Ptr CLong -> IO CLong
forall a. Storable a => Ptr a -> IO a
peek Ptr CLong
resultPtr
    (H3Error, CLong) -> IO (H3Error, CLong)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, CLong
result)
  (H3Error, [H3Index])
out <- if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
         then do let sizei :: Int
sizei = CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
size
                 Ptr H3Index
resultPtr <- Int -> IO (Ptr H3Index)
forall a. Storable a => Int -> IO (Ptr a)
callocArray Int
sizei
                 H3Error
h3error2 <- Ptr CGeoPolygon -> Int -> H3Error -> Ptr H3Index -> IO H3Error
cPolygonToCells Ptr CGeoPolygon
cpolyPtr Int
res H3Error
flags Ptr H3Index
resultPtr
                 [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
sizei Ptr H3Index
resultPtr
                 Ptr H3Index -> IO ()
forall a. Ptr a -> IO ()
free Ptr H3Index
resultPtr
                 (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error2, [H3Index]
result)
         else 
           (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])
  Ptr CGeoPolygon -> IO ()
destroyCGeoPolygonPtr Ptr CGeoPolygon
cpolyPtr 
  (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error, [H3Index])
out

hsPolygonToCells :: GeoPolygon -> Int -> Word32 -> (H3Error, [H3Index])
hsPolygonToCells :: GeoPolygon -> Int -> H3Error -> (H3Error, [H3Index])
hsPolygonToCells GeoPolygon
poly Int
res H3Error
flags = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ GeoPolygon -> Int -> H3Error -> IO (H3Error, [H3Index])
hsPolygonToCellsIO GeoPolygon
poly Int
res H3Error
flags


-- Miscellaneous


foreign import capi "h3/h3api.h res0CellCount" cRes0CellCount :: IO Int

foreign import capi "h3/h3api.h getRes0Cells" cGetRes0Cells :: Ptr H3Index -> IO H3Error

hsGetRes0Cells :: (H3Error, [H3Index])
hsGetRes0Cells :: (H3Error, [H3Index])
hsGetRes0Cells = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  Int
cellCount <- IO Int
cRes0CellCount
  Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
cellCount ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
resultPtr -> do
    H3Error
h3error <- Ptr H3Index -> IO H3Error
cGetRes0Cells Ptr H3Index
resultPtr
    [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
cellCount Ptr H3Index
resultPtr
    (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)

foreign import capi "h3/h3api.h pentagonCount" cPentagonCount :: IO Int

foreign import capi "h3/h3api.h getPentagons" cGetPentagons :: Int -> Ptr H3Index -> IO H3Error

hsGetPentagons :: Int -> (H3Error, [H3Index])
hsGetPentagons :: Int -> (H3Error, [H3Index])
hsGetPentagons Int
res = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  Int
cellCount <- IO Int
cPentagonCount
  Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
cellCount ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
resultPtr -> do
    H3Error
h3error <- Int -> Ptr H3Index -> IO H3Error
cGetPentagons Int
res Ptr H3Index
resultPtr
    [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
cellCount Ptr H3Index
resultPtr
    (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)


-- Traversals

foreign import capi "h3/h3api.h maxGridDiskSize" cMaxGridDiskSize :: Int -> Ptr Int64 -> IO H3Error

hsMaxGridDiskSize :: Int -> IO (H3Error, Int64)
hsMaxGridDiskSize :: Int -> IO (H3Error, Int64)
hsMaxGridDiskSize Int
k = do
  (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64))
-> (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxSizePtr -> do
    H3Error
h3error <- Int -> Ptr Int64 -> IO H3Error
cMaxGridDiskSize Int
k Ptr Int64
maxSizePtr
    if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      Int64
maxSize <- Int64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int64) -> IO Int64 -> IO Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
maxSizePtr
      (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, Int64
maxSize)
    else do
      (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, Int64
0)

hsGridRingUnsafeSize :: Int -> IO (H3Error, Int64)
hsGridRingUnsafeSize :: Int -> IO (H3Error, Int64)
hsGridRingUnsafeSize Int
k | Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0     = Int -> IO (H3Error, Int64)
localGridRingUnsafeSize Int
k
                       | Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0    = (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
0, Int64
1)
                       | Bool
otherwise = (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
2, Int64
0) -- domain error
  where localGridRingUnsafeSize :: Int -> IO (H3Error, Int64)
localGridRingUnsafeSize Int
k0 = do
          (H3Error
h3error0, Int64
size0) <- Int -> IO (H3Error, Int64)
hsMaxGridDiskSize Int
k0
          (H3Error
h3error1, Int64
size1) <- Int -> IO (H3Error, Int64)
hsMaxGridDiskSize (Int
k0Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
          if (H3Error
h3error0 H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0) Bool -> Bool -> Bool
&& (H3Error
h3error1 H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0)
            then (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error0, Int64
size0 Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
- Int64
size1)
          else if H3Error
h3error0 H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
/= H3Error
0
            then (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error0, Int64
0)
          else (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error1, Int64
0)
 
hsGridDiskUsingMethod :: (H3Index -> Int -> Ptr H3Index -> IO H3Error) -> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod :: (H3Index -> Int -> Ptr H3Index -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod H3Index -> Int -> Ptr H3Index -> IO H3Error
diskMethod H3Index
h3index Int
k = do
  (Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index]))
-> (Ptr Int64 -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxSizePtr -> do
    H3Error
sizeh3error <- Int -> Ptr Int64 -> IO H3Error
cMaxGridDiskSize Int
k Ptr Int64
maxSizePtr
    if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      Int
maxSize <- Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int) -> IO Int64 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
maxSizePtr
      Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
maxSize ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
resultPtr -> do
        H3Error
h3error <- H3Index -> Int -> Ptr H3Index -> IO H3Error
diskMethod H3Index
h3index Int
k Ptr H3Index
resultPtr
        [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
maxSize Ptr H3Index
resultPtr
        (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)
    else do
      (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, [])
 
foreign import capi "h3/h3api.h gridDisk" cGridDisk :: H3Index -> Int -> Ptr H3Index -> IO H3Error

hsGridDisk :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDisk :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDisk H3Index
origin = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> (Int -> IO (H3Error, [H3Index])) -> Int -> (H3Error, [H3Index])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod H3Index -> Int -> Ptr H3Index -> IO H3Error
cGridDisk H3Index
origin

foreign import capi "h3/h3api.h gridDiskUnsafe" cGridDiskUnsafe :: H3Index -> Int -> Ptr H3Index -> IO H3Error

hsGridDiskUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDiskUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridDiskUnsafe H3Index
origin = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> (Int -> IO (H3Error, [H3Index])) -> Int -> (H3Error, [H3Index])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, [H3Index])
hsGridDiskUsingMethod H3Index -> Int -> Ptr H3Index -> IO H3Error
cGridDiskUnsafe H3Index
origin

hsGridDiskDistancesUsingMethod :: (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error) -> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod :: (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
diskDistanceMethod H3Index
h3index Int
k = do
  (Ptr Int64 -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, ([H3Index], [Int])))
 -> IO (H3Error, ([H3Index], [Int])))
-> (Ptr Int64 -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxSizePtr -> do
    H3Error
sizeh3error <- Int -> Ptr Int64 -> IO H3Error
cMaxGridDiskSize Int
k Ptr Int64
maxSizePtr
    if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      Int
maxSize <- Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int) -> IO Int64 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
maxSizePtr
      Int
-> (Ptr H3Index -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
maxSize ((Ptr H3Index -> IO (H3Error, ([H3Index], [Int])))
 -> IO (H3Error, ([H3Index], [Int])))
-> (Ptr H3Index -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
indexResultPtr -> do
        Int
-> (Ptr CInt -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
maxSize ((Ptr CInt -> IO (H3Error, ([H3Index], [Int])))
 -> IO (H3Error, ([H3Index], [Int])))
-> (Ptr CInt -> IO (H3Error, ([H3Index], [Int])))
-> IO (H3Error, ([H3Index], [Int]))
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
distanceResultPtr -> do
          H3Error
h3error <- H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
diskDistanceMethod H3Index
h3index Int
k Ptr H3Index
indexResultPtr Ptr CInt
distanceResultPtr
          [H3Index]
indexResult <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
maxSize Ptr H3Index
indexResultPtr
          [Int]
distanceResult <- (CInt -> Int) -> [CInt] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([CInt] -> [Int]) -> IO [CInt] -> IO [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Ptr CInt -> IO [CInt]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
maxSize Ptr CInt
distanceResultPtr
          (H3Error, ([H3Index], [Int])) -> IO (H3Error, ([H3Index], [Int]))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, ([H3Index]
indexResult, [Int]
distanceResult))
    else do
      (H3Error, ([H3Index], [Int])) -> IO (H3Error, ([H3Index], [Int]))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, ([], []))

foreign import capi "h3/h3api.h gridDiskDistances" cGridDiskDistances :: H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error

hsGridDiskDistances :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistances :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistances H3Index
origin = IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int]))
forall a. IO a -> a
unsafePerformIO (IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int])))
-> (Int -> IO (H3Error, ([H3Index], [Int])))
-> Int
-> (H3Error, ([H3Index], [Int]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
cGridDiskDistances H3Index
origin

foreign import capi "h3/h3api.h gridDiskDistancesSafe" cGridDiskDistancesSafe :: H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error

hsGridDiskDistancesSafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesSafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesSafe H3Index
origin = IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int]))
forall a. IO a -> a
unsafePerformIO (IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int])))
-> (Int -> IO (H3Error, ([H3Index], [Int])))
-> Int
-> (H3Error, ([H3Index], [Int]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
cGridDiskDistancesSafe H3Index
origin

foreign import capi "h3/h3api.h gridDiskDistancesUnsafe" cGridDiskDistancesUnsafe :: H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error

hsGridDiskDistancesUnsafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUnsafe :: H3Index -> Int -> (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUnsafe H3Index
origin = IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int]))
forall a. IO a -> a
unsafePerformIO (IO (H3Error, ([H3Index], [Int])) -> (H3Error, ([H3Index], [Int])))
-> (Int -> IO (H3Error, ([H3Index], [Int])))
-> Int
-> (H3Error, ([H3Index], [Int]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error)
-> H3Index -> Int -> IO (H3Error, ([H3Index], [Int]))
hsGridDiskDistancesUsingMethod H3Index -> Int -> Ptr H3Index -> Ptr CInt -> IO H3Error
cGridDiskDistancesUnsafe H3Index
origin

foreign import capi "h3/h3api.h gridRingUnsafe" cGridRingUnsafe :: H3Index -> Int -> Ptr H3Index -> IO H3Error

hsGridRingUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridRingUnsafe :: H3Index -> Int -> (H3Error, [H3Index])
hsGridRingUnsafe H3Index
origin Int
k = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  (H3Error
sizeh3error, Int64
maxSize64) <- Int -> IO (H3Error, Int64)
hsGridRingUnsafeSize Int
k
  let maxSize :: Int
maxSize = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
maxSize64
  if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
  then do
    [H3Index]
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> H3Index -> [H3Index]
forall a. Int -> a -> [a]
replicate Int
maxSize H3Index
0) ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
resultPtr -> do
      H3Error
h3error <- H3Index -> Int -> Ptr H3Index -> IO H3Error
cGridRingUnsafe H3Index
origin Int
k Ptr H3Index
resultPtr
      if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
      then do
        [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
maxSize Ptr H3Index
resultPtr
        (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)
      else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])
  else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, [])

foreign import capi "h3/h3api.h gridPathCellsSize" cGridPathCellsSize :: H3Index -> H3Index -> Ptr Int64 -> IO H3Error

foreign import capi "h3/h3api.h gridPathCells" cGridPathCells :: H3Index -> H3Index -> Ptr H3Index -> IO H3Error

hsGridPathCells :: H3Index -> H3Index -> (H3Error, [H3Index])
hsGridPathCells :: H3Index -> H3Index -> (H3Error, [H3Index])
hsGridPathCells H3Index
origin H3Index
h3 = 
  IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ (Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index]))
-> (Ptr Int64 -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
sizePtr -> do
    H3Error
sizeh3error <- H3Index -> H3Index -> Ptr Int64 -> IO H3Error
cGridPathCellsSize H3Index
origin H3Index
h3 Ptr Int64
sizePtr
    if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      Int
size <- Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int) -> IO Int64 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
sizePtr
      Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
size ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
resultPtr -> do
        H3Error
h3error <- H3Index -> H3Index -> Ptr H3Index -> IO H3Error
cGridPathCells H3Index
origin H3Index
h3 Ptr H3Index
resultPtr
        [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
size Ptr H3Index
resultPtr
        (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)
    else do
      (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, [])

-- Note: We are skipping the binding of gridDisksUnsafe at this time, 
--       as we are not certain about the sizing of the output array of H3Index values 
--       at this time.


-- Hierarchy


foreign import capi "h3/h3api.h cellToChildrenSize" cCellToChildrenSize :: H3Index -> Int -> Ptr Int64 -> IO H3Error

foreign import capi "h3/h3api.h cellToChildren" cCellToChildren :: H3Index -> Int -> Ptr H3Index -> IO H3Error

hsCellToChildren :: H3Index -> Int -> (H3Error, [H3Index])
hsCellToChildren :: H3Index -> Int -> (H3Error, [H3Index])
hsCellToChildren H3Index
cell Int
childRes = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  (Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index])
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, [H3Index])) -> IO (H3Error, [H3Index]))
-> (Ptr Int64 -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
sizePtr -> do
    H3Error
sizeh3error <- H3Index -> Int -> Ptr Int64 -> IO H3Error
cCellToChildrenSize H3Index
cell Int
childRes Ptr Int64
sizePtr
    if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      Int
size <- Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int) -> IO Int64 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
sizePtr
      Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
size ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
resultPtr -> do
        H3Error
h3error <- H3Index -> Int -> Ptr H3Index -> IO H3Error
cCellToChildren H3Index
cell Int
childRes Ptr H3Index
resultPtr
        if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
        then do
          [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
size Ptr H3Index
resultPtr
          (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)
        else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])
    else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, [])

-- Normally a method like compactCells would be in H3Api.chs, but the order of the arguments 
-- reduces the benefit of c2hs fun hooks
foreign import capi "h3/h3api.h compactCells" cCompactCells :: Ptr H3Index -> Ptr H3Index -> Int64 -> IO H3Error

hsCompactCells :: [H3Index] -> (H3Error, [H3Index])
hsCompactCells :: [H3Index] -> (H3Error, [H3Index])
hsCompactCells [H3Index]
cellSet = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  [H3Index]
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray [H3Index]
cellSet ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
cellSetPtr -> do
    let size :: Int
size = [H3Index] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [H3Index]
cellSet
    Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
size ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
compactedSetPtr -> do
      H3Error
h3error <- Ptr H3Index -> Ptr H3Index -> Int64 -> IO H3Error
cCompactCells Ptr H3Index
cellSetPtr Ptr H3Index
compactedSetPtr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)
      if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
      then do
        [H3Index]
result <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
size Ptr H3Index
compactedSetPtr
        (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
result)
      else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])

foreign import capi "h3/h3api.h uncompactCellsSize" cUncompactCellsSize :: Ptr H3Index -> Int64 -> Int -> Ptr Int64 -> IO H3Error

foreign import capi "h3/h3api.h uncompactCells" cUncompactCells :: Ptr H3Index -> Int64 -> Ptr H3Index -> Int64 -> Int -> IO H3Error

hsUncompactCells :: [H3Index] -> Int -> (H3Error, [H3Index])
hsUncompactCells :: [H3Index] -> Int -> (H3Error, [H3Index])
hsUncompactCells [H3Index]
compactedSet Int
res = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  [H3Index]
-> (Int -> Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
withArrayLen [H3Index]
compactedSet ((Int -> Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Int -> Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Int
numCells Ptr H3Index
compactedSetPtr -> do
    (H3Error
sizeh3error, Int64
maxCells) <- (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64))
-> (Ptr Int64 -> IO (H3Error, Int64)) -> IO (H3Error, Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
maxCellsPtr -> do
      H3Error
sizeh3error <- Ptr H3Index -> Int64 -> Int -> Ptr Int64 -> IO H3Error
cUncompactCellsSize Ptr H3Index
compactedSetPtr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
numCells) Int
res Ptr Int64
maxCellsPtr
      if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
      then do
        Int64
size <- Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
maxCellsPtr
        (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, Int64
size)
      else (H3Error, Int64) -> IO (H3Error, Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, Int64
0)
    if H3Error
sizeh3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      let maxCellsInt :: Int
maxCellsInt = Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
maxCells
      Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
maxCellsInt ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
cellSetPtr -> do
        H3Error
h3error <- Ptr H3Index -> Int64 -> Ptr H3Index -> Int64 -> Int -> IO H3Error
cUncompactCells Ptr H3Index
compactedSetPtr (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
numCells) Ptr H3Index
cellSetPtr Int64
maxCells Int
res
        if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
        then do
          [H3Index]
cellSet <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
maxCellsInt Ptr H3Index
cellSetPtr
          (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
cellSet)
        else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])
    else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
sizeh3error, [])

-- Directed edges


foreign import capi "h3/h3api.h isValidDirectedEdge" cIsValidDirectedEdge :: H3Index -> Int

-- |Determines if the provided 'H3Index' is a valid unidirectional edge index.
isValidDirectedEdge :: H3Index -> Bool
isValidDirectedEdge :: H3Index -> Bool
isValidDirectedEdge = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
0) (Int -> Bool) -> (H3Index -> Int) -> H3Index -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> Int
cIsValidDirectedEdge

foreign import capi "h3/h3api.h directedEdgeToCells" cDirectedEdgeToCells :: H3Index -> Ptr H3Index -> IO H3Error

hsDirectedEdgeToCells :: H3Index -> (H3Error, [H3Index])
hsDirectedEdgeToCells :: H3Index -> (H3Error, [H3Index])
hsDirectedEdgeToCells H3Index
h3index = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
2 ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
originDestinationPtr -> do
    H3Error
h3error <- H3Index -> Ptr H3Index -> IO H3Error
cDirectedEdgeToCells H3Index
h3index Ptr H3Index
originDestinationPtr 
    if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      [H3Index]
originDestination <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
2 Ptr H3Index
originDestinationPtr
      (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
originDestination)
    else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])

foreign import capi "h3/h3api.h originToDirectedEdges" cOriginToDirectedEdges :: H3Index -> Ptr H3Index -> IO H3Error

hsOriginToDirectedEdges :: H3Index -> (H3Error, [H3Index])
hsOriginToDirectedEdges :: H3Index -> (H3Error, [H3Index])
hsOriginToDirectedEdges H3Index
h3index = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
edgeCount ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
edgesPtr -> do
    H3Error
h3error <- H3Index -> Ptr H3Index -> IO H3Error
cOriginToDirectedEdges H3Index
h3index Ptr H3Index
edgesPtr
    if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      [H3Index]
edges <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
edgeCount Ptr H3Index
edgesPtr
      (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
edges)
    else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])
  where edgeCount :: Int
edgeCount = Int
6


-- Vertexes 


foreign import capi "h3/h3api.h cellToVertexes" cCellToVertexes :: H3Index -> Ptr H3Index -> IO H3Error

hsCellToVertexes :: H3Index -> (H3Error, [H3Index])
hsCellToVertexes :: H3Index -> (H3Error, [H3Index])
hsCellToVertexes H3Index
origin = IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a. IO a -> a
unsafePerformIO (IO (H3Error, [H3Index]) -> (H3Error, [H3Index]))
-> IO (H3Error, [H3Index]) -> (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ do
  Int
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
vertexCount ((Ptr H3Index -> IO (H3Error, [H3Index]))
 -> IO (H3Error, [H3Index]))
-> (Ptr H3Index -> IO (H3Error, [H3Index]))
-> IO (H3Error, [H3Index])
forall a b. (a -> b) -> a -> b
$ \Ptr H3Index
outPtr -> do
    H3Error
h3error <- H3Index -> Ptr H3Index -> IO H3Error
cCellToVertexes H3Index
origin Ptr H3Index
outPtr
    if H3Error
h3error H3Error -> H3Error -> Bool
forall a. Eq a => a -> a -> Bool
== H3Error
0
    then do
      [H3Index]
out <- Int -> Ptr H3Index -> IO [H3Index]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
vertexCount Ptr H3Index
outPtr
      (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [H3Index]
out)
    else (H3Error, [H3Index]) -> IO (H3Error, [H3Index])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (H3Error
h3error, [])
  where vertexCount :: Int
vertexCount = Int
6

foreign import capi "h3/h3api.h isValidVertex" cIsValidVertex :: H3Index -> Int

-- | Returns True if the given index represents a valid H3 vertex.
isValidVertex :: H3Index -> Bool
isValidVertex :: H3Index -> Bool
isValidVertex = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/=Int
0) (Int -> Bool) -> (H3Index -> Int) -> H3Index -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> Int
cIsValidVertex