#include <lemon/smart_graph.h>

#include "map_utils.h"


#include "graph_reader.h"
#include "graph_writer.h"

#include <iostream>
#include <fstream>

using namespace std;
using namespace lemon;

int main() {
  ifstream input("test.lgf");
  SmartGraph graph;
  GraphReader<SmartGraph> reader(input, graph);

  SmartGraph::NodeMap<int> id(graph);
  reader.addNodeMap("id", id);

  SmartGraph::NodeMap<int> cost(graph);
  reader.addNodeMap("cost", cost);
 
  SmartGraph::NodeMap<string> color(graph);
  reader.addNodeMap("color", color);

  SmartGraph::NodeMap<string> description(graph);
  reader.addNodeMap<QuotedStringReader>("description", description);

  SmartGraph::EdgeMap<char> mmap(graph);
  reader.addEdgeMap("mmap", mmap);

  reader.skipEdgeMap<QuotedStringReader>("description");

  SmartGraph::Node source;
  reader.addNode("source", source);
  
  SmartGraph::Edge newedge;
  reader.addEdge("newedge", newedge);

  try {
    reader.read();
  } catch (IOException& e) {
    cerr << e.what() << endl;
  } catch (Exception e) {
    cerr << e.what() << endl;
  }

  for (SmartGraph::NodeIt it(graph); it != INVALID; ++it) {
    cout << cost[it] << ' ' << color[it] << ' ' << description[it] << endl;
  }

  for (SmartGraph::EdgeIt it(graph); it != INVALID; ++it) {
    cout << mmap[it] << ' ' << id[graph.source(it)] << ' ' << 
      id[graph.target(it)]  << endl;
  }

  cout << id[source] << ' ' << cost[source] << ' ' <<
    color[source] << ' ' << description[source] << endl;
  cout << mmap[newedge] << ' ' << id[graph.source(newedge)] << 
    ' ' << id[graph.target(newedge)]  << endl;

  ofstream output("copy.lgf");
  GraphWriter<SmartGraph> writer(output, graph);
  
  DescriptorMap<SmartGraph, SmartGraph::Node, SmartGraph::NodeMap<int> > 
    node_ids(graph);
  
  writer.addNodeMap("id", node_ids);
  writer.addNodeMap<QuotedStringWriter>("format", description);

  IdMap<SmartGraph, SmartGraph::Edge > edge_ids(graph);

  writer.addEdgeMap("id", edge_ids);
  writer.addEdgeMap("chars", mmap);
  
  writer.addNode("source", node_ids.inverse()[3]);
  //  writer.addEdge("elek", edge_ids.inverse()[6]);
  writer.write();
  
  return 0;
}
