#pragma once
#include "sector.hpp"
#include "a83/mat.hpp"
#include "common/Vec.hpp"
//! игровая кординатная система
struct Cord {
  int xs = 0, ys = 0; ///< кординаты в сектора
  float x = 0, y = 0; ///< кординаты внутри сектора
  Cord() = default;
  Cord(const Cord&) = default;
  Cord(int xSct, int ySct, float _x, float _y)
    : xs(xSct), ys(ySct), x(_x), y(_y) {}
  void fix(); ///< исправляет x/y корды, если они больше положеного
  void clear() { xs = ys = 0; x = y = 0; }
  Cord& operator =(const Cord&) = default;
  void operator -=(const Cord& val);
  void operator +=(const Cord& val);
  void operator +=(const Vec& val);
  void operator *=(float val);
  Cord operator +(Cord val) const;
  Cord operator -(Cord val) const;
};
void Cord::fix() {
  constexpr auto XP = float(Sector::XP);
  constexpr auto YP = float(Sector::YP);
  if (x < 0.0f) {
    auto mul = std::floor(-x / XP) + 1.0f;
    x += Sector::XP * mul;
    --xs;
  }
  if (x >= XP) {
    auto mul = std::floor(x / XP);
    x -= Sector::XP * mul;
    ++xs;
  }
  if (y < 0.0f) {
    auto mul = std::floor(-y / YP) + 1.0f;
    y += YP * mul;
    --ys;
  }
  if (y >= YP) {
    auto mul = std::floor(y / YP);
    y -= YP * mul;
    ++ys;
  }
}
Cord Cord::operator +(Cord val) const {
  val.xs += xs; val.ys += ys;
  val.x  += x;  val.y  += y;
  return val;
}
Cord Cord::operator -(Cord val) const {
  val.xs -= xs; val.ys -= ys;
  val.x  -= x;  val.y  -= y;
  return val;
}
void Cord::operator -=(const Cord& val) {
  xs -= val.xs; ys -= val.ys;
  x  -= val.x;  y  -= val.y;
}
void Cord::operator +=(const Cord& val) {
  xs += val.xs; ys += val.ys;
  x  += val.x;  y  += val.y;
}
void Cord::operator +=(const Vec& val) { x += val.x; y += val.y; }
void Cord::operator *=(float val) {
  if (val == 1.0f)
    return;
  if (val == 0.0f) {
    clear();
    return;
  }
  x = (x + xs * Sector::XP) * val;
  y = (y + ys * Sector::YP) * val;
  xs = ys = 0;
  fix();
}
