#include "render.h"

#include "../style.h"
#include "../save.h"

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

#include <maps/libs/geolib/include/conversion_geos.h>
#include <geos/geom/LineString.h>

#include <geos/geom/MultiLineString.h>

#include <maps/libs/log8/include/log8.h>

#include <ostream>

namespace maps {
namespace wiki {
namespace signals_graph {
namespace {

void printLineString(
    std::ostream& ostr,
    const geos::geom::LineString* geometry
) {
    auto points = geolib3::internal::geosLineString2Points(geometry);

    for (const auto& point : points) {
        printPoint(ostr, point) << " ";
    }
}

} // namespace

void renderEasyView(
    std::ostream& ostr,
    const geolib3::Polyline2& polyline,
    const std::string& description /* = "" */
) {
    for (const auto& point : polyline.points()) {
        printPoint(ostr, point) << " ";
    }
    ostr << description << std::endl;
}

void renderEasyView(
    std::ostream& ostr,
    const geos::geom::MultiLineString* geomPtr,
    const std::string& description /* = "" */
) {
    for (const auto& linestring : *geomPtr) {
        printLineString(
            ostr,
            dynamic_cast<const geos::geom::LineString*>(linestring.get())
        );
        ostr << description << std::endl;
    }
}

void renderEasyView(
    std::ostream& ostr,
    common::ConstGeosGeometryPtr geomPtr,
    geos::geom::GeometryTypeId id,
    const std::string& description /* = "" */
) {
    switch (id) {
        case geos::geom::GeometryTypeId::GEOS_LINESTRING:
            printLineString(
                ostr,
                dynamic_cast<const geos::geom::LineString*>(geomPtr)
            );
            ostr << description << std::endl;
            break;
        case geos::geom::GeometryTypeId::GEOS_MULTILINESTRING:
            renderEasyView(
                ostr,
                dynamic_cast<const geos::geom::MultiLineString*>(geomPtr),
                description
            );
            break;
        default:
            INFO() << "Don't know how to render TypeId " << id;
    }
}

void renderGeometriesEasyView(
    std::ostream& file,
    const std::vector<common::Geom>& geoms,
    const std::vector<std::string>& descriptions,
    Style style
)
{
    printLinestyle(style, file);
    for (size_t i = 0; i < geoms.size(); ++i) {
        const auto& geom = geoms[i];

        if (geom.isNull()) {
            continue;
        }

        auto id = geom->getGeometryTypeId();
        renderEasyView(file, geom.geosGeometryPtr(), id, descriptions[i]);
    }
}

void renderGeometriesEasyView(
    std::ostream& file,
    const std::vector<common::Geom>& geoms,
    Style style
)
{
    printLinestyle(style, file);
    for (size_t i = 0; i < geoms.size(); ++i) {
        const auto& geom = geoms[i];

        if (geom.isNull()) {
            continue;
        }

        auto id = geom->getGeometryTypeId();
        renderEasyView(file, geom.geosGeometryPtr(), id);
    }
}

void renderGeometriesEasyView(
    std::ostream& file,
    const std::vector<geolib3::Polyline2>& geoms,
    Style style
)
{
    printLinestyle(style, file);
    for (size_t i = 0; i < geoms.size(); ++i) {
        const auto& geom = geoms[i];
        renderEasyView(file, geom);
    }
}

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