#pragma once

#include "PlatformImage.h"

#include <memory>
#include <vector>

class Color;

class AbstractGrid;
template<typename T>
class Grid;

class Image
{
public:
    enum class DataType
    {
        UCHAR
    };

    using Index = std::pair<std::size_t, std::size_t>;
    using Indices = std::vector<Index>;

    Image(unsigned width, unsigned height, DataType dataType = DataType::UCHAR);
    ~Image();
    static std::unique_ptr<Image> Create(unsigned width, unsigned height, DataType dataType = DataType::UCHAR);

    unsigned getBytesPerRow() const;
    unsigned getWidth() const;
    unsigned getHeight() const;
    unsigned getBitDepth() const;
    unsigned getNumChannels() const;

    AbstractGrid* getGrid() const;

    template<typename T>
    Grid<T>* getGridT() const;

    DataType getType() const;
    PlatformImage* getPlatformImage();

    void setPixelValues(const Indices& indices, const std::vector<Color>& colors);
    void setWidth(unsigned width);
    void setHeight(unsigned height);
    void setBitDepth(unsigned bitDepth);
    void setNumChannels(unsigned numChannels);

private:
    void initialize();
    unsigned mWidth{1};
    unsigned mHeight{1};
    unsigned mBitDepth{8};
    unsigned mNumChannels{4};

    DataType mDataType;
    std::unique_ptr<AbstractGrid> mData;
    std::unique_ptr<PlatformImage> mPlatformImage;
};
