/** Returns number of nodes in the graph, expects a line: # Nodes: nodecount Edges: edgecount */
  @Override
  public int nodes(String filename) {
    String sep1 = Config.get("SNAP_SEPARATOR_1");

    SNAPFileReader fr = new SNAPFileReader(filename);

    String line = fr.readLine();
    while (!line.contains("Nodes:")) {
      line = fr.readLine();
    }

    String[] sl = line.split(sep1);
    return Integer.parseInt(sl[1]);
  }
  /*
   * (non-Javadoc)
   *
   * @see gtna.io.graphReader.GraphReader#read(java.lang.String)
   */
  @Override
  public Graph read(String filename) {
    String sep1 = Config.get("SNAP_SEPARATOR_1");
    String ffd = Config.get("FILESYSTEM_FOLDER_DELIMITER");
    SNAPFileReader fr = new SNAPFileReader(filename);
    try {
      String line = null;
      String name = filename.substring(filename.lastIndexOf(ffd) + 1);

      Graph graph = new Graph(name);

      Map<Integer, Integer> idMapping = new HashMap<Integer, Integer>();
      int nodecounter = 0;

      LinkedList<String> edges = new LinkedList<String>();

      graphtype type = null;

      line = fr.readLine();
      type = (line.contains("Directed graph")) ? graphtype.DIRECTED : graphtype.UNDIRECTED;

      while (!line.contains("FromNodeId") && !line.contains("ToNodeId")) {
        line = fr.readLine();
      }
      nodecounter = parseEdges(sep1, fr, idMapping, nodecounter, edges, type);

      Node[] nodes = Node.init(idMapping.size(), graph);
      Edges e = new Edges(nodes, edges.size());
      ListIterator<String> edgeIterator = edges.listIterator();
      while (edgeIterator.hasNext()) {
        String[] pair = edgeIterator.next().split("-");
        e.add(Integer.parseInt(pair[0]), Integer.parseInt(pair[1]));
      }

      e.fill();
      graph.setNodes(nodes);
      return graph;
    } catch (Exception e) {
      return null;
    } finally {
      fr.close();
    }
  }
  /**
   * @param sep1
   * @param fr
   * @param idMapping
   * @param nodecounter
   * @param edges
   * @param type
   * @return
   */
  private int parseEdges(
      String sep1,
      SNAPFileReader fr,
      Map<Integer, Integer> idMapping,
      int nodecounter,
      LinkedList<String> edges,
      graphtype type) {
    String line;
    while ((line = fr.readLine()) != null) {
      line.trim();

      String[] temp = line.split(sep1);
      if (temp.length < 2 || temp[1].length() == 0) {
        continue;
      }
      int src = Integer.parseInt(temp[0]);
      int dst = Integer.parseInt(temp[1]);
      @SuppressWarnings("unused")
      int relation = Integer.parseInt(temp[2]); // TODO currently not used, prepared for later usage

      int gtnaSrc;
      int gtnaDst;

      if (idMapping.containsKey(src)) {
        gtnaSrc = idMapping.get(src);
      } else {
        idMapping.put(src, nodecounter);
        gtnaSrc = nodecounter;
        nodecounter++;
      }

      if (idMapping.containsKey(dst)) {
        gtnaDst = idMapping.get(dst);
      } else {
        idMapping.put(dst, nodecounter);
        gtnaDst = nodecounter;
        nodecounter++;
      }

      // directed
      edges.add(gtnaSrc + "-" + gtnaDst);
      if (type == graphtype.UNDIRECTED) edges.add(gtnaDst + "-" + gtnaSrc);
    }
    return nodecounter;
  }