#pragma once

#include <string>
#include <algorithm>
#include <unordered_set>
#include <cmath>
#include "DataTypes.h"

class MeshLoader {
private:
    Node makeMiddleNode(unsigned int, unsigned int);

protected:
    std::vector<Node> nodes;
    std::vector<FiniteElement> finiteElements;
    std::vector<FiniteElement> boundaryElements;

public:
    virtual void loadMesh(const std::string &) = 0;

    std::vector<Node> &getNodes();

    std::vector<Node> getNodes() const;

    std::vector<FiniteElement> &getFiniteElements();

    std::vector<FiniteElement> &getBoundaryElements();

    std::vector<unsigned int> getElementsByNodesID(unsigned int, unsigned int, unsigned int);

    std::vector<unsigned int> getElementsByEdge(unsigned int, unsigned int);

    std::unordered_set<unsigned int> getBoundaryNodesByBoundaryID(unsigned int);

    std::vector<unsigned int> getFiniteElementsByAreaID(unsigned int);

    std::vector<unsigned int> getBoundaryElementsByBoundaryID(unsigned int);

    void insertNodesIntoMiddles();

    std::vector<std::unordered_set<unsigned int>> makeVectorOfNeighbours();

    virtual ~MeshLoader() = default;
};

