module HGraph.Undirected.Load
       ( loadDot
       )
where

import HGraph.Undirected
import Language.Dot.Parser as D
import Language.Dot.Utils  as D
import Language.Dot.Graph  as D
import qualified Data.Map  as M
import qualified Data.Set  as S

loadDot :: t String -> String -> Either String (t String)
loadDot t String
gr String
dotStr = do
  (Bool, GraphType, Maybe Name, [Statement])
dot <- String -> Either String (Bool, GraphType, Maybe Name, [Statement])
D.parse String
dotStr
  t String -> Either String (t String)
forall (m :: * -> *) a. Monad m => a -> m a
return (t String -> Either String (t String))
-> t String -> Either String (t String)
forall a b. (a -> b) -> a -> b
$ 
    let ([GraphElement]
ns, [GraphElement]
es) = (Bool, GraphType, Maybe Name, [Statement])
-> ([GraphElement], [GraphElement])
forall a b c.
(a, b, c, [Statement]) -> ([GraphElement], [GraphElement])
D.adjacency (Bool, GraphType, Maybe Name, [Statement])
dot
        names :: [String]
names = (Set String -> [String]
forall a. Set a -> [a]
S.toList (Set String -> [String]) -> Set String -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> Set String
forall a. Ord a => [a] -> Set a
S.fromList ([String] -> Set String) -> [String] -> Set String
forall a b. (a -> b) -> a -> b
$ (GraphElement -> String) -> [GraphElement] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map GraphElement -> String
getNodeName [GraphElement]
ns)
        addE :: GraphElement -> t String -> t String
addE (D.Edge String
v String
u [(Name, Name)]
_) t String
d = t String -> (String, String) -> t String
forall (t :: * -> *) a. Mutable t => t a -> (a, a) -> t a
addEdge t String
d (String
v, String
u)
        getNodeName :: GraphElement -> String
getNodeName (D.Node String
name [(Name, Name)]
_) = String
name
    in (GraphElement -> t String -> t String)
-> t String -> [GraphElement] -> t String
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr GraphElement -> t String -> t String
forall (t :: * -> *).
Mutable t =>
GraphElement -> t String -> t String
addE ((String -> t String -> t String)
-> t String -> [String] -> t String
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((t String -> String -> t String) -> String -> t String -> t String
forall a b c. (a -> b -> c) -> b -> a -> c
flip t String -> String -> t String
forall (t :: * -> *) a. Mutable t => t a -> a -> t a
addVertex) t String
gr [String]
names) [GraphElement]
es