#ifndef PROGRESS_ARRAY_H
#define PROGRESS_ARRAY_H

#pragma once

#include "labeled_progress.h"
#include "ros_bridge/rapidjson/include/rapidjson/document.h"

#include <QVector>

namespace ros_bridge {
//! @brief Namespace containing classes and methodes ros message generation.
namespace messages {
//! @brief Namespace containing classes and methodes for geometry_msgs
//! generation.
namespace nemo_msgs {
//! @brief Namespace containing methodes for nemo_msgs/progress_array message
//! generation.
namespace progress_array {

std::string messageType();

namespace {
const char *progressArrayKey = "progress_array";
} // namespace

//! @brief C++ representation of nemo_msgs/progress_array message
template <template <class, class...> class Container = QVector>
class GenericProgressArray {
public:
  typedef Container<labeled_progress::LabeledProgress> ContainerType;
  GenericProgressArray() {}

  ContainerType &progress_array() { return _progres_array; }

  const ContainerType &progress_array() const { return _progres_array; }

  void setProgressArray(const ContainerType &c) { _progres_array = c; }

protected:
  Container<labeled_progress::LabeledProgress> _progres_array;
};

typedef GenericProgressArray<> ProgressArray;

template <class Array>
bool toJson(const Array &array, rapidjson::Value &value,
            rapidjson::Document::AllocatorType &allocator) {
  rapidjson::Value jsonArray(rapidjson::kArrayType);
  for (const auto &lp : array.progress_array()) {
    rapidjson::Value jsonLp;
    if (labeled_progress::toJson(lp, jsonLp, allocator)) {
      jsonArray.PushBack(jsonLp, allocator);
    } else {
      return false;
    }
  }
  value.AddMember(rapidjson::Value(progressArrayKey), jsonArray, allocator);
  return true;
}

template <class Array> bool fromJson(const rapidjson::Value &value, Array &p) {
  if (!value.HasMember(progressArrayKey) ||
      !value[progressArrayKey].IsArray()) {
    return false;
  }

  const auto &jsonArray = value[progressArrayKey].GetArray();
  p.progress_array().clear();
  p.progress_array().reserve(jsonArray.Size());
  for (long i = 0; i < jsonArray.Size(); ++i) {
    labeled_progress::LabeledProgress lp;
    if (!labeled_progress::fromJson(jsonArray[i], lp)) {
      return false;
    } else {
      p.progress_array().push_back(lp);
    }
  }

  return true;
}

} // namespace progress_array
} // namespace nemo_msgs
} // namespace messages
} // namespace ros_bridge

#endif // PROGRESS_ARRAY_H
