#pragma once
#include <vector>
#include <queue>
#include <string>
#include <array>
#include <numeric>
#include <algorithm>
#include <fmt/core.h>
#include "point.hpp"
#include "rand.hpp"
#include "dbc.hpp"
#include "shiterator.hpp"

namespace matrix {
  using Row = shiterator::BaseRow<int>;
  using Matrix = shiterator::Base<int>;

  using viewport = shiterator::viewport_t<Matrix>;

  using each_cell = shiterator::each_cell_t<Matrix>;

  using each_row = shiterator::each_row_t<Matrix>;
  using box = shiterator::box_t<Matrix>;
  using compass = shiterator::compass_t<Matrix>;
  using circle = shiterator::circle_t<Matrix>;
  using rectangle = shiterator::rectangle_t<Matrix>;
  using rando_rect = shiterator::rando_rect_t<Matrix>;
  using line = shiterator::line;

  void dump(const std::string &msg, Matrix &map, int show_x=-1, int show_y=-1);

  inline Matrix make(size_t width, size_t height) {
    return shiterator::make<int>(width, height);
  }

  inline bool inbounds(Matrix &mat, size_t x, size_t y) {
    return shiterator::inbounds(mat, x, y);
  }

  inline size_t width(Matrix &mat) {
    return shiterator::width(mat);
  }

  inline size_t height(Matrix &mat) {
    return shiterator::height(mat);
  }

  inline void assign(Matrix &out, int new_value) {
    shiterator::assign(out, new_value);
  }
}