// C++ program calculating the solar position for
// the current date and a set location (latitude, longitude)
// Jarmo Lammi 1999
//
// Code refreshed to work in the newer versions of C++
// ComM_PIled and tested with
// Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
// Target: x86_64-apple-darwin14.0.0
// Jarmo Lammi 4-Jan-2015

#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#include <ctime>

class Sun
{
private:

	static constexpr double TO_DEGS = 180.0/M_PI;
	static constexpr double TO_RADS = M_PI/180.0;
	static constexpr double SUN_DIA = 0.53; //degrees
	static constexpr double AIR_REFRACTION  = 34.0/60.0;

	static constexpr double ARGUMENT_OF_PERIHELION  = 102.9372;
	static constexpr double PLANETARY_AXIAL_TILT  = 23.44;

	class JdTime;

	double latitude_;
	double longetude_;
	double altitude_;

private:

	double nextMeanSolarNoonJD(const JdTime& time);
	double meanSolarAnomaly(double meanSolarNoon);
	double eqOfCenter(double meanSolarAnomaly);
	double eclipticLongitude(double eqOfCenter, double meanSolarAnomaly);
	double solarTransit(double meanSolarNoon, double meanSolarAnomaly, double eclipticLongitude);
	double solarDeclination(double eclipticLongitude);
	double hourAngleAtSunset(double solarDeclination);
	double hourAngle(double localSolarTime);
	double equationOfTime(double meanSolarAnomaly, double eclipticLongitude);
	double localSolarTime(const JdTime& time, double equationOfTime);

public:

	Sun(double latitude, double longitude, double altitude = 0);
	double altitude();
	double maximumAltitude();
	double azimuth();
	double declination();
	std::time_t riseTime();
	std::time_t setTime();
};
