#pragma once

#include <cstdint>
#include <string>
#include <fstream>

const char PADDING_ZEROES[3] = {0, 0, 0};

#pragma pack(push, 1)
struct BitmapFileHeader {
    char signature[2] = {0, 0};
    uint32_t fileSize = 0;
    uint16_t reserved1 = 0;
    uint16_t reserved2 = 0;
    uint32_t imageDataOffset = 0;
};
#pragma pack(pop)

#pragma pack(push, 1)
struct BITMAPINFOHEADER {
    uint32_t HeaderSize = 0;
    uint32_t BitmapWidth = 0;
    uint32_t BitmapHeight = 0;
    uint16_t ColorPlanes = 0;
    uint16_t BitsPerPixel = 0;
    uint32_t CompressionMethod = 0;
    uint32_t ImageSize = 0;
    int32_t HorizontalPixelPerMetre = 0;
    int32_t VerticalPixelPerMetre = 0;
    uint32_t NumberOfColors = 0;
    uint32_t NumberOfImportantColors = 0;
};
#pragma pack(pop)

#pragma pack(push, 1)
struct Pixel {
    uint8_t r = 0;
    uint8_t g = 0;
    uint8_t b = 0;
};
#pragma pack(pop)

class BMPImage {
    BitmapFileHeader fileHeader;
    BITMAPINFOHEADER infoHeader;
    Pixel **pixelArray;
public:
    BMPImage(BitmapFileHeader &fileHeader, BITMAPINFOHEADER &infoHeader, Pixel **pixelArray);

    [[nodiscard]] const uint32_t &width() const;

    [[nodiscard]] const uint32_t &height() const;

    void write(const std::string &);
};

BMPImage readBMPImage(const std::string &filename);
