#ifndef TREE_HPP
#define TREE_HPP

#include <vector>
#include <cstdlib>
#include <string>
#include <pthread.h>
#include <stack>
#include "Body.hpp"
#include "Box.hpp"

namespace nbody {
	class Node;
	class Simulation;

	//superclass for Barnes-Hut tree
	class Tree {
		friend class Node;
		friend class PthreadSimulation;
		friend class ContinuousPthreadSimulation;
	protected:
		Node* nodes;
		unsigned int maxLeafBodies;
		int parallelId;
		Simulation* simulation;
	public:
		Tree(int parallelId);
		virtual ~Tree();
		virtual void setSimulation(Simulation* simulation);
		virtual void clean();
		virtual void build(const std::vector<Body>& bodies) = 0;
		virtual void build(const std::vector<Body>& bodies, const Box& domain) = 0; //TODO(steinret) dead?
		virtual int numberOfChildren() const = 0;
		virtual size_t numberOfNodes() const;
		virtual bool isCorrect() const;
		virtual void accumulateForceOnto(Body& body);
		virtual void computeForces();
		virtual std::vector<Body> extractLocalBodies();
		virtual std::vector<Body> copyRefinements(const Box& domain) const;
		virtual void rebuild(const Box& domain);
		virtual void rebuild(const Box& domain, const std::vector<Body>& bodies);
		virtual void rebuild();
		virtual Box getRootBB() const;
		virtual void print(int parallelId) const;
		virtual Box advance();
		virtual Box getLocalBB() const;
	};


}

#endif
