#define _CRT_SECURE_NO_WARNINGS
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define WEEK	"日 月 火 水 木 金 土"
#define COL	24

char disp[8][80];

void strfmt(void* dest, char* fmt, int i)
{
	char		buf[8];

	sprintf(buf, fmt, i);
	memcpy(dest, buf, strlen(buf));
}

void calsub(int year, int month, int col)
{
	struct tm	tm;
	struct tm*	ptm;
	time_t		timer;
	int		line;
	int		i;

	if (month < 1) {
		year--;
		month += 12;
	}
	if (12 < month) {
		year++;
		month -= 12;
	}
	strfmt(disp[0] + col * COL, "%d", year);
	strfmt(disp[0] + col * COL + 8, "%d月", month);
	memcpy(disp[1] + col * COL, WEEK, strlen(WEEK));

	memset(&tm, 0, sizeof tm);
	tm.tm_year	= year - 1900;
	tm.tm_mon	= month - 1;
	tm.tm_mday	= 1;
	timer = mktime(&tm);
	line = 2;
	for (i = 1; i <= 31; i++) {
		ptm = localtime(&timer);
		if (ptm->tm_mon != month - 1) {
			break;
		}
		if (ptm->tm_wday == 0 && 1 < i) {
			line++;
		}
		strfmt(disp[line] + col * COL + ptm->tm_wday * 3, "%2d", i);
		timer += 24 * 60 * 60;
	}
}

void cal(int year, int month)
{
	int		i;

	for (i = 0; i < 8; i++) {
		memset(disp[i], ' ', 79);
		disp[i][79] = '\0';
	}
	calsub(year, month - 1, 0);
	calsub(year, month, 1);
	calsub(year, month + 1, 2);
	for (i = 0; i < 8; i++) {
		printf("%s\n", disp[i]);
	}
}

int main()
{
	time_t		timer;
	struct tm*	ptm;
	int		year;
	int		month;
	int		ch;
	int		flag;

	time(&timer);
	ptm = localtime(&timer);
	year = ptm->tm_year + 1900;
	month = ptm->tm_mon + 1;
	while (1) {
		cal(year, month);
		printf("ESCキーで終了\n");
		do {
			ch = _getch();
			flag = 0;
			switch (ch) {
			case 0x1b:	// ESC
				return 0;
			case 0x48:	// up
				month -= 3;
				break;
			case 0x49:	// PageUp
				year--;
				break;
			case 0x4b:	// left
				month--;
				break;
			case 0x4d:	// right
				month++;
				break;
			case 0x50:	// down
				month += 3;
				break;
			case 0x51:	// PageDown
				year++;
				break;
			case 0xe0:
			default:
				flag = 1;
			}
		} while (flag);
		if (month < 1) {
			year--;
			month += 12;
		}
		if (12 < month) {
			year++;
			month -= 12;
		}
	}
	return 0;
}
