#ifndef orbit
#define orbit

#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
#include "MJD.h"
//p, e, prec, nutatation, omega, tau
struct elements_orbit
{
	//������� � ����� [1]
	double p;  // p - ��������� �������� 
	double e;  // e - ��������������
	double precession; // ������� ����������� ����
	double nutation; // ���������� ������
	double omega;; // omega - ���� ������������ ��������/ �������� ������ �������
	double tau; // tau - 
	friend std::ostream& operator <<(std::ostream& out, const elements_orbit& i_elements_orbit);
	friend std::ofstream& operator <<(std::ofstream& out, const elements_orbit& i_elements_orbit);
};

struct const_elements_ellipse_orbite
{
	double a;  // ������� �������
	double abs_c;  // ����������� ������ ��������
	double b; // ����� �������
	double n;  //  ������� ������� �������� 
	double r_a;  // ���������� �� ������
	double r_p;  // ���������� �� �������
	double T; // ������ ���������
	friend std::ostream& operator <<(std::ostream& out, const const_elements_ellipse_orbite& i_const_elements_ellipse_orbite);
	friend std::ofstream& operator <<(std::ofstream& out, const const_elements_ellipse_orbite& i_const_elements_ellipse_orbite);
};

struct variable_elements_ellipse_orbit
{
	double E;  // ��������������� ��������
	double M;  // ������� ��������
	double nu; //�������� ��������
	double Vr; // ���������� �������� ��������
	double r; //������-������ �� �����
	double u;
	double dnu;
	friend std::ostream& operator <<(std::ostream& out, const variable_elements_ellipse_orbit& i_variable_elements_ellipse_orbit);
	friend std::ofstream& operator <<(std::ofstream& out, const variable_elements_ellipse_orbit& i_variable_elements_ellipse_orbit);
};

struct coordinates
{
	double x;
	double y;
	double z;
	friend std::ostream& operator <<(std::ostream& out, const coordinates& i_coordinates);
	friend std::ofstream& operator <<(std::ofstream& out, const coordinates& i_coordinates);
};

struct speed_components
{
	double v_x;
	double v_y;
	double v_z;
	friend std::ostream& operator <<(std::ostream& out, const speed_components& i_speed_components);
	friend std::ofstream& operator <<(std::ofstream& out, const speed_components& i_speed_components);
};

class Orbit {
private:
	std::ofstream log_coordinates;

	Convert_Time m_time;
	const double  gravitational_parameter_Earth = 398600.4415; //�������������� ��������� ����� ��/�
	elements_orbit m_elements;
	const_elements_ellipse_orbite m_const_ellipse{ 0,0,0,0,0,0,0 };
	variable_elements_ellipse_orbit m_variable_ellipse{ 0,0,0,0,0,0 };
	coordinates m_coordinates{0,0,0};
	speed_components m_speed_components{ 0,0,0 };

	int calculate_E(int accuracy);
	int calculate_const_elements_ellipse();
	int calculate_varible_elements_ellipse(double);
	int calculate_coordinates();
	int calculate_speed_components();

public:
	Orbit(elements_orbit input_elements);
	~Orbit() {
		log_coordinates.close();
	};
	int modulation();
	friend std::ostream& operator <<(std::ostream& out, const Orbit& out_orbit);
	friend std::ofstream& operator <<(std::ofstream& out, const Orbit& out_orbit);
};
#endif