#ifndef BOX_HPP
#define BOX_HPP

#include <vector>
#include <array>
#include <limits> 
#include <Body.hpp>

namespace nbody {
	struct Box {
		using flt_lim = std::numeric_limits<float>;
		std::array<double, 3> min{ {
			flt_lim::max(),
			flt_lim::max(),
			flt_lim::max() }};
		std::array<double, 3> max{{
			flt_lim::min(),
			flt_lim::min(),
			flt_lim::min() }};

		void extendToCube();
		void extendForBodies(const std::vector<Body>& bodies);
		std::vector<Body> extractBodies(std::vector<Body>& bodies) const;
		std::vector<Body> copyBodies(const std::vector<Body>& bodies) const;
		double volume() const;
		double maxSidelength() const;
		bool isCorrectBox() const;
		bool isValid() const;
		void printBB(std::size_t parallelId) const;
		double distanceToPosition(const std::array<double, 3>& position) const;
		double distanceToBox(const Box& box2) const;
		std::vector<Box> octreeSplit() const;
		std::vector<Box> splitLongestSide() const;
		bool contained(const std::array<double, 3>& position) const;
		void extend(const Box& extender);
		void extend(const Body& extender);
	};
	bool isContained(const Body& body, const Box& box);
	bool isContained(const Box& inner, const Box& outer);

} // namespace nbody

#endif
