#ifndef SRC_CONTACTNETWORKFACTORY_HH
#define SRC_CONTACTNETWORKFACTORY_HH

#include <dune/common/parametertree.hh>

#include "../data-structures/network/contactnetwork.hh"

template <class HostGridType, class VectorType>
class ContactNetworkFactory {
public:
    using ContactNetwork = ContactNetwork<HostGridType, VectorType>;

protected:
    using LeafBody = typename ContactNetwork::LeafBody;
    using FrictionCouplingPair = typename ContactNetwork::FrictionCouplingPair;

    const Dune::ParameterTree& parset_;
    const size_t bodyCount_;
    const size_t couplingCount_;

    std::vector<std::shared_ptr<LeafBody>> bodies_;
    std::vector<std::shared_ptr<FrictionCouplingPair>> couplings_;

    ContactNetwork contactNetwork_;

private:
    virtual void setBodies() = 0;
    virtual void setLevelBodies() = 0;
    virtual void setCouplings() = 0;
    virtual void setLevelCouplings() = 0;
    virtual void setBoundaryConditions() = 0;

public:
    ContactNetworkFactory(const Dune::ParameterTree& parset, size_t bodyCount, size_t couplingCount) :
        parset_(parset),
        bodyCount_(bodyCount),
        couplingCount_(couplingCount),
        bodies_(bodyCount_),
        couplings_(couplingCount_),
        contactNetwork_(bodyCount_, couplingCount_) {}

    void build() {
        setBodies();
        contactNetwork_.setBodies(bodies_);

        setCouplings();
        contactNetwork_.setCouplings(couplings_);

        setLevelBodies();
        setLevelCouplings();

        setBoundaryConditions();      
    }

    ContactNetwork& contactNetwork() {
        return contactNetwork_;
    }
};
#endif