#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <cmath>
#include <exception>
#include <iostream>

#include <dune/common/exceptions.hh>
// #include <dune/common/parametertree.hh>
// #include <dune/common/parametertreeparser.hh>

#include "../assemblers.hh"
#include "../gridselector.hh"

#include "vtk.hh"

#include "../problem-data/grid/gridconstructor.hh"

#include "../utils/diameter.hh"

size_t const dims = MY_DIM;
size_t const refinements = 5; // FIXME?

int main(int argc, char *argv[]) {
  try {
    // Dune::ParameterTree parset;
    // Dune::ParameterTreeParser::readOptions(argc, argv, parset);

    using GridView = Grid::LeafGridView;
    using MyAssembler = MyAssembler<GridView, dims>;

    GridConstructor<Grid> gridConstructor;
    auto grid = gridConstructor.getGrid();

    // refine uniformly!
    for (size_t refinement = 0; refinement < refinements; ++refinement)
      grid->globalRefine(1);

    double minDiameter = std::numeric_limits<double>::infinity();
    double maxDiameter = 0.0;
    for (auto &&e : elements(grid->leafGridView())) {
      auto const geometry = e.geometry();
      auto const diam = diameter(geometry);
      minDiameter = std::min(minDiameter, diam);
      maxDiameter = std::max(maxDiameter, diam);
    }
    std::cout << "min diameter: " << minDiameter << std::endl;
    std::cout << "max diameter: " << maxDiameter << std::endl;

    auto const leafView = grid->leafGridView();
    auto const leafVertexCount = leafView.size(dims);

    std::cout << "Number of DOFs: " << leafVertexCount << std::endl;

    MyAssembler const myAssembler(leafView);
    MyVTKWriter<typename MyAssembler::VertexBasis,
                typename MyAssembler::CellBasis> const
        vtkWriter(myAssembler.cellBasis, myAssembler.vertexBasis, "obs");
    vtkWriter.writeGrid();
  } catch (Dune::Exception &e) {
    Dune::derr << "Dune reported error: " << e << std::endl;
  } catch (std::exception &e) {
    std::cerr << "Standard exception: " << e.what() << std::endl;
  }
}