#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H

#include <GL/glew.h>

#include "client/rendering/WindowSize.h"
#include "common/utils/Array.h"
#include "common/utils/Types.h"

class Framebuffer final {
public:
    static const uint POSITION = 1;
    static const uint NORMAL = 2;
    static const uint COLOR = 4;
    static const uint RED = 8;
    static const uint DEPTH = 16;

    Framebuffer(const WindowSize& size, uint mode, bool texCompare = false);
    ~Framebuffer();
    Framebuffer(const Framebuffer& other) = delete;
    Framebuffer(Framebuffer&& other) = delete;
    Framebuffer& operator=(const Framebuffer& other) = delete;
    Framebuffer& operator=(Framebuffer&& other) = delete;

    bool hasError() const;
    void bind() const;

    void resize(uint width, uint height) const;

    void bindPositionTexture(uint textureUnit) const;
    void bindNormalTexture(uint textureUnit) const;
    void bindColorTexture(uint textureUnit) const;
    void bindRedTexture(uint textureUnit) const;
    void bindDepthTexture(uint textureUnit) const;

private:
    void genTexture(uint index, uint width, uint height);
    void setupTexture(uint index, uint width, uint height, GLuint* attachments, uint& counter);
    void bindTexture(uint textureUnit, GLuint texture) const;
    const char* getErrorString(GLenum error) const;

    uint mode;
    Array<GLuint, 5> textures;
    GLuint buffer;
    bool error;

    struct Data final {
        uint mask;
        GLint internalFormat;
        GLenum format;
        GLenum type;
    };
    Data data[5];
};

#endif