#ifndef SCENETREE_H
#define SCENETREE_H

#include <vector>
#include <string>
#include <unordered_set>
#include "SparrowRenderer/scene.h"
#include "containernode.h"
#include "engine.h"

class Light;
class CameraNode;

/**
 * @brief The SceneNode class represents a class of the game
 * that will be updated or used for rendering every frame
 */

class SceneTree : public Scene
{
public:
    ~SceneTree();

    virtual SceneIterator<Light*>* getLights();
    virtual SceneIterator<GeometryNode*>* getGeometry();

    virtual void getMeshTypes(std::vector<unsigned int> &meshTypes);
    virtual void getLightTypes(std::vector<unsigned int> &lightTypes);

    void update();

    void setMainCamera(CameraNode *camNode);
    Camera* getCamera() const { return m_camera; }

    ContainerNode* getRootObject(){return &m_root;}
    void registerMeshType(unsigned int meshType);
    void registerLightType(unsigned int lightType);
    void addToIndex(SceneNode* node);
    void removeFromIndex(SceneNode *node);
    void updateShaders();

    const Engine& getEngine() { return m_engine; }

private:
    // A SceneTree can only be constructed by the engine by using Engine::createScene()
    //friend SceneTree* Engine::createScene();
    friend void Engine::createScene(std::string scene_name);
    SceneTree(const Engine &engine);

    const Engine &m_engine;
    ContainerNode m_root;
    std::vector<Light*> m_lights;
    std::vector<GeometryNode*> m_geometries;
    std::unordered_set<unsigned int> m_meshTypes;
    std::unordered_set<unsigned int> m_lightTypes;
    bool m_shaderRefreshRequired;
    Camera* m_camera;
};

#endif // SCENETREE_H
