#pragma once
#include "tile.hpp"
#include "a83/error.hpp"
/** базовый класс секторов
* @details прозрачный сектор это nullptr */
class Sector {
public:
  // размеры тайла:
  constx int X = 8;
  constx int Y = 8;
  // размеры в пикселях:
  constx int XP = X * 8;
  constx int YP = Y * 8;
  Sector() = default;
  virtual ~Sector() = default;
  //! отобразить сектор
  virtual void print(int /*xPos*/, int /*yPos*/, Image& /*dst*/, const BankTex& /*btex*/,
    const BankSprite& /*bspr*/, const int& /*anim_timer*/) const {}
  //! задать тайл в секторе
  virtual void set(int /*x*/, int /*y*/, const Tile& /*val*/) {}
  virtual const Tile* get(int =0, int =0) const { return nullptr; }
  // заполнить сектор одинаковыми тайлами
  virtual void fill(const Tile& /*val*/) {}
};
//! одна общая картинка на весь сектор сектор
class SectorMono: public Sector {
protected:
  Tile tile = {};
public:
  SectorMono() = default;
  explicit SectorMono(int id, bool msk=false, int cnt=1, int st=0, int divr=1)
    : tile(id, msk, cnt, st, divr) {}
  void print(int xPos, int yPos, Image& dst, const BankTex& btex, const BankSprite& bspr,
    const int& anim_timer) const override
    { tile.print(xPos, yPos, dst, btex, bspr, anim_timer); }
  const Tile* get(int = 0, int = 0) const override { return &tile; }
  virtual void fill(const Tile& val) override { tile = val; }
};
//! текстурированный сектор
class SectorTile: public Sector {
protected:
  constx int SIZE = X * Y;
  Tile data[SIZE] = {};
public:
  SectorTile() = default;
  ~SectorTile() = default;
  void print(int xPos, int yPos, Image& dst, const BankTex& btex, const BankSprite& bspr,
    const int& anim_timer) const override;
  void set(int x, int y, const Tile& val) override;
  const Tile* get(int x, int y) const override;
  virtual void fill(const Tile& val) override { std::fill(data, data + X*Y, val); }
};
void SectorTile::print(int xPos, int yPos, Image& dst,
const BankTex& btex, const BankSprite& bspr,
const int& anim_timer) const {
  for (int y = 0; y < Y; ++y)
  for (int x = 0; x < X; ++x)
    data[y * X + x].print(x*8 + xPos, y*8 + yPos, dst, btex, bspr, anim_timer);
}
void SectorTile::set(int x, int y, const Tile& val) {
  const int index = y * X + x;
  IFERROR(index < 0 || index >= SIZE, "sector tile set - index error");
  data[index] = val;
}
const Tile* SectorTile::get(int x, int y) const {
  const int index = y * X + x;
  IFERROR(index < 0 || index >= SIZE, "sector tile get ptr - index error");
  return &data[index];
}
//! пустой сектор
class SectorEmpty: public Sector {
public:
  SectorEmpty() = default;
  ~SectorEmpty() = default;
};
