#pragma once

#include <flecs.h>
#include <memory>

namespace Ogre {
    class SceneManager;
}

namespace Procedural {
    class TriangleBuffer;
}

class ProceduralMeshSystem {
public:
    ProceduralMeshSystem(flecs::world& world, Ogre::SceneManager* sceneMgr);
    ~ProceduralMeshSystem();
    
    // Initialize the system
    void initialize();
    
    // Main update - builds dirty triangle buffers and converts to meshes
    void update();
    
    // Force rebuild of a specific triangle buffer
    void rebuildTriangleBuffer(flecs::entity entity);
    
    // Check if triangle buffer has valid triangles (non-degenerate)
    bool hasValidTriangles(Procedural::TriangleBuffer* buffer);
    
private:
    flecs::world& m_world;
    Ogre::SceneManager* m_sceneMgr;
    
    flecs::query<struct TriangleBufferComponent> m_triangleBufferQuery;
    flecs::query<struct PrimitiveComponent> m_primitiveQuery;
    
    bool m_initialized = false;
    int m_meshCount = 0;
    
    // Build triangle buffer from primitive children
    void buildTriangleBuffer(flecs::entity entity, struct TriangleBufferComponent& tb);
    
    // Convert triangle buffer to Ogre mesh
    void convertToMesh(flecs::entity entity, struct TriangleBufferComponent& tb);
    
    // Apply UV mapping from named rectangle
    void applyUVMapping(Procedural::TriangleBuffer* buffer, struct ProceduralTextureComponent& texture, 
                        const std::string& rectName);
    
    // Destroy existing mesh/entity
    void destroyMesh(struct TriangleBufferComponent& tb);
    
    // Check if any primitive children are dirty
    bool arePrimitivesDirty(flecs::entity parent);
    
    // Attach mesh to StaticGeometry region
    void attachToStaticGeometry(flecs::entity entity, struct TriangleBufferComponent& tb);
};
