module Geometry.HCDT.Utils
  ( borderEdges,
    partitionEdges
  )
where
    
import           Geometry.HCDT.Types 
import           Data.Sequence as DS     (Seq, fromList, (><), filter, drop) 
import           Data.Maybe              (isNothing, fromJust)
import           Data.Foldable           (find)
import           Data.Foldable.WithIndex (ifind)

triangleEdges :: Triangle -> Seq Edge
triangleEdges :: Triangle -> Seq Edge
triangleEdges (Triangle Int
i Int
j Int
k) = forall a. [a] -> Seq a
fromList [Int -> Int -> Edge
Edge Int
i Int
j, Int -> Int -> Edge
Edge Int
j Int
k, Int -> Int -> Edge
Edge Int
i Int
k]

-- isUnique :: Eq a => Seq a -> a -> Bool
-- isUnique xs x = length (DS.filter (== x) xs) == 1

allEdges :: Triangulation -> Seq Edge
allEdges :: Triangulation -> Seq Edge
allEdges Triangulation
triangulation = 
  let triplets :: [Seq Edge]
triplets = forall a b. (a -> b) -> [a] -> [b]
map Triangle -> Seq Edge
triangleEdges (Triangulation -> [Triangle]
_triangles Triangulation
triangulation) in
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 forall a. Seq a -> Seq a -> Seq a
(><) [Seq Edge]
triplets

-- borderEdges :: Triangulation -> Seq Edge
-- borderEdges triangulation = DS.filter (isUnique edges) edges
--   where
--     edges = allEdges triangulation

isUnique :: Eq a => Seq a -> a -> Bool
isUnique :: forall a. Eq a => Seq a -> a -> Bool
isUnique Seq a
xs a
x = forall a. Maybe a -> Bool
isNothing Maybe a
y 
  where
    (Int
i, a
_) = forall a. HasCallStack => Maybe a -> a
fromJust forall a b. (a -> b) -> a -> b
$ forall i (f :: * -> *) a.
FoldableWithIndex i f =>
(i -> a -> Bool) -> f a -> Maybe (i, a)
ifind (\Int
_ a
x' -> a
x' forall a. Eq a => a -> a -> Bool
== a
x) Seq a
xs
    y :: Maybe a
y = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (forall a. Eq a => a -> a -> Bool
== a
x) (forall a. Int -> Seq a -> Seq a
DS.drop Int
i Seq a
xs)

-- | Exterior edges of a Delaunay triangulation.
borderEdges :: Triangulation -> Seq Edge
borderEdges :: Triangulation -> Seq Edge
borderEdges Triangulation
triangulation = forall a. (a -> Bool) -> Seq a -> Seq a
DS.filter (forall a. Eq a => Seq a -> a -> Bool
isUnique Seq Edge
edges) Seq Edge
edges
  where
    edges :: Seq Edge
edges = Triangulation -> Seq Edge
allEdges Triangulation
triangulation

-- | Exterior and interior edges of a Delaunay triangulation.
partitionEdges :: Triangulation -> (Seq Edge, Seq Edge)
partitionEdges :: Triangulation -> (Seq Edge, Seq Edge)
partitionEdges Triangulation
triangulation = (Seq Edge
exEdges, Seq Edge
inEdges)
  where
    edges :: Seq Edge
edges = Triangulation -> Seq Edge
allEdges Triangulation
triangulation
    exEdges :: Seq Edge
exEdges = forall a. (a -> Bool) -> Seq a -> Seq a
DS.filter (forall a. Eq a => Seq a -> a -> Bool
isUnique Seq Edge
edges) Seq Edge
edges
    inEdges :: Seq Edge
inEdges = forall a. (a -> Bool) -> Seq a -> Seq a
DS.filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => Seq a -> a -> Bool
isUnique Seq Edge
edges) Seq Edge
edges