#pragma once

#include <string>

class Date {
public:
    Date(int year, int month, int day) : y(year), m(month), d(day) {}

    bool IsLeap() const {
         return !(y % 400) || (!(y % 4) && y % 100);
    }

    int DaysLeft(const Date& date) const {
        int ineq = 0;
        int im = date.m;

        if (date.y > y) {
            ineq += 365;
            if (IsLeap()) {
                ineq++;
            }
        }

        while (im > 1 && im > m) {
            ineq += this->md[im - 1];
            if (im - 1 == 2 && date.y == y && IsLeap()) {
                ineq++;
            }
            im--;
        }

        if (date.d > d) {
            ineq += date.d - d;
        }

        return ineq;
    }

    std::string ToString() const {
        std::string sd = std::to_string(d);
        std::string sm = std::to_string(m);
        std::string sy = std::to_string(y);

        if (sd.size() < 2) {
            sd = "0" + sd;
        }

        if (sm.size() < 2) {
            sm = "0" + sm;
        }

        if (sy.size() < 4) {
            while (sy.size() < 4) {
                sm = "0" + sm;
            }
        }

        return sd + "." + sm + "." + sy;
    }

    Date DaysLater(int days) const {
        Date dest(y, m, d);

        if ((!IsLeap() && days >= 365) || (IsLeap() && days >= 366)) {
            dest.y++;
            days -= 365;
            if (IsLeap()) {
                days--;
            }
        }

        while (md[dest.m] <= days) {
            days -= md[dest.m];
            if (dest.m == 2 && dest.y == y && IsLeap()) {
                days--;
            }
            dest.m++;
        }
        dest.d = d + days;

        return dest;
    }

    int md[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int d;
    int m;
    int y;
};