{-|
Module      : H3.DirectedEdges

Directed edges allow encoding the directed edge from one cell to a neighboring cell.
-}
module H3.DirectedEdges
  ( isValidDirectedEdge 
  , directedEdgeToCells
  , originToDirectedEdges
  , areNeighborCells
  , cellsToDirectedEdge
  , getDirectedEdgeOrigin
  , getDirectedEdgeDestination
  , directedEdgeToBoundary
  ) where

import H3.Internal.H3Api 
  ( LatLng
  , H3ErrorCodes
  , H3Index
  , c2hs_areNeighborCells
  , c2hs_cellsToDirectedEdge
  , c2hs_getDirectedEdgeOrigin
  , c2hs_getDirectedEdgeDestination
  , c2hs_directedEdgeToBoundary
  )
import H3.Internal.FFI 
  ( isValidDirectedEdge
  , hsDirectedEdgeToCells
  , hsOriginToDirectedEdges
  )
import H3.Internal.Utils (toEither)


-- | Returns a list of length 2 consisting of the origin and the destination hexagon IDs for the given edge ID.
directedEdgeToCells :: H3Index -> Either H3ErrorCodes [H3Index]
directedEdgeToCells :: H3Index -> Either H3ErrorCodes [H3Index]
directedEdgeToCells = (H3Error, [H3Index]) -> Either H3ErrorCodes [H3Index]
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, [H3Index]) -> Either H3ErrorCodes [H3Index])
-> (H3Index -> (H3Error, [H3Index]))
-> H3Index
-> Either H3ErrorCodes [H3Index]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> (H3Error, [H3Index])
hsDirectedEdgeToCells

-- | Provides all of the directed edges from the current 'H3Index'. 
--   The return will be of length 6, but the number of directed edges placed in the array may be less than 6. 
--   If this is the case, one of the members of the array will be 0.
originToDirectedEdges :: H3Index -> Either H3ErrorCodes [H3Index]
originToDirectedEdges :: H3Index -> Either H3ErrorCodes [H3Index]
originToDirectedEdges = (H3Error, [H3Index]) -> Either H3ErrorCodes [H3Index]
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, [H3Index]) -> Either H3ErrorCodes [H3Index])
-> (H3Index -> (H3Error, [H3Index]))
-> H3Index
-> Either H3ErrorCodes [H3Index]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> (H3Error, [H3Index])
hsOriginToDirectedEdges

-- | Returns whether or not the provided H3 cell indexes are neighbors.
areNeighborCells :: H3Index -> H3Index -> Either H3ErrorCodes Bool
areNeighborCells :: H3Index -> H3Index -> Either H3ErrorCodes Bool
areNeighborCells H3Index
origin = (H3Error, Bool) -> Either H3ErrorCodes Bool
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, Bool) -> Either H3ErrorCodes Bool)
-> (H3Index -> (H3Error, Bool))
-> H3Index
-> Either H3ErrorCodes Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> H3Index -> (H3Error, Bool)
c2hs_areNeighborCells H3Index
origin

-- | Returns a unidirectional edge H3 index based on the provided @origin@ and @destination@.
cellsToDirectedEdge :: H3Index -- ^ origin
                    -> H3Index -- ^ destination
                    -> Either H3ErrorCodes H3Index
cellsToDirectedEdge :: H3Index -> H3Index -> Either H3ErrorCodes H3Index
cellsToDirectedEdge H3Index
origin = (H3Error, H3Index) -> Either H3ErrorCodes H3Index
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, H3Index) -> Either H3ErrorCodes H3Index)
-> (H3Index -> (H3Error, H3Index))
-> H3Index
-> Either H3ErrorCodes H3Index
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> H3Index -> (H3Error, H3Index)
c2hs_cellsToDirectedEdge H3Index
origin 

-- | Returns the origin hexagon from the unidirectional edge 'H3Index'.
getDirectedEdgeOrigin :: H3Index -> Either H3ErrorCodes H3Index
getDirectedEdgeOrigin :: H3Index -> Either H3ErrorCodes H3Index
getDirectedEdgeOrigin = (H3Error, H3Index) -> Either H3ErrorCodes H3Index
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, H3Index) -> Either H3ErrorCodes H3Index)
-> (H3Index -> (H3Error, H3Index))
-> H3Index
-> Either H3ErrorCodes H3Index
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> (H3Error, H3Index)
c2hs_getDirectedEdgeOrigin 

-- | Returns the destination hexagon from the unidirectional edge 'H3Index'.
getDirectedEdgeDestination :: H3Index -> Either H3ErrorCodes H3Index
getDirectedEdgeDestination :: H3Index -> Either H3ErrorCodes H3Index
getDirectedEdgeDestination = (H3Error, H3Index) -> Either H3ErrorCodes H3Index
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, H3Index) -> Either H3ErrorCodes H3Index)
-> (H3Index -> (H3Error, H3Index))
-> H3Index
-> Either H3ErrorCodes H3Index
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> (H3Error, H3Index)
c2hs_getDirectedEdgeDestination

-- | Provides the coordinates defining the unidirectional edge.
directedEdgeToBoundary :: H3Index -> Either H3ErrorCodes [LatLng]
directedEdgeToBoundary :: H3Index -> Either H3ErrorCodes [LatLng]
directedEdgeToBoundary = (H3Error, [LatLng]) -> Either H3ErrorCodes [LatLng]
forall a. (H3Error, a) -> Either H3ErrorCodes a
toEither ((H3Error, [LatLng]) -> Either H3ErrorCodes [LatLng])
-> (H3Index -> (H3Error, [LatLng]))
-> H3Index
-> Either H3ErrorCodes [LatLng]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. H3Index -> (H3Error, [LatLng])
c2hs_directedEdgeToBoundary