#pragma once

#include "Point.h"

#include <unordered_map>
#include <string>
#include <vector>

class Node
{
public:

    enum class State
    {
        HEALTHY,
        DIRTY
    };

    Node(const Point& p, unsigned index = 0);

    static std::unique_ptr<Node> Create(const Point& p, unsigned index = 0);

    ~Node();

    void associateEdge(unsigned edgeId);

    void associateFace(unsigned faceId);

    void addVectorAttribute(const std::string& tag, const std::vector<double>& values);

    void clearConnectivity();

    unsigned getIndex() const;

    unsigned getNumConnectedEdges() const;

    unsigned getNumConnectedFaces() const;

    unsigned getConnectedEdgeId(std::size_t idx) const;

    unsigned getConnectedFaceId(std::size_t idx) const;

    State getState() const;

    const Point& getPoint() const;

    std::vector<double> getVectorAttribute(const std::string& tag) const;

    bool isCoincident(Node* node) const;

    void setState(State state);

    void setIndex(std::size_t idx);

    void updateIndex(unsigned index);

    void scale(double x, double y);

    void translate(double x, double y, double z = 0.0);

private:
    std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
    unsigned mIndex{0};
    Point mPoint;

    std::vector<unsigned> mAssociatedEdgeIds;
    std::vector<unsigned> mAssociatedFaceIds;

    State mState{State::HEALTHY};
};
