#include "FrameBuffer.h"
#include <iostream>
#include "Environment.h"

namespace ZL {

    FrameBuffer::FrameBuffer(int w, int h, bool useMipmaps)
        : width(w), height(h), useMipmaps(useMipmaps) {

        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);

        glGenTextures(1, &textureID);
        glBindTexture(GL_TEXTURE_2D, textureID);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

        // Настраиваем фильтрацию
        if (useMipmaps) {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            // Сразу генерируем пустые уровни, чтобы текстура считалась "полной"
            glGenerateMipmap(GL_TEXTURE_2D);
        }
        else {
            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, textureID, 0);

        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
            std::cerr << "Error: Framebuffer is not complete!" << std::endl;
        }

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    FrameBuffer::~FrameBuffer() {
        glDeleteFramebuffers(1, &fbo);
        glDeleteTextures(1, &textureID);
    }

    void FrameBuffer::GenerateMipmaps() {
        if (useMipmaps) {
            glBindTexture(GL_TEXTURE_2D, textureID);
            glGenerateMipmap(GL_TEXTURE_2D);
        }
    }

    void FrameBuffer::Bind() {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glViewport(0, 0, width, height); // Важно: устанавливаем вьюпорт под размер текстуры
    }

    void FrameBuffer::Unbind() {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        // Здесь желательно возвращать вьюпорт к размерам экрана, 
        // например, через Environment::width/height
        glViewport(0, 0, Environment::width, Environment::height);
    }

} // namespace ZL