//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: sun.hpp
//      Краткое описание: darkstar sun representation
//

#ifndef DSE_NATURE_SUN_HPP
#define DSE_NATURE_SUN_HPP

#include <Darkstar/common.hpp>
#include <Darkstar/math.hpp>
#include <Darkstar/Kernel/timetable.hpp>

namespace nature
{
	char getGreenwichOffset(const float site_longtitude, const bool is_daylight_saving = false);

	class Sun
	{
	private:
		// the angle between sun and zenith
		float theta_sun;
		// the angle between sun and azimuth, we assume that this angle calculates from south, with
		// positive values corresponds to south-west
		float phi_sun;
		// sun direction as a vector from the center of geosphere to the center of the sun
		math::Vect3 sun_direction;

		// solar declination
		float solar_delta;
		// solar time in minutes
		float solar_time;
		// time of solar sunrise in minutes
		float solar_sunrise;
		// time of solar sunset in minutes
		float solar_sunset;
		// time of solar noon in minutes
		float solar_noon;
		// hour angle as angle in celestial coordinate system
		float hour_angle;
		// equation of time in minutes
		float equation_of_time;
		// time offset between solar time and standard time in minutes
		float time_offset;

		// sun angle offset is offset of the sun in sunrise and sunset time. It appear because
		// our calculations of sun position assume that sun specifies by its center, but 
		// sky model assume that sun specifies by its higher point above earth
		float sun_angle_offset;

		// current date
		ker::Date current_date;
		// current time
		ker::Time current_time;
		// current site longitude in degrees
		float site_longitude;
		// current site latitude in radians
		float site_latitude;
		// current time zone
		char time_zone;
		// is daylight saving
		bool is_daylight_saving;

		void _computeSolarTime();
		void _computeSolarDelta();
		void _computeTimeOffset();
		void _computeEquationOfTime();
		void _computeSunConstants();
		void _computeSolarPosition();
		void _computeSunAngleOffset();
	public:
		Sun();
		Sun(const ker::Date& cur_date, const ker::Time& cur_time, const float site_lat, const float site_long);
		~Sun();

		void setTime(const ker::Time& time);
		void setDate(const ker::Date& date);
		void setTimeAndDate(const ker::Time& time, const ker::Date& date);
		// both, longitude and latitude, are passes in degrees
		void setSiteCoordinates(const float site_longtitude, const float site_latitude, const bool is_daylight_saving = false);

		void setAngles(const float theta_sun, const float phi_sun);

		const float getThetaSun() const;
		const float getPhiSun() const;
		const math::Vect3& getSunDirection() const;

		const float getSunriseTime() const;
		const float getSunsetTime() const;
		const float getSunNoonTime() const;

		const ker::Date& getCurrentDate() const;
		const ker::Time& getCurrentTime() const;
		const float getSiteLongitude() const;
		const float getSiteLatitude() const;
	};
};

#include "sun.inl"

#endif

