#include "guitools.h"

#include "engine.h"
#include "tools/scenepicker.h"
#include "scene/scenetree.h"

#include <imgui/imgui.h>

#include <SparrowRenderer/mesh.h>
#include <SparrowRenderer/pbrmaterial.h>
#include <SparrowRenderer/deferredpipeline.h>

#include <glm/ext.hpp>

GuiTools::GuiTools() :
    m_pickerNode(new ScenePicker()),
    m_selectedMesh(nullptr),
    m_pickerEnabled(false),
    m_materialEditorEnabled(false)
{
    addChild(m_pickerNode);
    m_pickerNode->setVisible(false);
}

GuiTools::~GuiTools()
{
    delete m_pickerNode;
}

void GuiTools::update()
{
    // no automatic update of children, we want to update them manually
    // ContainerNode::update();

    if(m_pickerEnabled)
        m_pickerNode->update();

    if(m_materialEditorEnabled)
        materialGui();
}

void GuiTools::materialGui()
{
    static int selectedOption = 0;

    ImGui::Begin("Material Editor", &m_materialEditorEnabled);
    std::string options;
    std::vector<Mesh*> meshes;
    options += "None\n";
    meshes.push_back(nullptr);
    int i = 1;
    for(SceneIterator<GeometryNode*>* geometryIt = m_scene->getGeometry(); geometryIt->isValid(); geometryIt->next())
    {
        options += geometryIt->getItem()->mesh->getName();
        options += '\n';
        meshes.push_back(geometryIt->getItem()->mesh);
        if(geometryIt->getItem()->mesh == m_selectedMesh)
            selectedOption = i;
    }

    for(char &c : options)
    {
        if(c == '\n')
            c = '\0';
    }
    if(ImGui::Combo("Mesh", &selectedOption, options.c_str()))
    {
        m_selectedMesh = meshes[selectedOption];
    }

    if(m_selectedMesh == nullptr)
        ImGui::Text("No mesh selected");
    else
    {
        PBRMaterial* mat = dynamic_cast<PBRMaterial*>(m_selectedMesh->getMaterial());
        ImGui::ColorEdit3("albedo", &mat->albedo.r);
        ImGui::ColorEdit3("emission", &mat->emission.r);
        ImGui::SliderFloat("metallic", &mat->metallic, 0, 1);
        ImGui::SliderFloat("roughness", &mat->roughness, 0, 1);
    }

    ImGui::End();
}

void GuiTools::togglePicker()
{
    m_pickerEnabled = !m_pickerEnabled;
    m_pickerNode->setVisible(m_pickerEnabled);
}

void GuiTools::toggleMaterialEditor()
{
    m_materialEditorEnabled = !m_materialEditorEnabled;
}

void GuiTools::toggleRenderingPipelineGui()
{
    DeferredPipeline* pipeline = dynamic_cast<DeferredPipeline*>(m_scene->getPipeline());
    pipeline->toggleDebugGui();
}
