
#ifndef DATETIME_H
#define DATETIME_H

#include "common.h"

namespace dv_time
{
	// ################################################################################################

	class datetime
	{
	private:
		double datetime_;
	public:
		/// Konstruktor, nastavi nulovy cas.
		datetime(void);

		/// Konstruktor, nastavi cas na dt
		datetime(double datetime);

		/// Prirazovaci operator
		datetime& operator=(const datetime& other);

		/// Scitaci operator, secte dve data a vyda vysledek
		const datetime operator+(const datetime& other) const;
		/// Odecitaci operator, odecte dve data a vyda vysledek
		const datetime operator-(const datetime& other) const;

		/// Nasobici operator
		const datetime operator*(const double other) const;
		const datetime operator*(const unsigned long long other) const;
		/// Delici operator
		const double operator/(const datetime& other) const;
		const datetime operator/(const double other) const;
		const datetime operator/(const unsigned long long other) const;

		datetime& operator+=(const datetime& other);
		datetime& operator-=(const datetime& other);
		datetime& operator*=(const datetime& other);

		bool operator==(const datetime& other) const;
		bool operator!=(const datetime& other) const;

		bool operator<(const datetime& other) const;
		bool operator>(const datetime& other) const;
		bool operator<=(const datetime& other) const;
		bool operator>=(const datetime& other) const;

		operator double() const;

		static const datetime nanosecond(void);
		static const datetime microsecond(void);
		static const datetime millisecond(void);
		static const datetime second(void);
		static const datetime minute(void);
		static const datetime hour(void);
		static const datetime day(void);
		static const datetime month(void);
		static const datetime year(void);

		datetime& incYear(int years);
		datetime& incMonth(int months);
		datetime& incDay(int days);
		datetime& incHour(int hours);
		datetime& incMinute(int minutes);
		datetime& incSecond(int seconds);
		datetime& incMillisecond(int milliseconds);

		datetime& decYear(int years);
		datetime& decMonth(int months);
		datetime& decDay(int days);
		datetime& decHour(int hours);
		datetime& decMinute(int minutes);
		datetime& decSecond(int seconds);
		datetime& decMillisecond(int milliseconds);

	};

	// ################################################################################################

	datetime encodeDate(int year, int month, int day);
	datetime encodeTime(int hours, int minutes, int seconds, int milliseconds);
	datetime encodeDateTime(int year, int month, int day, int hours, int minutes, int seconds, int milliseconds);
	datetime encodeSeconds(unsigned long long seconds);

	void decodeTime(const datetime& t, int& hours, int& minutes, int& seconds, int& milliseconds);
	void decodeDate(const datetime& t, int& year, int& month, int& day);
	void decodeDateTime(const datetime& t, int& year, int& month, int& day, 
		int& hours, int& minutes, int& seconds, int& milliseconds);
	void decodeTime(const datetime* t, int* hours, int* minutes, int* seconds, int* milliseconds);
	void decodeDate(const datetime* t, int* year, int* month, int* day);
	void decodeDateTime(const datetime* t, int* year, int* month, int* day, 
		int* hours, int* minutes, int* seconds, int* milliseconds);

	bool isLeapYear(int year);

	// ################################################################################################

	datetime datediff(const datetime& d1, const datetime& d2);

	// ################################################################################################

	long long yearsBetween			(const datetime& d1, const datetime& d2);
	long long monthsBetween			(const datetime& d1, const datetime& d2);
	long long daysBetween			(const datetime& d1, const datetime& d2);
	long long hoursBetween			(const datetime& d1, const datetime& d2);
	long long minutesBetween		(const datetime& d1, const datetime& d2);
	long long secondsBetween		(const datetime& d1, const datetime& d2);
	long long millisecondsBetween	(const datetime& d1, const datetime& d2);

	// ################################################################################################

	long long yearsBegunBetween			(const datetime& d1, const datetime& d2);
	long long monthsBegunBetween		(const datetime& d1, const datetime& d2);
	long long daysBegunBetween			(const datetime& d1, const datetime& d2);
	long long hoursBegunBetween			(const datetime& d1, const datetime& d2);
	long long minutesBegunBetween		(const datetime& d1, const datetime& d2);
	long long secondsBegunBetween		(const datetime& d1, const datetime& d2);
	long long millisecondsBegunBetween	(const datetime& d1, const datetime& d2);

	// ################################################################################################

	long long yearsOf			(const datetime& dt);
	long long monthsOf			(const datetime& dt);
	long long daysOf			(const datetime& dt);
	long long hoursOf			(const datetime& dt);
	long long minutesOf			(const datetime& dt);
	long long secondsOf			(const datetime& dt);
	long long millisecondsOf	(const datetime& dt);

	// ################################################################################################

	datetime now(void);

}

#endif