#ifndef EDITSCENE_EDITOR_WATERPLANE_SYSTEM_HPP
#define EDITSCENE_EDITOR_WATERPLANE_SYSTEM_HPP
#pragma once

#include <flecs.h>
#include <Ogre.h>

/**
 * WaterPlane system - manages visual water surface with
 * reflection/refraction render-to-texture.
 */
class EditorWaterPlaneSystem {
public:
	EditorWaterPlaneSystem(flecs::world &world,
			       Ogre::SceneManager *sceneMgr);
	~EditorWaterPlaneSystem();

	void update(float deltaTime, Ogre::Camera *camera);

private:
	void rebuildWaterPlane(flecs::entity entity, struct WaterPlane &wp,
			       struct TransformComponent &transform);
	void cleanupWaterPlane(WaterPlane &wp);
	void createPlaneMesh(WaterPlane &wp);
	void updateCameras(WaterPlane &wp, Ogre::Camera *camera);
	void updatePosition(WaterPlane &wp, float deltaTime,
			    Ogre::Camera *camera);
	void updateShaderParams(WaterPlane &wp, float deltaTime);
	void updateUnderwaterEffect(Ogre::Camera *camera, float deltaTime);
	Ogre::SceneNode *getReflectionNode(WaterPlane &wp);
	Ogre::SceneNode *getRefractionNode(WaterPlane &wp);

	// Render target listener - hides water during RTT update
	class WaterRenderTargetListener :
		public Ogre::RenderTargetListener {
	public:
		Ogre::ManualObject *waterMesh = nullptr;
		void preRenderTargetUpdate(
			const Ogre::RenderTargetEvent &evt) override;
		void postRenderTargetUpdate(
			const Ogre::RenderTargetEvent &evt) override;
	};

	flecs::world &m_world;
	Ogre::SceneManager *m_sceneMgr;
	flecs::query<struct WaterPlane, struct TransformComponent> m_query;
	WaterRenderTargetListener m_listener;
	float m_underwaterTime = 0.0f;
	bool m_compositorAdded = false;
	Ogre::Viewport *m_compositorViewport = nullptr;
};

#endif // EDITSCENE_EDITOR_WATERPLANE_SYSTEM_HPP
