#include "grid.h"

#include <yandex/maps/wiki/common/geom.h>
#include <yandex/maps/wiki/common/geom_utils.h>

#include <maps/libs/geolib/include/bounding_box.h>
#include <maps/libs/geolib/include/conversion.h>
#include <maps/libs/geolib/include/distance.h>
#include <maps/libs/geolib/include/vector.h>

#include <vector>
#include <cmath>

namespace maps {
namespace wiki {
namespace signals_graph {

Grid::Grid(const maps::geolib3::BoundingBox& mercatorBbox, double cellSpan)
        : cellSpan(cellSpan) {
    const double mercSpan = geolib3::toMercatorUnits(cellSpan, mercatorBbox.lowerCorner());

    widthCells = std::ceil(mercatorBbox.width() / mercSpan);
    heightCells = std::ceil(mercatorBbox.height() / mercSpan);

    auto initialPoint = mercatorBbox.lowerCorner();
    maps::geolib3::Vector2 widthVec{mercatorBbox.width() / widthCells, 0};
    maps::geolib3::Vector2 heightVec{0, mercatorBbox.height() / heightCells};
    auto diagonal = widthVec + heightVec;

    boxes = std::vector<std::vector<geolib3::BoundingBox>>(
            heightCells, std::vector<geolib3::BoundingBox>(widthCells));

    for (size_t i = 0; i < heightCells; ++i) {
        for (size_t j = 0; j < widthCells; ++j) {
            auto currentPoint = initialPoint + i * heightVec + j * widthVec;
            boxes[i][j] = maps::geolib3::BoundingBox(
                currentPoint, currentPoint + diagonal);
        }
    }
}

} // namespace signals_graph
} // namespace wiki
} // namespace maps
