/**
 *  \brief     Node class.
 *  \details   Used to store properties of the node
 *  \author    vadims
 *  \date      May 10, 2017
 *  \bug       Not all memory is freed when deleting an object of this class.
 *  \warning   Improper use can crash your application
 *  \copyright CENOS LLC
 */

#ifndef NODE_H
#define NODE_H

class Element;

#include <vector>
#include <iostream>
//#include "Element.hpp"
//#include "ElementTypes.hpp"

class Node
{
private:
	int id; ///< Node Id
	double xCoordinate; ///< Node x coordinate
	double yCoordinate; ///< Node y coordinate
	double zCoordinate; ///< Node z coordinate
	std::vector<std::weak_ptr<Element>> ownerElements; ///< Node owner elements.
	bool is_midside;

public:
	/// @brief Node constructor
	Node(int, double, double, double);

	/// @brief Node copy constructor
	Node(const Node& that);

    ~Node() { };
	bool operator==(const Node& rhs) const;
	bool operator!=(const Node& rhs) const;
	bool operator < (const Node& rhs) const;

	/// Get Node Id
    int getId(); 

	/// Get Node x coordinate
	double x();

	/// Get Node y coordinate
	double y();

	/// Get Node z coordinate
	double z();

	/// Get Node coordinates as a vector
	std::vector<double> getCoordinates();

	/// Add Node owner elements
    void addOwnerElement(std::shared_ptr<Element>);

	/// Get Node owner elements
	std::vector<std::shared_ptr<Element>> getOwnerElements();

	/// check if node is midside node (higher order elements)
	bool isMidsideNode();

	// since it is impossible to determinde whether node is midside at construction time,
	// it is required to set it later
	void setMidside(bool);

};

typedef std::shared_ptr<Node> Node_;

#endif /* NODE_H */
