/*********************** UndiGraph.java ***************************************/
/** Klasse zur Implementation eines ungerichteten Graphen                     */
/*  basierend auf UndiVertex und UndiEdge                                     */
/*  Der Graph wird implementiert als HashMap <String, Vertex>, d.h. als eine  */
/*  Hashtabelle mit Keys vom Typ String und Values vom Typ Knoten             */

import java.util.*;
public class UndiGraph {

  private Map <String, UndiVertex> graph;     // Datenstruktur fuer Graph

  public UndiGraph() {                        // leerer Graph wird angelegt
    graph = new HashMap<String,UndiVertex>(); // HashMap von String, UndiVertex 
  }
 
  public boolean isEmpty(){                   // liefert true, falls Graph leer
    return graph.isEmpty();                   // mit isEmpty() von HashMap
  }
  
  public int size(){                          // liefert die Anzahl der Knoten
    return graph.size();                      // mit size() von HashMap
  }                                    
  
  public Collection <UndiVertex> vertices(){  // liefert Knoten als Collection 
    return graph.values();                    // mit values() von HashMap
  }

  public Collection <UndiEdge> edges()  {     // liefert Kanten als Collection 
    Set s = new HashSet<UndiEdge>();          // erzeuge Menge von Kanten
    for (UndiVertex v : vertices()) {         // fuer jeden Graphknoten
      for (UndiEdge e : v.edges)              // durchlaufe seine Kanten
        s.add(e);                             // (doppelte werden vermieden)
    }  
    return s;
  } 

  public UndiVertex getVertex(String s){      // liefere Knoten zu String 
    UndiVertex v = graph.get(s);              // besorge Knoten zu Knotennamen
    if (v==null) {                            // falls nicht gefunden
      v = new UndiVertex(s);                  // lege neuen Knoten an
      graph.put(s, v);                        // fuege Namen und Knoten ein
    } 
    return v;                           // liefere gefundenen oder neuen Knoten
  }

  public void addEdge(String source,    // fuege Kante ein von Knoten source
                      String dest,      // zu Knoten dest
                      double cost) {    // mit Kosten cost 
    UndiVertex v = getVertex(source);   // finde Knoten v zum Startnamen
    UndiVertex w = getVertex(dest);     // finde Knoten w zum Zielnamen
    UndiEdge e= new UndiEdge(v,w,cost); // erzeuge ungerichtete Kante
    v.edges.add(e);                     // fuege Kante (v,w,c) bei Knoten v ein 
    w.edges.add(e);                     // fuege Kante (v,w,c) bei Knoten w ein 
  }
}
