#include <stdio.h>
#include <time.h>

int month;
int year;
int decade;
int counter;
int offset;
int months[14][42];
char *names[] = { "DECEMBER ", " JANUARY ", "FEBRUARY ", "  MARCH  ", "  APRIL  ", 
	"   MAY   ", "  JUNE   ", "  JULY   ", " AUGUST ", "SEPTEMBER", 
	" OCTOBER ", "NOVEMBER ", "DECEMBER ", " JANUARY "};
static int days_of_month[2][15] = {
	{31, 31, 28, 31, 30,31,30,31,31,30,31,30,31,31},
	{31, 31, 29, 31, 30,31,30,31,31,30,31,30,31,31} };

main(argc, argv)
int argc;
char *argv[];
{
	int fdo_year;		/* first day of year	*/
	int fdo_month;		/* first day of month	*/
	int i, leap;
	int k, j, l;

	get_opt(argc, argv);
	offset = (year - 1600) % 400;
	if (offset < 0)
	{
		fprintf(stderr, "%s: cannot determine calendar of year before 1600 AD\n", argv[0]);
		exit(0);
	}
	counter = 6;	/* day of week of January 1, 1600 (Saturday)	*/
	for (i = 0; i < offset; i++)
	{
		if ((i == 0) || (((i % 4) == 0) && ((i % 100) != 0)))
			counter += 2;
		else
			counter++;
	}
	fdo_month = fdo_year = counter % 7;
	leap = (((year % 400) == 0) || (((year % 4) == 0) && ((year % 100) != 0)));
	for (i = 0; i < 14; i++)
	{
		if (i == 0)
			fdo_month = ((fdo_year - 3) + 7) % 7;
		for (k = 0; k < fdo_month ; k++)
			months[i][k] = 0;
		for (k = fdo_month, j = 1; k < (fdo_month + days_of_month[leap][i]); k++, j++)
			months[i][k] = j;
		for (k = fdo_month + days_of_month[leap][i]; k < 42; k++)
			months[i][k] = 0;
		fdo_month = (fdo_month + days_of_month[leap][i]) % 7;
	}
	if (month != 0)
		print_month(month);
	else
	{
		for (month = 1; month < 13; month++)
			print_month(month);
	}
}

get_opt(argc, argv)
int argc;
char *argv[];
{
	int i, j;
	char *string;
	long time_info;		/* number of seconds since January 1, 1970	*/
	struct tm *time_struct;

	for (i = 1; i < argc; i++)
	{
		string = argv[i];
		j = atoi(string);
		if (j > 12)
			year = j;
		else
			month = j;
	}
	if ((year == 0) && (month == 0))
	{
		time_info = time(0);
		time_struct = localtime(&time_info);
		month = time_struct->tm_mon + 1;
		year = time_struct->tm_year + 1900;
	}
	if ((year == 0) || (month == 0))
	{
		time_info = time(0);
		time_struct = localtime(&time_info);
/*		if (month == 0)
			month = time_struct->tm_mon + 1;*/
		if (year == 0)
			year = time_struct->tm_year + 1900;
	}
}

atoi(string)
char *string;
{
	int i;
	char *temp;

	temp = string;
	i = 0;
	while ((*temp >= '0') && (*temp <= '9'))
	{
		i = (i * 10) + (*temp - '0');
		temp++;
	}
	return(i);
}

print_month(this_month)
int this_month;
{
	int i, j, k, l;

	printf("\n     %s     ", names[this_month-1]);
	printf("            %s %d              ", names[this_month], year);
	printf("     %s     \n", names[this_month+1]);
	printf(" S  M  T  W  T  F  S");
	printf("                                      ");
	printf(" S  M  T  W  T  F  S\n");
	for (k = 0; k < 42; k += 7)
	{
		for (j = 0; j < 7; j++)
		{
			if (months[this_month-1][k+j] == 0)
				printf("   ");
			else if (months[this_month-1][k+j] < 10)
				printf(" %d ", months[this_month-1][k+j]);
			else
				printf("%2d ", months[this_month-1][k+j]);
		}
		printf("                                     ");
		for (j = 0; j < 7; j++)
		{
			if (months[this_month+1][k+j] == 0)
				printf("   ");
			else if (months[this_month+1][k+j] < 10)
				printf(" %d ", months[this_month+1][k+j]);
			else
				printf("%2d ", months[this_month+1][k+j]);
		}
		putchar('\n');
	}
	for (k = 0; k < 42; k += 7)
	{
		putchar('+');
		for (i = 0; i < 7; i++)
			printf("----------+");
		printf("\n|");
		for (j = 0; j < 7; j++)
		{
			if (months[this_month][k+j] == 0)
				printf("   ");
			else if (months[this_month][k+j] < 10)
				printf(" %d ", months[this_month][k+j]);
			else
				printf("%2d ", months[this_month][k+j]);
			printf("       |");
		}
		putchar('\n');
		for (i = 0; i < 7; i++)
		{
			putchar('|');
			for (j = 0; j < 7; j++)
				printf("          |");
			putchar('\n');
		}
	}
	putchar('+');
	for (i = 0; i < 7; i++)
		printf("----------+");
	printf("\n\f\n");
}
