#include <iostream>
#include <stdio.h>
using namespace std;

struct Date {
	int day;
	int month;
	int year;
};

const int MONTH_LIMIT = 12;

Date createDate(int day, int month, int year) {
	Date newDate = {day, month, year};
	return newDate;
}

/**
 *	The date is inputed as a string in format
 *	dd.mm.yyyy and is automatically parsed by
 *  scanf.
 */
Date inputDate() {
	printf("Input a date: ");
	int day, month, year;
	scanf("%d.%d.%d", &day, &month, &year);

	// Input validation could be applied here.
	return createDate(day, month, year);
}

void printDate(Date date) {
	printf("%02d.%02d.%04d", date.day, date.month, date.year);
}

bool isDateSmaller(Date left, Date right) {
	if(left.year != right.year)
		return left.year < right.year;
	if(left.month != right.year)
		return left.month < right.month;
	return left.day < right.month;
}

bool operator < (Date left, Date right) {
	return isDateSmaller(left, right);
}

int getDayLimit(int month, int year) {

	// Magic numbers reduced to minimum
	const int DAFAULT_DAY_LIMIT = 31;
	const int SHORT_DAY_LIMIT = 30;
	const int FEBRUARY_DAY_LIMIT = 28;

	bool isLeapYear = (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
	int dayLimit = DAFAULT_DAY_LIMIT;
	switch(month) {
		case 2:
			dayLimit = FEBRUARY_DAY_LIMIT + isLeapYear;
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			dayLimit = SHORT_DAY_LIMIT;
			break;
	}

	return dayLimit;
}

Date nextDate(Date date) {

	// date is a copy of the original Date, so it's ok to modify it
	int dayLimit = getDayLimit(date.month, date.year);
	if(date.day <= dayLimit) {
		return date;
	}
	++date.month;
	date.day = 1;
	if(date.month > MONTH_LIMIT) {
		++date.year;
		date.month = 1;
	}

	return date;
}

Date theDateAfterNdays(Date date, int n) {

	// again, date is copy of the original
	for(int i = 0; i < n; ++i) {
		date = nextDate(date);
	}

	return date;
}

Date operator + (Date date, int n) {
	return theDateAfterNdays(date, n);
}

void sortDates(Date dates[], int count) {

	// A nice bubble sort here (:
	for(int i = count - 1; i > 0; --i) {
		bool isChanged = false;
		for(int j = 0; j < i; ++j) {
			if(dates[j + 1] < dates[j]) {
				swap(dates[j], dates[j + 1]);
				isChanged = true;
			}
		}
		if(!isChanged) {
			break;
		}
	}
}

int main() {
	
	const int DATES_COUNT = 5;
	Date dates[DATES_COUNT];
	
	cout << "You will now input " << DATES_COUNT << " dates: " << endl;
	for(int i = 0; i < DATES_COUNT; ++i) {
		dates[i] = inputDate();
	}

	sortDates(dates, DATES_COUNT);

	cout << "Printing the sorted sequence:" << endl;
	for(int i = 0; i < DATES_COUNT; ++i) {
		printDate(dates[i]);
		cout << endl;
	}
	cout << endl;
	return 0;
}
