#ifndef __ITEMS_H__
#define __ITEMS_H__
#include <OgreMeshLodGenerator.h>
#include <flecs.h>
#include "Components.h"
#include "GameData.h"
namespace ECS
{
namespace Items
{
void showItemPopup(const std::pair<flecs::entity, Ogre::String> &item);
void showItemButtons(const std::pair<flecs::entity, Ogre::String> &item);
void createItemsMenu();
void runScriptsForAllTowns();
}
namespace Geometry
{
void setupLods(Ogre::LodConfig &config);
struct harbourMaker {
	Ogre::Entity *planks, *pillar, *beam;
	Ogre::String makeName(const Ogre::String &base, flecs::entity e)
	{
		return base + Ogre::StringConverter::toString(e.id());
	}
	harbourMaker(flecs::entity e)
	{
		Ogre::String planksName = makeName("Plank", e);
		Ogre::String beamName = makeName("Beam", e);
		Ogre::String pillarName = makeName("Pillar", e);
		std::pair<Ogre::String, Ogre::Entity **> sets[] = {
			{ planksName, &planks },
			{ beamName, &beam },
			{ pillarName, &pillar }
		};
		std::map<Ogre::String, Ogre::String> meshes = {
			{ planksName, "pier-plank.glb" },
			{ beamName, "pier-beam.glb" },
			{ pillarName, "pier-pillar.glb" },
		};
		for (auto &p : sets) {
			if (ECS::get<EngineData>().mScnMgr->hasEntity(p.first))
				*p.second =
					ECS::get<EngineData>()
						.mScnMgr->getEntity(p.first);
			else {
				*p.second = ECS::get<EngineData>()
						    .mScnMgr->createEntity(
							    p.first,
							    meshes.at(p.first));
				Ogre::MeshPtr mesh = (*p.second)->getMesh();
				Ogre::LodConfig config(mesh);
				setupLods(config);
			}
		}
	}
};
void createItemGeometry(flecs::entity e);
void destroyItemGeometry(flecs::entity e);
void updateItemGeometry(flecs::entity e);
void registerTownItem(flecs::entity e);
flecs::entity createMeshGeometry(const Ogre::String &meshName,
				 flecs::entity parente,
				 Ogre::SceneNode *sceneNode,
				 Ogre::StaticGeometry *geo);

}
static void to_json(nlohmann::json &j, const Ogre::Vector3 &position)
{
	j["x"] = position.x;
	j["y"] = position.y;
	j["z"] = position.z;
}
static void to_json(nlohmann::json &j, const Ogre::Quaternion &orientation)
{
	j["w"] = orientation.w;
	j["x"] = orientation.x;
	j["y"] = orientation.y;
	j["z"] = orientation.z;
}
static void to_json(nlohmann::json &j, const Ogre::ColourValue &colour)
{
    j["r"] = colour.r;
    j["g"] = colour.g;
    j["b"] = colour.b;
    j["a"] = colour.a;
}
static void from_json(const nlohmann::json &j, Ogre::Vector3 &position)
{
	position.x = j["x"].get<float>();
	position.y = j["y"].get<float>();
	position.z = j["z"].get<float>();
}
static void from_json(const nlohmann::json &j, Ogre::Quaternion &orientation)
{
	orientation.w = j["w"].get<float>();
	orientation.x = j["x"].get<float>();
	orientation.y = j["y"].get<float>();
	orientation.z = j["z"].get<float>();
}
static void from_json(const nlohmann::json &j, Ogre::ColourValue &colour)
{
    colour.r = j["r"].get<float>();
    colour.g = j["g"].get<float>();
    colour.b = j["b"].get<float>();
    colour.a = j["a"].get<float>();
}
}
#endif
