//
// Created by slinky on 5/11/26.
//

#include "UISceneViewer.h"

#include "GLFW/glfw3.h"

UISceneViewer::UISceneViewer() {
    create_scene_framebuffer();
    resize_scene_framebuffer(1, 1);
}

void UISceneViewer::update(EditorContext& ctx) {
    ImGui::Begin("Scene");

    const ImVec2 viewportSize = ImGui::GetContentRegionAvail();
    if (viewportSize.x > 0.0f && viewportSize.y > 0.0f)
    {
        if (sceneViewportSize.x != viewportSize.x ||
            sceneViewportSize.y != viewportSize.y)
        {
            sceneViewportSize = viewportSize;
            resize_scene_framebuffer((int)sceneViewportSize.x, (int)sceneViewportSize.y);

            ctx.viewportSize = {sceneViewportSize.x, sceneViewportSize.y};
            ctx.viewportAspectRatio = sceneViewportSize.x / sceneViewportSize.y;
        }

        ImGui::Image(
            sceneRenderTexture,
            viewportSize,
            ImVec2(0, 1),
            ImVec2(1, 0)
        );

        bool hovered = ImGui::IsItemHovered();
        if (hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
        {
            capturedMouse = true;
            ctx.sceneViewerFocused = true;

            glfwSetInputMode(ctx.window,
                             GLFW_CURSOR,
                             GLFW_CURSOR_DISABLED);
        }

        if (capturedMouse && ImGui::IsMouseReleased(ImGuiMouseButton_Right))
        {
            capturedMouse = false;
            ctx.sceneViewerFocused = false;

            glfwSetInputMode(ctx.window,
                             GLFW_CURSOR,
                             GLFW_CURSOR_NORMAL);
        }
    }
    ImGui::End();
}

void UISceneViewer::bind_fbo() const {
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}

void UISceneViewer::create_scene_framebuffer() {
    glGenFramebuffers(1, &fbo);
    resize_scene_framebuffer(1, 1);
}

void UISceneViewer::resize_scene_framebuffer(int width, int height) {
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    glGenTextures(1, &sceneRenderTexture);
    glBindTexture(GL_TEXTURE_2D, sceneRenderTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sceneRenderTexture, 0);

    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
