#ifndef BODY_HPP
#define BODY_HPP

#include <vector>
#include <string>
#include <array>
#include <Vec3.hpp>

namespace nbody {
	static const double timestep = 1.0;

	struct Derivative {
		Vec3 dx{};
		Vec3 dv{};
	};

	struct Body {
		Body() = default;
	    Body(const Vec3& position_,
			const Vec3& velocity_,
			const Vec3& acceleration_,
			double mass_,
			bool refinement_,
			std::size_t id_);

		std::size_t id{0};
		Vec3 position{};
		Vec3 velocity{};
		Vec3 acceleration{};
		double mass{0.0};
		bool refinement{false};

		void resetAcceleration();
		Derivative evaluate(double dt, const Derivative& d) const;
		void integrate();
		void accumulateForceOntoBody(const Body& from);
		bool isValid() const;
		void print(std::size_t parallelId) const;
	};

	void printBodies(std::size_t parallelId, const std::vector<Body>& bodies);
	bool valid(const std::vector<Body>& bodies);
	std::vector<Body> dubinskiParse(const std::string& filename);
} // namespace nbody

#endif
