#! /bin/csh   

########################################################
#
#  v 2.4.5	 H.A.Trujillo, Wilkes University
#
########################################################


if ($1 == -h) then
    cat << END_OF_HELP_TEXT

 `basename $0` [ -h | -i ]

   A homemade replacement for the "calendar" command.

   Searches through ~/calendar for lines beginning with the keys
   below, and prints the ones for the present day and the next (or
   through Monday if run over the weekend).
   
   Recognizes the following formats at the beginning of a line.  All
   are case insensitive.  Weekdays and month names are all 3-letter
   abbreviations.
  
  	mmm dd					   eg: sep 25, apr 01, may 1, jun  1
  	xxx dd		every month on day "dd"    eg: xxx 25
  	www		every week on day www 	   eg: mon, tue  (3 letters)
 	www_n		nth w-day of month         eg: 3rd Saturday = sat_3
	www·, www¨	every other week           eg: mon·, tue¨
	www¹, www², www³	every third week   eg: mon¹, tue²
	www-, www=, www±, www#	every fourth week  
	

    every-other-week index = ( date of 1st Sun in Jan  +  \`date +%U\` )MOD(2)  +  1 
    every-third-week index = ( date of 1st Sun in Jan  +  \`date +%U\` )MOD(3)  +  2 
	(Week for index begins on Sunday)
  
 Flags:
	-h	print this help message
	-i	print 2-, 3- and 4-week cycle indices for today.

END_OF_HELP_TEXT
    exit
    endif

### Preliminary definitions
						#   1    2  3  |  4      5      6
set i       = (`date +%m\ %e\ %g\ %u\ %s\ %Z`)	# month day yr | wkd epoch_time tz
set m = _$i[1] ; set m = $m:s/_0//

@   m 	    = $m:s/_// 				# jan=1, feb=2, ...
@   date    = $i[2]
@   w       = $i[4]				# mon=1, tue=2, ...
set mlen    = (31 28 31 30 31 30 31 31 30 31 30 31 31) 
set month   = (jan feb mar apr may jun jul aug sep oct nov dec jan)
set wkdy    = (mon tue wed thu fri sat sun mon)
set spacer  = ("" "------" "------" "------")
set nloops  = (2 2 2 2 4 3 2)
@ loopsleft = $nloops[$w]


# Is this a leap year?
if (`expr $i[3] % 4` == 0) set mlen[2] = 29


# Do we need to compensate for daylight savings time?
if ($i[6] =~ ?D?) @ i[5] = $i[5] + 3600


#  Every-other-week items
set oe_flags = (· · ¨ ¨ · ·)
set oe_start = (1 1 1 1 1 2 1)
@   oe_index = `expr \( \( $i[5] - 277200 \) / 604800 \) % 2 \* 2 + $oe_start[$w]`
   # { [ (seconds since 1st Sun midnight after Epoch) / (600k sec/wk) ] MOD(2) } * 2
   # 		+ start position
  

#  Every-third-week items
set tw_flags = (¹ ¹ ² ² ³ ³ ¹ ¹)
@   tw_index = `expr \( \( $i[5] - 277200 \) / 604800 \) % 3 \* 2 + $oe_start[$w]`
   # { [ (seconds since 1st Sun midnight after Epoch) / (600k sec/wk) ] MOD(3) } * 2
   # 		+ start position

  

#  Every-fourth-week items
set fw_flags = (- - = = ± ± \# \# - -)
@   fw_index = `expr \( \( $i[5] - 277200 \) / 604800 \) % 4 \* 2 + $oe_start[$w]`
   # { [ (seconds since 1st Sun midnight after Epoch) / (600k sec/wk) ] MOD(4) } * 2
   # 		+ start position

  

if ($1- == "-i-") then
    echo "	 2-week index: $oe_flags[$oe_index]	 3-week index: $tw_flags[$tw_index]	 4-week index: $fw_flags[$fw_index]"
    exit
    endif


### The big loop

while ($loopsleft > 0)

    @ w_nbr = `expr \( $date + 6 \) / 7`

	grep -i \
	"^$wkdy[$w]\(	\|_$w_nbr\|$oe_flags[$oe_index]\|$tw_flags[$tw_index]\|$fw_flags[$fw_index]\)" \
	    ~/calendar 						>! /tmp/calhash.$$
	grep -iw "^\($month[$m]\|xxx\) $date"	  ~/calendar	>> /tmp/calhash.$$

				# DEAL WITH SINGLE-DIGIT DATES
    if ($date < 10) then
	grep -iw "^\($month[$m]\|xxx\) [ 0]$date" ~/calendar	>> /tmp/calhash.$$
    endif


    sort -f -k2  -t "	" /tmp/calhash.$$ 
    echo $spacer[$loopsleft]

    @ w ++
    @ date ++
    @ loopsleft --
    @ oe_index ++
    @ tw_index ++
    @ fw_index ++

				# DID WE SCROLL PAST END OF MONTH?
    if ($date > $mlen[$m]) then
	@ date = 1
	@ m ++
    endif
end


### Clean up and go away

/bin/rm /tmp/calhash.$$
exit



##############################
#
# v 1.0		  2001
#   A homemade replacement for the "calendar" command, which wasn't
#   implemented at Grinnell.
#
# v 2.0		  2003
#   ... and now that I have "calendar" on OS X, I've discovered all the
#   baggage needed to use it (cpp, etc), but which I don't want to install
#   at work.
#       v2 no longer relies on the niceties afforded by the MathLan "date"
#   command -- in particular the -d option to give the date of a day other than
#   today.
#
# v 2.1		4/2008
#   added "3rd Saturday" feature, to deal with committee meetings, etc.
#
# v 2.2		2/2009
#   added "odd/even week of year" selection to deal with city recycling.
# 
# v 2.3		1/2010
#   repaired and simplified odd/even week counter
#
# v 2.4		13may10
#   added every-third-week counter (allergy shots/UAC)
#
# v 2.4.1	30jun10
#   added -i flag
#
# v 2.4.2	18jul10
#   corrected two- and three-week cycles to account for daylight savings time,
#   if script run between midnight and 2 AM.
#
# v 2.4.3	14Feb11
#   finally included www* items in sort
#
# v 2.4.4	12 May 11
#   added "every-fourth-week" selector  (Allergy shots)
#
# v 2.4.5	 1 Aug 14
#   @ m = ... suddenly gagging when month is zero-padded. (??)  Value now filtered.
#
##############################

#						    vim: tw=0 ft=csh
