/* See LICENSE file for copyright and license details. */
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "util.h"

enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
enum caltype { JULIAN, GREGORIAN };
enum { TRANS_YEAR = 1752, TRANS_MONTH = SEP, TRANS_DAY = 2 };

static struct tm *ltime;

static int
isleap(size_t year, enum caltype cal)
{
	if (cal == GREGORIAN) {
		if (year % 400 == 0)
			return 1;
		if (year % 100 == 0)
			return 0;
		return (year % 4 == 0);
	}
	else { /* cal == Julian */
		return (year % 4 == 0);
	}
}

static int
monthlength(size_t year, int month, enum caltype cal)
{
	int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	return (month == FEB && isleap(year, cal)) ? 29 : mdays[month];
}

/* From http://www.tondering.dk/claus/cal/chrweek.php#calcdow */
static int
dayofweek(size_t year, int month, int dom, enum caltype cal)
{
	size_t y;
	int m, a;

	a = (13 - month) / 12;
	y = year - a;
	m = month + 12 * a - 1;

	if (cal == GREGORIAN)
		return (dom + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12) % 7;
	else  /* cal == Julian */
		return (5 + dom + y + y / 4 + (31 * m) / 12) % 7;
}

static void
printgrid(size_t year, int month, int fday, int line)
{
	enum caltype cal;
	int offset, dom, d = 0, trans; /* are we in the transition from Julian to Gregorian? */
	int today = 0;

	cal = (year < TRANS_YEAR || (year == TRANS_YEAR && month <= TRANS_MONTH)) ? JULIAN : GREGORIAN;
	trans = (year == TRANS_YEAR && month == TRANS_MONTH);
	offset = dayofweek(year, month, 1, cal) - fday;

	if (offset < 0)
		offset += 7;
	if (line == 1) {
		for (; d < offset; ++d)
			printf("   ");
		dom = 1;
	} else {
		dom = 8 - offset + (line - 2) * 7;
		if (trans && !(line == 2 && fday == 3))
			dom += 11;
	}
	if (ltime && year == ltime->tm_year + 1900 && month == ltime->tm_mon)
		today = ltime->tm_mday;
	for (; d < 7 && dom <= monthlength(year, month, cal); ++d, ++dom) {
		if (dom == today)
			printf("\x1b[7m%2d\x1b[0m ", dom); /* highlight today's date */
		else
			printf("%2d ", dom);
		if (trans && dom == TRANS_DAY)
			dom += 11;
	}
	for (; d < 7; ++d)
		printf("   ");
}

static void
drawcal(size_t year, int month, size_t ncols, size_t nmons, int fday)
{
	char *smon[] = {"  January", " February", "    March", "    April",
	                "      May", "     June", "     July", "   August",
	                "September", "  October", " November", " December" };
	char *days[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", };
	size_t m, n, col, cur_year, cur_month, dow;
	int line;

	for (m = 0; m < nmons; ) {
		n = m;
		for (col = 0; m < nmons && col < ncols; ++col, ++m) {
			cur_year = year + m / 12;
			cur_month = month + m % 12;
			if (cur_month > 11) {
				cur_month -= 12;
				cur_year += 1;
			}
			printf("   %s %zu    ", smon[cur_month], cur_year);
			printf("  ");
		}
		putchar('\n');
		for (col = 0, m = n; m < nmons && col < ncols; ++col, ++m) {
			for (dow = fday; dow < (fday + 7); ++dow)
				printf("%s ", days[dow % 7]);
			printf("  ");
		}
		putchar('\n');
		for (line = 1; line <= 6; ++line) {
			for (col = 0, m = n; m < nmons && col < ncols; ++col, ++m) {
				cur_year = year + m / 12;
				cur_month = month + m % 12;
				if (cur_month > 11) {
					cur_month -= 12;
					cur_year += 1;
				}
				printgrid(cur_year, cur_month, fday, line);
				printf("  ");
			}
			putchar('\n');
		}
	}
}

static void
usage(void)
{
	eprintf("usage: %s [-1 | -3 | -y | -n num] "
	        "[-s | -m | -f num] [-c num] [[month] year]\n", argv0);
}

int
main(int argc, char *argv[])
{
	time_t now;
	size_t year, ncols, nmons;
	int fday, month;

	now   = time(NULL);
	ltime = localtime(&now);
	year  = ltime->tm_year + 1900;
	month = ltime->tm_mon + 1;
	fday  = 0;

	if (!isatty(STDOUT_FILENO))
		ltime = NULL; /* don't highlight today's date */

	ncols = 3;
	nmons = 0;

	ARGBEGIN {
	case '1':
		nmons = 1;
		break;
	case '3':
		nmons = 3;
		if (--month == 0) {
			month = 12;
			year--;
		}
		break;
	case 'c':
		ncols = estrtonum(EARGF(usage()), 0, MIN(SIZE_MAX, LLONG_MAX));
		break;
	case 'f':
		fday = estrtonum(EARGF(usage()), 0, 6);
		break;
	case 'm': /* Monday */
		fday = 1;
		break;
	case 'n':
		nmons = estrtonum(EARGF(usage()), 1, MIN(SIZE_MAX, LLONG_MAX));
		break;
	case 's': /* Sunday */
		fday = 0;
		break;
	case 'y':
		month = 1;
		nmons = 12;
		break;
	default:
		usage();
	} ARGEND

	if (nmons == 0) {
		if (argc == 1) {
			month = 1;
			nmons = 12;
		} else {
			nmons = 1;
		}
	}

	switch (argc) {
	case 2:
		month = estrtonum(argv[0], 1, 12);
		argv++;
	case 1: /* fallthrough */
		year = estrtonum(argv[0], 0, INT_MAX);
		break;
	case 0:
		break;
	default:
		usage();
	}

	drawcal(year, month - 1, ncols, nmons, fday);

	return fshut(stdout, "<stdout>");
}
