#ifndef TEXTURE_2D
#define TEXTURE_2D

#include <iosfwd>
#include <fstream>
#include <string>
#include <memory>

#include "../math/math.h"
#include "../math/pixel.h"

namespace sleek
{
    namespace device
    {
        class Device;
    }
    namespace driver
    {
        enum TextureFormat : u8
        {
            TXFMT_LUMINANCE = 1,
            TXFMT_LUMINANCE_ALPHA = 2,
            TXFMT_RGB = 3,
            TXFMT_RGBA = 4,

            TXFMT_LUMINANCE_32F = 5,
            TXFMT_LUMINANCE_ALPHA_32F = 6,
            TXFMT_RGB_32F = 7,
            TXFMT_RGBA_32F = 8
        };
        class context;
        class identifier;
        class texture : public std::enable_shared_from_this<texture>
        {
            public:
                texture(const math::vec2i &s, const TextureFormat a = TXFMT_RGBA) noexcept;
                virtual ~texture() noexcept;

                inline std::shared_ptr<texture> getptr() noexcept
                {
                    return shared_from_this();
                }

                //! if floating texture, pixel is a ptr to the data
                virtual void setPixel(const math::vec2i &, const math::pixel&) noexcept;

                //! if floating texture, pixel is a ptr to the data
                virtual math::pixel getPixel(const math::vec2i&) const noexcept;

                virtual void createIdentifier(context*) noexcept;
                virtual void setIdentifier(std::shared_ptr<identifier>) noexcept;

                virtual math::vec2i getOriginalSize() const noexcept;

                virtual TextureFormat getFormat() const noexcept;
                virtual u8 getComposantCount() const noexcept;
                virtual u8 getPitch() const noexcept;

                virtual std::shared_ptr<identifier> getIdentifier() const noexcept;

                virtual texture *clone() const noexcept;

                virtual u32 getBufferSize() const noexcept;
                virtual u8* getBuffer() const noexcept;

                // tool for texture loader
                void flipVertical() noexcept;

                // tool for texture loader
                void flipHorizontal() noexcept;

                // tool for texture loader
                void flipDual() noexcept;

                // tool for texture loader
                void monochrome() noexcept;

                // tool for texture loader
                void invertColor() noexcept;
            protected:
                std::shared_ptr<identifier> gpu;
            private:
                u8 *buffer;
                std::string filename;
                math::vec2i original;
                TextureFormat fmt;
                u8 component;
                u8 pitch;
        };
    }
}

#endif