#pragma once

#include <vectors/vec2.h>
#include "glTexture.h"
#include "raw.h"
#include "../object.h"
#include <memory>

namespace render{

enum tex_type
{
    t_ubyte = 0x1401,
    t_byte  = 0x1400,
    t_float = 0x1406
};

enum tex_format
{
    f_red  = 0x1903,
    f_rg   = 0x8227,
    f_rgb  = 0x1907,
    f_rgba = 0x1908
};

enum tex_mode
{
    m_texture2d = 0x0DE1,
    m_texture2d_rect = 0x84F5,
    m_texture2d_multisample = 0x9100
};

namespace tex_parameteri
{
    enum wrap
    {
        w_repeat = 0x2901,
        w_clamp = 0x2900,
        w_clamp_to_edge = 0x812F
    };

    enum filter
    {
        f_nearest = 0x2600,
        f_linear  = 0x2601
    };

    enum param
    {
        p_wrap_t = 0x2803,
        p_wrap_s = 0x2802
    };
}

class texture: public _object
{
public:
    texture();
    texture(const std::string &path, bool filter = 0, bool flip = 0);
    ~texture();

    virtual bool load(const std::string &path, bool filter = 0, bool flip = 0);
    void create(const vec2u32& size, bool filter = 0);


    void data(const vec2u32 &size, void*data);
    void subData(const vec2u32 &size, void*data);

    virtual void free();

    void parameteri(uint32_t, uint32_t);

    void bind(uint32_t slot = 0) const;
    void unbind(int slot = -1);

    const vec2u32 &size() const noexcept;

    uint32_t getGLTexture();
    uint32_t getMode();

    inline const std::string &name() const noexcept;

    tex_type type;
    tex_format format;
    tex_mode mode;
protected:
    std::string _name;
    void _alloc();
    vec2u32 _size;
    std::shared_ptr<__glTexture> _obj;
    rawImage img;
};


}
