#pragma once

#include "cache.h"

#include <map>
#include <string>
#include <filesystem>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

namespace bg = boost::geometry;

class BoundingBox {
private:
	Position a;
	Position b;
public:
	inline bool within(Position p);

	BoundingBox(Position p1, Position p2);
};

class ContourData {
private:
	bg::model::polygon<boost::geometry::model::d2::point_xy<double>> contour;
	BoundingBox bbox;
public:
	ContourData(BoundingBox bbox);
	bool within(Position p);
	void add_point(Position p);
};

class Region {
private:
	ContourData* contour;
	std::string name;
	std::vector<Region*> subregions;

	std::map<std::string, ContourData*> parse_geojson(const std::string& json_file);
public:
	Region(ContourData* contour, std::string name) : contour(contour), name(name) {}
	Region(const std::filesystem::path& geojson, const std::filesystem::path& geojson_sub);
	~Region();

	bool within(Position p) { return contour->within(p); }
	std::string get_name() { return name; }
	std::string find_subregion(Position p);
};

class Country {
private:
	std::vector<Region*> regions;
public:
	Country(const std::vector<std::filesystem::path>& jsons);
	void locate(Cache& c);
};
