#!/bin/bash

# Hacky wrapper for BSD cal. Sends simple calendars to standard output.
#
# Usage: mycal [month] [year]
# If no month or year is given the current month is shown.
#  year --- by itself must be 4-digits. Otherwise 2-digits will do.
#           if omitted the next matching month in the future is shown.
# month --- a number or any non-ambiguous prefix of the English name
#           if omitted the whole year is shown.
#
# This is somewhat more understanding of what I usually want than cal by itself.
# For example: "cal 9" gives a calendar for the year 0009.
#              "mycal 9" gives a calendar for "next september".
#
# Note that GNU cal or gcal is quite a bit more advanced than BSD cal. It
# doesn't interpret the command line in exactly the same way as this hack.
#
# Iain Murray August 2005, December 2007, November 2022

# For Debian/Ubuntu after it stopped highlighting the current day, even if called with 0 args
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=904839
# https://unix.stackexchange.com/questions/664311/current-date-in-cal-is-not-highlighted-in-recent-debian
if [ -t 1 ] ; then
    CAL="ncal -b"
else
    # If standard out redirected, don't force highlighting
    CAL="/usr/bin/cal"
fi

# The cal I have used to only highlight the current day if called with 0 args
if [ $# -eq 0 ] ; then
    exec $CAL
fi

# Only spit out whole year if I specify 4 digit year. Otherwise assume I wanted
# a month.
if echo "$1" | grep '^[12][0123456789]\{3\}$' > /dev/null 2> /dev/null ; then
    $CAL "$1"
    exit
fi

# Allow me to specify months as a string
month=`echo "$1" | sed \
    -e 's/^ja.*/01/i' \
    -e 's/^f.*/02/i' \
    -e 's/^mar.*/03/i' \
    -e 's/^ap.*/04/i' \
    -e 's/^may/05/i' \
    -e 's/^jun.*/06/i' \
    -e 's/^jul.*/07/i' \
    -e 's/^au.*/08/i' \
    -e 's/^s.*/09/i' \
    -e 's/^o.*/10/i' \
    -e 's/^n.*/11/i' \
    -e 's/^d.*/12/i'`

if [ "$month" ] ; then
    if echo "$month" | grep '^[01]\?[0123456789]$' > /dev/null 2> /dev/null ; then
        true
    else
        echo Sorry, I do not understand which month you want.
        exit
    fi
else
    month=`date +'%m'`
fi

if [ "$2" ] ; then
    # allow two digit years (although evil)
    year="`echo "$2" | sed -e 's/^\([123456789]\)$/200\1/' -e 's/^\([012345].\)$/20\1/' -e 's/^\([6789].\)$/19\1/'`"
else
    # grab next month in the future if year not specified
    if [ "$month" -ge "`date +'%m'`" ] ; then
        year=`date +'%Y'`
    else
        year=$((`date +'%Y'`+1))
    fi
fi

$CAL "$month" "$year"
