#ifndef SRC_HDF5_LEVELWRITER_HH
#define SRC_HDF5_LEVELWRITER_HH

#include <dune/fufem/hdf5/file.hh>

#include "hdf5/iteration-writer.hh"
#include "hdf5/time-writer.hh"
#include "hdf5-bodywriter.hh"

template <class ProgramState, class VertexBasis, class GridView>
class HDF5LevelWriter {
public:
    using HDF5BodyWriter = HDF5BodyWriter<ProgramState, VertexBasis, GridView>;
    using VertexCoordinates = std::vector<typename HDF5BodyWriter::VertexCoordinates>;
    using VertexBases = std::vector<const VertexBasis*>;
    using FrictionPatches = std::vector<typename HDF5BodyWriter::FrictionPatches>;
    using WeakPatches = std::vector<typename HDF5BodyWriter::WeakPatches>;

    //friend class HDF5NetworkWriter<ProgramState, VertexBasis, GridView>;

    HDF5LevelWriter(HDF5::Grouplike &file,
             const VertexCoordinates& vertexCoordinates,
             const VertexBases& vertexBases,
             const FrictionPatches& frictionBoundaries,
             const WeakPatches& weakPatches)
      : bodyCount_(vertexCoordinates.size()),
        file_(file),
        iterationWriter_(file_),
        timeWriter_(file_),
        bodyWriters_(bodyCount_) {

        for (size_t i=0; i<bodyCount_; i++) {
            bodyWriters_[i] = std::make_unique<HDF5BodyWriter>(file_, vertexCoordinates[i], *vertexBases[i], frictionBoundaries[i], weakPatches[i]);
        }
    }

    template <class Friction>
    void reportSolution(
            const ProgramState& programState,
            // for the friction coefficient
            Friction& friction) {
        timeWriter_.write(programState);

        for (size_t i=0; i<bodyCount_; i++) {
            bodyWriters_[i]->reportSolution(programState, friction); //TODO
        }
    }

    void reportIterations(
            const ProgramState& programState,
            const IterationRegister& iterationCount) {
        iterationWriter_.write(programState.timeStep, iterationCount);
  }

private:
  const size_t bodyCount_;

  HDF5::Grouplike &file_;

  IterationWriter iterationWriter_;
  TimeWriter<ProgramState> timeWriter_;

  std::vector<std::unique_ptr<HDF5BodyWriter>> bodyWriters_;
};
#endif