#pragma once
#include "algos/point.hpp"
#include "algos/matrix.hpp"
#include <functional>

using matrix::Matrix;

constexpr const int PATHING_TOWARD=1;
constexpr const int PATHING_AWAY=-1;

enum class PathingResult {
  FAIL=0,
  FOUND=1,
  CONTINUE=2
};

class Pathing {
public:
  size_t $width;
  size_t $height;
  Matrix $paths;
  Matrix $input;

  Pathing(size_t width, size_t height) :
    $width(width),
    $height(height),
    $paths(height, matrix::Row(width, 1)),
    $input(height, matrix::Row(width, 1))
  {}

  int compute_paths(Matrix &walls);
  void set_target(const Point &at, int value=0);
  void clear_target(const Point &at);
  Matrix &paths() { return $paths; }
  Matrix &input() { return $input; }
  int distance(Point to) { return $paths[to.y][to.x];}
  PathingResult find_path(Point &out, int direction, bool diag);

  bool INVARIANT();
  void dump(const std::string& msg);
};
