#include "test_tools.h"
#include <hugo/smart_graph.h>
#include <hugo/bfs.h>
#include<hugo/skeletons/graph.h>

using namespace hugo;

const int PET_SIZE =5;


void check_Bfs_Compile() 
{
  typedef skeleton::StaticGraphSkeleton Graph;

  typedef Graph::Edge Edge;
  typedef Graph::Node Node;
  typedef Graph::EdgeIt EdgeIt;
  typedef Graph::NodeIt NodeIt;
 
  typedef Bfs<Graph> BType;
  
  Graph G;
  Node n;
  Edge e;
  int l;
  bool b;
  BType::DistMap d(G);
  BType::PredMap p(G);
  BType::PredNodeMap pn(G);
  
  BType bfs_test(G);
  
  bfs_test.run(n);
  
  l  = bfs_test.dist(n);
  e  = bfs_test.pred(n);
  n  = bfs_test.predNode(n);
  d  = bfs_test.distMap();
  p  = bfs_test.predMap();
  pn = bfs_test.predNodeMap();
  b  = bfs_test.reached(n);

}

int main()
{
    
  typedef SmartGraph Graph;

  typedef Graph::Edge Edge;
  typedef Graph::Node Node;
  typedef Graph::EdgeIt EdgeIt;
  typedef Graph::NodeIt NodeIt;
  typedef Graph::EdgeMap<int> LengthMap;

  Graph G;
  Node s, t;
  PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
   
  s=ps.outer[2];
  t=ps.inner[0];
  
  Bfs<Graph> bfs_test(G);
  bfs_test.run(s);
  
  check(bfs_test.dist(t)==3,"Bfs found a wrong path. " << bfs_test.dist(t));


  for(EdgeIt e(G); e==INVALID; ++e) {
    Node u=G.tail(e);
    Node v=G.head(e);
    check( !bfs_test.reached(u) ||
	   (bfs_test.dist(v) > bfs_test.dist(u)+1),
	   "Wrong output.");
  }

  for(NodeIt v(G); v==INVALID; ++v) {
    check(bfs_test.reached(v),"Each node should be reached.");
    if ( bfs_test.pred(v)!=INVALID ) {
      Edge e=bfs_test.pred(v);
      Node u=G.tail(e);
      check(u==bfs_test.predNode(v),"Wrong tree.");
      check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
	    "Wrong distance. Difference: " 
	    << std::abs(bfs_test.dist(v) - bfs_test.dist(u) 
			- 1));
    }
  }
}

