#ifndef TEXTURE_H
#define TEXTURE_H

#include "wrapper/GL.h"

struct Texture final {
    struct Format final {
        GL::TextureFormat format;
        bool linear;
        bool depth;

        static Format color8(int channels, bool linear = false);
        static Format float16(int channels, bool linear = false);
        static Format float32(int channels, bool linear = false);
        static Format depth16(bool linear = false);
        static Format depth32(bool linear = false);
        static Format unknown();

    private:
        Format(const GL::TextureFormat& tf, bool linear, bool depth = false);
    };

private:
    Format format;
    GL::Texture texture;
    int maxMipMaps;

    template<int N>
    friend class Framebuffer;

public:
    Texture();
    ~Texture();
    Texture(const Texture& other) = delete;
    Texture(Texture&& other) = delete;
    Texture& operator=(const Texture& other) = delete;
    Texture& operator=(Texture&& other) = delete;

    void init(const Format& format, int maxMipMaps);

    void setNearestFilter();
    void setLinearFilter();
    void setRepeatWrap();
    void setClampWrap();
    void setData(int width, int height, const void* data = nullptr);

    void bindTo(int index = 0) const;

    Error load(const char* path, int maxMipMaps);

private:
    void bind() const;
};

#endif