#ifndef BSK_SCENE2D_H
#define BSK_SCENE2D_H

#include <basilisk/util/includes.h>
#include <memory>
#include <basilisk/engine/engine.h>
#include <basilisk/camera/virtualCamera.h>
#include <basilisk/scene/virtualScene.h>
#include <basilisk/camera/camera2d.h>
#include <basilisk/render/shader.h>
#include <basilisk/physics/solver.h>
#include <basilisk/scene/raycast.h>

namespace bsk::internal {

class Node2D;

class Scene2D : public VirtualScene<Node2D, glm::vec2, float, glm::vec2> {
    private:
        StaticCamera2D* camera;
        StaticCamera2D* internalCamera;
        std::shared_ptr<StaticCamera2D> cameraPython;
        Shader* shader;
        Solver* solver;

    public:
        Scene2D(Engine* engine);
        Scene2D(Engine* engine, Shader* shader);
        ~Scene2D();

        void update();
        void render();

        void add(Node2D* node) override;
        void add(std::shared_ptr<Node2D> node) override;
        void remove(Node2D* node) override;
        void remove(std::shared_ptr<Node2D> node) override;

        void setCamera(StaticCamera2D* camera) { this->camera = camera; }
        void setCamera(std::shared_ptr<StaticCamera2D> cameraSp) { cameraPython = std::move(cameraSp); camera = cameraPython.get(); }

        inline Shader* getShader() override { return shader; }
        inline StaticCamera2D* getCamera() { return camera; }
        inline Solver* getSolver() { return solver; }

        // raycasting
        Node2D* pick(glm::vec2 mousePosition);
        RayCastResult2D raycast(glm::vec2 origin, glm::vec2 direction);
};

}

#endif