#!/bin/bash
#  
#Display calendar with arrow key navigation for month and year.
# By The Free Thinker, 2020. gopher://aussies.space/1/~freet/
#
#Usage:
# browsecal.sh [cal args] [-m month] [-y year]
#
#See "man cal" for "cal args".
#
# UP = next year, DOWN = last year, RIGHT = next month,
# LEFT = last month, SPACE = current month/year, q = quit.
#
#Example usage:
# browsecal.sh -3 -y 2013 -m 1
# urxvt -geometry 22x9 -title "Calendar" -e browsecal.sh

clear

#Process command-line arguments:
calargs=
until [ -z "$1" ]
do
 case "$1" in
	"-m") shift; [ ! -z "${1##*[!0-9]*}" ] && month=$1 || month=`date -d "$1 1" +%-m` ;; #https://stackoverflow.com/a/2704760
	"-y") shift; year=$1 ;;
	*) calargs="$calargs $1" ;;
 esac
 shift
done

[ -z $month ] && month=`date +%-m`
[ -z $year ] && year=`date +%-Y`

cal $calargs $month $year || exit

oldIFS="$IFS"
IFS=
#Arrow key reading from:
# https://stackoverflow.com/a/46481173
escape_char=$(printf "\u1b")
while true
do
 read -rsn1 mode # get 1 character
 if [[ $mode == $escape_char ]]; then
    read -rsn2 mode # read 2 more chars
 fi
 case $mode in
#key q
    'q') exit ;;

#key SPACE
    ' ') IFS=" "
         month=`date +%-m`
         year=`date +%-Y`
         clear
         cal $calargs $month $year
         IFS=
        ;;

#key UP
    '[A') IFS=" "
          (( year++ ))
          clear
          cal $calargs $month $year
          IFS=
         ;;

#key DOWN
    '[B') IFS=" "
          [ $year -gt 1 ] && (( year-- ))
          clear
          cal $calargs $month $year
          IFS=
         ;;

#key LEFT
    '[D') IFS=" "
          if [ $month -gt 1 ]; then
            (( month-- ))
          else
            (( year-- ))
            month=12
          fi
          clear
          cal $calargs $month $year
          IFS=
         ;;

#key RIGHT
    '[C') IFS=" "
          if [ $month -lt 12 ]; then
            (( month++ ))
          else
            (( year++ ))
            month=1
          fi
          clear; cal $calargs $month $year
          IFS=
         ;;
 esac
done

IFS="$oldIFS"
