#ifndef _STATIC_GEOMETRY_MODULE_H_
#define _STATIC_GEOMETRY_MODULE_H_
#include <flecs.h>
#include <nlohmann/json.hpp>
#include <Ogre.h>
namespace Procedural
{
class TriangleBuffer;
}
namespace Ogre
{
struct LodConfig;
}
namespace ECS
{
struct TerrainSlotParent {
	std::pair<long, long> slot;
};
struct TerrainItem {
	Ogre::Vector3 position;
	Ogre::Quaternion orientation;
	Ogre::String properties;
};
struct TerrainItemNode {
	Ogre::SceneNode *itemNode;
	Ogre::StaticGeometry *geo;
};
struct TerrainItemMeshNode {
	Ogre::SceneNode *itemNode;
	Ogre::StaticGeometry *geo;
};
struct FurnitureItem {
    Ogre::String properties;
    std::vector<Ogre::String> tags;
};
struct FurnitureInstance {
    Ogre::SceneNode *furniture;
};
struct GeometryUpdateItem {};

struct TownCollider {};

struct StaticGeometryModule {
	StaticGeometryModule(flecs::world &ecs);
	static void addGeometryForSlot(long x, long y);
	static void removeGeometryForSlot(long x, long y);
	static flecs::entity createItem(const Ogre::Vector3 &position,
					const Ogre::Quaternion &orientation,
					const Ogre::String &type);
	static void setItemProperties(flecs::entity id,
				      Ogre::String properties);
	static const Ogre::String &getItemProperties(flecs::entity id);
    static void loadTemplates();
    static void saveTemplates();
    static void saveItems();
	static void loadItems();
    static void saveFurniture();
    static void loadFurniture();
	static void getItemPositionPerSlot(long x, long y,
					   std::list<Ogre::Vector3> *positions);
	static void getItemPositions(std::list<Ogre::Vector3> *positions);
	static void getItemPositionAndRotation(flecs::entity e,
					       Ogre::Vector3 &position,
					       Ogre::Quaternion &orientation);
	static void getItemsProperties(
		std::list<std::pair<flecs::entity, Ogre::String> > *items);
	static void createItemGeometry(flecs::entity e);
	static void destroyItemGeometry(flecs::entity e);
    static nlohmann::json &getTemplates();
    static void updateItemGeometry(flecs::entity e);
    static void addTriangleBufferWork(const Ogre::String &meshName,
                      Ogre::StaticGeometry *geo,
                      const Ogre::Vector3 &position,
                      const Ogre::Quaternion &rotation,
                      const Procedural::TriangleBuffer &tb);
};
}
#endif
