#ifndef TREE_NODE_HPP
#define TREE_NODE_HPP

#include "Body.hpp"
#include "Box.hpp"
#include "Tree.hpp"
#include "BarnesHutTree.hpp"
#include <cstdlib>
#include <vector>

namespace nbody {
	//class for storing node information
	class Node {
		friend class Tree;
		friend class BarnesHutTree;
	protected:
		Box bb;
		std::vector<Body> bodies;
		Node* prev{ this };
		Node* next{ this };
		Node* nextSibling{ nullptr };
		Node* prevSibling{ nullptr };
		Node* afterSubtree{ nullptr };
		bool leaf{ true };
		Tree* tree{ nullptr };
		Body representative;
	public:
		Node(Tree* _tree);
		virtual ~Node() = default;
		virtual bool isSplitable() const;
		virtual void extendBBforBodies();
		virtual void extendBBtoCube();
		virtual Box getBB() const;
		virtual void setBB(const Box& bb_);
		virtual std::vector<Body> getBodies() const;
		virtual void insertBefore(Node* node);
		virtual void insertAfter(Node* node);
		virtual void unlink();
		virtual void update();
		virtual double getL() const;
		virtual bool isCorrect() const;
		virtual void print(std::size_t parallelId) const;
		virtual bool sufficientForBody(const Body& body) const;
		virtual bool sufficientForBox(const Box& box) const;
		virtual void setBodies(const std::vector<Body>& bodies_);
		virtual void setBodies(std::vector<Body>&& bodies_);
		virtual void extractLocalBodiesTo(std::vector<Body>& result);
	};
} // namespace nbody

#endif
