#ifndef IMAGE_H
#define IMAGE_H
#include <QObject>
enum Color { r, g, b };
class Image {
public:
  Image(bool colors, uint32_t width, uint32_t height,
        std::vector<uint8_t> data);
  Image(bool colors, uint32_t width, uint32_t height);
  Image();
  ~Image() {}
  std::vector<uint8_t> *getData() { return &(this->data); }
  uint32_t getWidth() { return this->width; }
  uint32_t getHeight() { return this->height; }
  bool getColors() { return this->rgb; }

  void setData(std::vector<uint8_t> d) { this->data = d; }
  void appendData(std::vector<uint8_t> d) {
    this->data.insert(std::end(this->data), std::begin(d), std::end(d));
  }
  void appendData(uint8_t d) { this->data.push_back(d); }
  void appendData(uint8_t *d, uint32_t length);
  void appendData(const QByteArray &data);
  void appendData(const QByteArray &data, uint32_t length);
  void setWidth(uint32_t w);
  void setHeight(uint32_t h);
  void setColors(bool c);
  void setParams(uint32_t w, uint32_t h, bool c);
  void image2rgb();

  void setDataAt(Color c, uint32_t x, uint32_t y, uint8_t val) {
    data.at(3 * (x + y * this->width) + c) = val;
  }

  void setDataAt(uint32_t x, uint32_t y, uint8_t val) {
    data.at(x + y * this->width) = val;
  }

  void setDataAt(uint32_t pos, uint8_t val) { data.at(pos) = val; }

  void clearData();

  uint8_t operator()(Color c, uint32_t x, uint32_t y) {
    return data.at(3 * (x + y * this->width) + c);
  }

  uint8_t operator()(uint32_t x, uint32_t y) {
    return data.at(x + y * this->width);
  }

  uint8_t operator()(uint32_t pos) { return data.at(pos); }

  void reserve();

private:
  uint32_t width, height;
  bool rgb;
  std::vector<uint8_t> data;
};

#endif // IMAGE_H
