-- | Functions for interacting with a graph as an undirected graph

module Data.IntGraph.Undirected (
  Node,
  NodeSet,
  Edge,
  IntGraph,
  empty,
  addNode,
  nodes,
  removeNode,
  addEdge,
  edges,
  removeEdge,
  fromEdges)
  where

import qualified Data.IntMap as I
import qualified Data.Set    as S
import           Data.List   (delete)

import           Data.IntGraph
import qualified Data.IntGraph.Directed as D

-- | Add an edge to the graph
-- | If either nodes is not already in the graph, they are added
addEdge :: Edge -> IntGraph -> IntGraph
addEdge (u, v) graph = D.addEdge (u, v) $ D.addEdge (v, u) graph


-- | Returns a list of all edges in the graph
edges :: IntGraph -> [Edge]
edges = D.edges


-- Returns a list of all edges in the graph, without duplicate edges
-- i.e if (u,v) is an edge, only one of (u, v) or (v, u) will be in this list
edges' :: IntGraph -> [Edge]
edges' graph = filter' (edges graph)
  where
    filter' []          = []
    filter' ((u, v):xs) = (u, v) : (filter' $ delete (v, u) xs)


-- | remove an edge from the graph
removeEdge :: Edge -> IntGraph -> IntGraph
removeEdge (u, v) graph = D.removeEdge (u, v) $ D.removeEdge (v, u) graph


-- | turns a list of edges into a graph
fromEdges :: [Edge] -> IntGraph
fromEdges graph = foldr addEdge empty graph