#pragma once
#include "serializer.h"

class Image : public Serializer::Type
{
public:
    std::unique_ptr<uint8_t[]> m_data;
    std::string file_name;
    std::string file_base;
    std::string file_ext;
    int width = 0;
    int height = 0;
    int comp = 4;
    Image() = default;
    Image(const Serializer::VMArray::ImageData& d)
    {
        m_data = std::make_unique<uint8_t[]>(d.size);
        std::copy_n(d.data.get(), d.size, m_data.get());
        width = d.width;
        height = d.height;
        comp = d.comp;
    }
    bool load(std::string filename);
    bool load_file(std::string filename);
    const uint8_t* data() const { return m_data.get(); }
    int size() const { return width * height * comp; }
    bool save_png(const std::string& path) const noexcept;
    bool save_jpg(const std::string& path, int quality) const noexcept;
    void create(int w, int h, uint8_t* data = nullptr)
    { 
        width = w; 
        height = h;  
        comp = 4;
        file_base = file_name = file_ext = "";
        m_data = data ? std::unique_ptr<uint8_t[]>(data) : std::make_unique<uint8_t[]>(size());
    }
    void copy_from(const uint8_t* data)
    {
        std::copy(data, data + size(), m_data.get());
    }
    virtual void destroy()
    {
        width = 0;
        height = 0;
        comp = 0;
        file_base = file_name = file_ext = "";
        m_data.reset();
    }
    void flip();
    // convert to grayscale and set opaque
    void gayscale_alpha();
    void create() { m_data = std::make_unique<uint8_t[]>(size()); }
    Image resize(int w, int h) const;
    Image resize_power2() const;
    Image resize_squared(const glm::u8vec4& bg) const;
    bool read(BinaryStreamReader& r) override;
    void write(BinaryStreamWriter& w) const override;
};

class ImageRef : public Image
{
public:
    ~ImageRef()
    {
        m_data.release();
    }
    virtual void destroy() override
    {
        width = 0;
        height = 0;
        comp = 0;
        file_base = file_name = file_ext = "";
        m_data.release();
    }
};