#include "limits.h"

Limits::Limits() {
  this->minWidth = 0;
  this->maxWidth = 0;
  this->minHeight = 0;
  this->maxHeight = 0;
  this->minGain = 0;
  this->maxGain = 0;
  this->minBright = 0;
  this->maxBright = 0;
}

bool Limits::setWidth(QByteArray &data) {
  if (data.length() == 4) {
    uint8_t tmp[2] = {
        static_cast<uint8_t>(data[0]),
        static_cast<uint8_t>(data[1]),
    };
    this->minWidth = (*reinterpret_cast<uint16_t *>(tmp));

    tmp[0] = static_cast<uint8_t>(data[2]);
    tmp[1] = static_cast<uint8_t>(data[3]);
    this->maxWidth = (*reinterpret_cast<uint16_t *>(tmp));
    return true;
  }
  return false;
}

bool Limits::setHeight(QByteArray &data) {
  if (data.length() == 4) {
    uint8_t tmp[2] = {
        static_cast<uint8_t>(data[0]),
        static_cast<uint8_t>(data[1]),
    };
    this->minHeight = (*reinterpret_cast<uint16_t *>(tmp));

    tmp[0] = static_cast<uint8_t>(data[2]);
    tmp[1] = static_cast<uint8_t>(data[3]);
    this->maxHeight = (*reinterpret_cast<uint16_t *>(tmp));
    return true;
  }
  return false;
}

bool Limits::setBin(QByteArray &data) {
  if (data.length() > 0) {
    this->binSteps.clear();
    for (int i = 0; i < data.length(); i++) {
      this->binSteps.push_back(static_cast<uint8_t>(data[i]));
    }
    return true;
  }
  return false;
}

bool Limits::setSkip(QByteArray &data) {
  if (data.length() > 0) {
    this->skipSteps.clear();
    for (int i = 0; i < data.length(); i++) {
      this->skipSteps.push_back(static_cast<uint8_t>(data[i]));
    }
    return true;
  }
  return false;
}

bool Limits::setGain(QByteArray &data) {
  if (data.length() > 2) {
    this->minGain = static_cast<uint8_t>(data[0]);
    this->maxGain = static_cast<uint8_t>(data[1]);
    this->gainStepSizeReal.clear();
    this->gainLims.clear();
    this->gainStepSize.clear();
    uint8_t tmp[2];
    float step;
    for (int i = 2; i < data.length(); i += 6) {
      tmp[0] = static_cast<uint8_t>(data[i]);
      tmp[1] = static_cast<uint8_t>(data[i + 1]);
      step = static_cast<float>((*reinterpret_cast<uint16_t *>(tmp))) / 10000;
      this->gainStepSizeReal.push_back(step);

      tmp[0] = static_cast<uint8_t>(data[i + 2]);
      tmp[1] = static_cast<uint8_t>(data[i + 3]);
      this->gainStepSize.push_back((*reinterpret_cast<uint16_t *>(tmp)));

      tmp[0] = static_cast<uint8_t>(data[i + 4]);
      tmp[1] = static_cast<uint8_t>(data[i + 5]);
      this->gainLims.push_back((*reinterpret_cast<uint16_t *>(tmp)));
    }
    return true;
  }
  return false;
}

bool Limits::setBright(QByteArray &data) {
  if (data.length() == 2) {
    this->minBright = static_cast<uint8_t>(data[0]);
    this->maxBright = static_cast<uint8_t>(data[1]);
    return true;
  }
  return false;
}

QTextStream &operator<<(QTextStream &out, Limits lim) {
  out << "{\n";
  out << tab << CMOSLimitsMinWidthText << ": " << lim.minWidth << endValue;
  out << tab << CMOSLimitsMaxWidthText << ": " << lim.maxWidth << endValue;
  out << tab << CMOSLimitsMinHeightText << ": " << lim.minHeight << endValue;
  out << tab << CMOSLimitsMaxHeightText << ": " << lim.maxHeight << endValue;
  out << tab << CMOSLimitsMinBrightText << ": " << lim.minBright << endValue;
  out << tab << CMOSLimitsMaxBrightText << ": " << lim.maxBright << endValue;
  out << tab << CMOSLimitsMinGainText << ": " << lim.minGain << endValue;
  out << tab << CMOSLimitsMaxGainText << ": " << lim.maxGain << endValue;
  out << tab << CMOSLimitsGainStepsRText << ":";
  foreach (float d, lim.gainStepSizeReal) { out << " " << d; }
  out << endValue;
  out << tab << CMOSLimitsGainStepsText << ":";
  foreach (uint16_t d, lim.gainStepSize) { out << " " << d; }
  out << endValue;
  out << tab << CMOSLimitsGainLimsText << ":";
  foreach (uint16_t d, lim.gainLims) { out << " " << d; }
  out << endValue;
  out << tab << CMOSLimitsBinText << ":";
  foreach (uint8_t d, lim.binSteps) { out << " " << d; }
  out << endValue;
  out << tab << CMOSLimitsSkipText << ":";
  foreach (uint8_t d, lim.skipSteps) { out << " " << d; }
  out << endValue;
  out << "}";
  return out;
}
