#include "Image.h"

#include "Color.h"

template<typename T>
Image<T>::Image(unsigned width, unsigned height)
    : mWidth(width),
      mHeight(height)
{

}

template<typename T>
Image<T>::~Image()
{

}

template<typename T>
void Image<T>::initialize()
{
    mData = std::vector<T>(getBytesPerRow()*mHeight, 10);
}

template<typename T>
void Image<T>::setDataItem(std::size_t index, T item)
{
    if(index >= mData.size())
    {
        return;
    }
    mData[index] = item;
}

template<typename T>
void Image<T>::setPixelValue(unsigned idx, unsigned jdx, const Color& color)
{
    if (mData.empty())
    {
        initialize();
    }

    mData[jdx*getBytesPerRow() + idx*3] = static_cast<T>(color.getR());
    mData[jdx*getBytesPerRow() + idx*3 + 1] = static_cast<T>(color.getG());
    mData[jdx*getBytesPerRow() + idx*3 + 2] = static_cast<T>(color.getB());
}

template<typename T>
std::unique_ptr<Image<T> > Image<T>::Create(unsigned width, unsigned height)
{
    return std::make_unique<Image<T> >(width, height);
}

template<typename T>
unsigned Image<T>::getBytesPerRow() const
{
    const auto bitsPerEntry = mBitDepth <= 8 ? 1 : 2;
    return mWidth * mNumChannels *bitsPerEntry;
}

template<typename T>
unsigned Image<T>::getWidth() const
{
    return mWidth;
}

template<typename T>
unsigned Image<T>::getHeight() const
{
    return mHeight;
}

template<typename T>
unsigned Image<T>::getBitDepth() const
{
    return mBitDepth;
}

template<typename T>
T Image<T>::getByte(unsigned idx, unsigned jdx) const
{
    return mData[jdx*getBytesPerRow() + idx];
}

template<typename T>
unsigned Image<T>::getNumChannels() const
{
    return mNumChannels;
}

template<typename T>
void Image<T>::setData(const std::vector<T>& data)
{
    mData = data;
}

template<typename T>
void Image<T>::setWidth(unsigned width)
{
    mWidth = width;
}

template<typename T>
void Image<T>::setHeight(unsigned height)
{
    mHeight = height;
}

template<typename T>
void Image<T>::setBitDepth(unsigned bitDepth)
{
    mBitDepth = bitDepth;
}

template<typename T>
void Image<T>::setNumChannels(unsigned numChannels)
{
    mNumChannels = numChannels;
}

template class Image<unsigned char>;
//template class Image<uint8_t>;
