#include "imagebuffer.h"

ImageBuffer::ImageBuffer(size_t buffer_size, QObject *parent) : QObject(parent), buffer_size(buffer_size) {
  buffer.resize(buffer_size);
}

void ImageBuffer::clear() {
  resize(buffer_size);
}

size_t ImageBuffer::capacity() {
  return buffer.capacity();
}

double ImageBuffer::bufferPreassure() {
  double preassure;
  mutex.lock();
  preassure = static_cast<double>(load)/static_cast<double>(buffer.capacity());
  mutex.unlock();
  return preassure * 100;
}

int64_t ImageBuffer::bufferLoad() {
  int64_t l;
  mutex.lock();
  l = load;
  mutex.unlock();
  return l;
}

void ImageBuffer::resize(size_t new_size) {
  mutex.lock();
  buffer_size = new_size;
  buffer.clear();
  buffer.resize(new_size);
  current_read_index = 0;
  current_write_index = -1;
  load = 0;
  mutex.unlock();
}

void ImageBuffer::push(const MyImage &img) {
  mutex.lock();
  static_cast<size_t>(current_write_index) < (buffer.size() - 1) ? current_write_index += 1 : current_write_index = 0;
  buffer[static_cast<size_t>(current_write_index)] = img;
  if (load < static_cast<int64_t>(buffer.capacity()))
    load += 1;
  mutex.unlock();
}

bool ImageBuffer::bufferNotEmpty() {
  bool res;
  mutex.lock();
  res = load > 0;
  mutex.unlock();
  return res;
}

bool ImageBuffer::pop(MyImage &img) {
  bool ret = false;
  mutex.lock();
  if (load > 0) {
     // std::cerr << "Buffer.pop, load: " << load << " read_idx: " << current_read_index << " write_idx: " << current_write_index << std::endl;
    img = buffer[static_cast<size_t>(current_read_index)];
    static_cast<size_t>(current_read_index) < (buffer.capacity() - 1) ? current_read_index += 1 : current_read_index = 0;
    load -= 1;
    ret = true;
  }
  mutex.unlock();
  return ret;
}

bool ImageBuffer::readLast(MyImage &img) {
  bool ret = false;
  mutex.lock();
  if (load > 0) {
    size_t idx;
    if (current_write_index != 0) {
      idx = static_cast<size_t>(current_write_index) - 1;
    } else {
      idx = buffer.capacity() -1;
    }
    img = buffer[idx];
    ret = true;
  }
  mutex.unlock();
  return ret;
}