#pragma once

#include "vector"
#include "algorithm"
#include "tuple"

static size_t distance;

template<typename Vertex>
class BfsVisitor {
 public:
  BfsVisitor() {
    distance_ = new std::vector<std::tuple<Vertex, size_t, Vertex>>;
    parent_ = new Vertex;
  }

  void ExamineVertex(const Vertex &vertex) {
    for (std::tuple<Vertex, size_t, Vertex> vert  : *distance_) {
      if (std::get<0>(vert) == vertex) {
        distance = std::get<1>(vert) + 1;
        *parent_ = vertex;
      }
    }
  }

  void DiscoverVertex(const Vertex &vertex) {
    if ((*distance_).size() == 0) {
      distance = 0;
      *parent_ = vertex;
    }
    (*distance_).push_back(std::make_tuple(vertex, distance, *parent_));
  }

  size_t DistanceTo(const Vertex &target) const {
    for (std::tuple<Vertex, size_t, Vertex> vert : *distance_) {
      if (std::get<0>(vert) == target) {
        return std::get<1>(vert);
      }
    }
    return 9999;
  }
  Vertex Parent(const Vertex &vertex) const {
    for (std::tuple<Vertex, size_t, Vertex> vert : *distance_) {
      if (std::get<0>(vert) == vertex) {
        return std::get<2>(vert);
      }
    }
    return 9999;
  }

  std::vector<std::tuple<Vertex, size_t, Vertex>> *distance_;
  Vertex *parent_;
};