#include <studio/simulator.hpp>

#include <gui/ui.hpp>
#include <utils/assumptions.hpp>

#include <iostream>

namespace studio {
Simulator::Simulator()
    : osi::Simulator()
    , my_shaders{{"lit", std::make_shared<Shader>("./data/shaders/lightshader.vert",
                                                 "./data/shaders/lightshader.frag", shader_type::lit),},
                {"basic", std::make_shared<Shader>("./data/shaders/basicshader.vert",
                                                   "./data/shaders/basicshader.frag", shader_type::basic)},
                {"skybox", std::make_shared<Shader>("./data/shaders/skybox.vert",
                                                   "./data/shaders/skybox.frag", shader_type::skybox)},
                {"interface", std::make_shared<Shader>("./data/shaders/basicshader.vert",
                                                   "./data/shaders/basicshader.frag", shader_type::interface)}}
{
    /* SET ACTIVE CAMERA AND CONTROLLER TYPE 
     * ADD ACTIVE CAMERAS HERE. */
    scene->addActiveCamera(scene->getCameras()[0]);
    scene->getActiveCameras()[0].lock()->setWindowSize(window().size());
    controls->bindCamera(scene->getActiveCameras()[0].lock()->getNode());
}

Simulator::~Simulator() {}
  
void Simulator::update()
{
    /* Update the state (i.e., transform objects, create/destroy objects, ... ) */
    
    // scene->findCameras(scene->getScene());
    scene->findLights(scene->getScene());
    scene->updateCameraAxesPosition();
    controls->processInput(scene, keyboard(), timer(), window());
    controls->processMouse(mouse(), window(), editor->getEditorRunning());

    editor->update();
}

void Simulator::present()
{
    /* Present the state to the user (i.e., render objects) */

    show_ui(window(), editor->getUIData(), timer().passed_seconds());
    show_edit_error_msg(window(), editor->getUIData(), timer().passed_seconds());

    for (auto &active_cam : scene->getActiveCameras())
    {
        if (window().is_resized())
        {
            active_cam.lock()->setWindowSize(window().size());
        }
        gfx_draw(my_shaders, scene->getLights(), active_cam.lock(), scene->getSkybox(), scene->getScene(), gfx_context);
    }
}

}
