#include "image.h"

using namespace maps::imageutils;

namespace maps::wiki::renderer_overlay {

Image::Image(size_t x, size_t y)
    :image_(FIT_BITMAP, x, y, 32)
{
}

Image::Image(const std::string& data)
    :image_(
        const_cast<BYTE*>(
            reinterpret_cast<const BYTE*>(data.data())), data.size())
{
    if (image_.bitsPerPixel() != 32) {
        image_.convertTo32Bits();
    }
}

size_t
Image::width() const
{
    return image_.width();
}

size_t
Image::height() const
{
    return image_.height();
}

PIXELCOLOR
Image::pixelColor(size_t x, size_t y) const
{
    return
        *(PIXELCOLOR*)(
            image_.scanLine(image_.height() - y - 1)
        + sizeof(PIXELCOLOR) * x);
}

void
Image::setPixelColor(size_t x, size_t y, PIXELCOLOR color)
{
    *(PIXELCOLOR*)(
        image_.scanLine(image_.height() - y - 1)
    + sizeof(PIXELCOLOR) * x) = color;
}

std::string
Image::pngData() const
{
    fipMemoryIO output;
    image_.save(FIF_PNG, output);
    BYTE *data;
    DWORD size;
    output.acquire(&data, &size);
    return std::string(reinterpret_cast<char*>(data), size);
}

void
Image::fitTo(size_t sizeLimit)
{
    if (image_.width() <= sizeLimit &&
        image_.height() <= sizeLimit) {
        return;
    }
    ASSERT(image_.width() && image_.height());
    bool fitX = image_.width() > image_.height();
    size_t newSize = fitX
        ? sizeLimit * image_.height() / image_.width()
        : sizeLimit * image_.width() / image_.height();
    image_.rescale(fitX ? sizeLimit : newSize, fitX ? newSize : sizeLimit, FILTER_BOX);
}

} //namespace maps::wiki::renderer_overlay
