#pragma once

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

class MeshLoader {
protected:
    std::vector<Node> nodes;
    std::vector<FiniteElement> finiteElements;
    std::vector<BoundaryElement> boundaryElements;

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

    virtual void loadNodes(std::ifstream &) = 0;

    virtual void loadFiniteElements(std::ifstream &) = 0;

    virtual void loadBoundaryElements(std::ifstream &) = 0;

    std::vector<Node> getNodes();

    std::vector<FiniteElement> getFiniteElements();

    std::vector<BoundaryElement> getBoundaryElements();

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

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

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

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

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

    void insertNodes(Node *);

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

    virtual ~MeshLoader() = default;
};

