#include <OgreMaterialManager.h>
#include <OgreMaterial.h>
#include <OgreTechnique.h>
#include <OgrePass.h>
#include "Components.h"
#include "GameData.h"
#include "EditorGizmoModule.h"

namespace ECS
{
static Ogre::MaterialPtr
createVertexColorNoDepthMaterial(const std::string &materialName)
{
	Ogre::MaterialPtr material =
		Ogre::MaterialManager::getSingleton().create(
			materialName,
			Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	Ogre::Pass *pass = material->getTechnique(0)->getPass(0);

	// Disable dynamic lighting, so only vertex colors are used
	pass->setLightingEnabled(false);
	pass->setCullingMode(Ogre::CULL_NONE);
	pass->setPolygonModeOverrideable(false);
	pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);

	// Set the material to use vertex colors for diffuse, ambient, and specular components
	pass->setVertexColourTracking(Ogre::TVC_DIFFUSE | Ogre::TVC_AMBIENT |
				      Ogre::TVC_SPECULAR);

	// Disable depth checking (so it renders regardless of what's already in the depth buffer)
	// pass->setDepthCheckEnabled(false);
	pass->setDepthCheckEnabled(false);

	// Disable depth writing (so subsequent objects are not occluded by this one)
	// pass->setDepthWriteEnabled(false);
	pass->setDepthWriteEnabled(false);

	// Optional: Set scene blending to alpha blending if you use vertex alpha
	// pass->setSceneBlending(Ogre::SBT_ALPHA_BLEND);

	// Load the material (important if resources are not automatically loaded)
	material->load();

	return material;
}
EditorGizmoModule::EditorGizmoModule(flecs::world &ecs)
{
	ecs.module<EditorGizmoModule>();
	ecs.component<EditorDebugMaterial>().add(flecs::Singleton);
	ecs.component<EditorGizmo>().add(flecs::Singleton);
	ecs.observer<EditorDebugMaterial>("SetupDebugMaterial")
		.event(flecs::OnAdd)
		.each([](EditorDebugMaterial &mdbg) {
			mdbg.material = createVertexColorNoDepthMaterial(
				"Debug/vcolor");
		});
	ecs.observer<const EditorDebugMaterial, EditorGizmo>("SetupGizmo")
		.event(flecs::OnSet)
		.each([](const EditorDebugMaterial &mdbg, EditorGizmo &gizmo) {
			const int size = 20;
			gizmo.gizmo->setBufferUsage(Ogre::HBU_CPU_TO_GPU);
			gizmo.gizmo->begin(mdbg.material,
					   Ogre::RenderOperation::OT_LINE_LIST);
			gizmo.gizmo->position(Ogre::Vector3(0, 0, 0));
			gizmo.gizmo->colour(Ogre::ColourValue(0, 0, 1, 1));
			gizmo.gizmo->position(Ogre::Vector3(0, 0, size));
			gizmo.gizmo->colour(Ogre::ColourValue(0, 0, 1, 1));
			gizmo.gizmo->position(Ogre::Vector3(0, 0, 0));
			gizmo.gizmo->colour(Ogre::ColourValue(0, 1, 0, 1));
			gizmo.gizmo->position(Ogre::Vector3(0, size, 0));
			gizmo.gizmo->colour(Ogre::ColourValue(0, 1, 0, 1));
			gizmo.gizmo->position(Ogre::Vector3(0, 0, 0));
			gizmo.gizmo->colour(Ogre::ColourValue(1, 0, 0, 1));
			gizmo.gizmo->position(Ogre::Vector3(size, 0, 0));
			gizmo.gizmo->colour(Ogre::ColourValue(1, 0, 0, 1));
			gizmo.gizmo->end();
		});
}
}
