#pragma once

#include "Sprite.hpp"
#include "interfaces/ITexture.hpp"
#include "Types.hpp"
#include "Vector2.hpp"
#include "interfaces/ITextureHelper.hpp"

#define FREEIMAGE_LIB
#include "FI/FreeImage.h"

namespace TSE
{
    class Texture : public ITexture
    {
    protected:
        uint TextureID = 0;
        Vector2 Size;
        uint Bpp;
        byte chanels = 0;
        FIBITMAP* bmp = nullptr;
        byte* imagePtr = nullptr;

    public:
        string name = "Unnamed";
        inline static ITextureHelper* helper = nullptr;

        Texture(const string& path);
        Texture(const int& width, const int& height, int bpp = 32);
        Texture(const Vector2& size, int bpp = 32);
        ~Texture();

        uint bpp() const;
        Vector2 size() const override;
        float Width() const override;
        float Height() const override;
        byte Chanels() const;
        byte* GetImagePtr() const;
        void SetPixel(const Vector2& pos, const Color& c);
        void GetPixel(const Vector2& pos, Color& c) const;
        Texture CutOut(const Vector2& pos, Vector2& size) const;
        void PasteIn(const Vector2& pos, Texture& t);
        void SetPixelNoApply(const Vector2& pos, const Color& c);
        void ToSprite(Sprite& s);
        void SetChanels(const byte& ch);
        uint GetTextureId() const override;
        void SetTextureId(uint id);
        void SetPixel(const int& x, const int& y, const Color& c);
        void GetPixel(const int& x, const int& y, Color& c) const;
        void Fill(const Color& c);
        void SetPixelNoApply(const int& x, const int& y, const Color& c);
        void AddPixelNoApply(const int& x, const int& y, const Color& c);
        void Recreate(const int& x, const int& y, const int& bpp, const int& chanels);
        void SavePNG(const std::string& path) const;
        byte* getPixelPointer(const int& x, const int& y) const;
        static void makeError(Texture& tex);

        void bind() const;
        void unbind() const;
        void Apply();
        void regist();
        void PlatformDestroy();
    };
} // namespace TSE
