#!/bin/sh

# User Definable Variables
BMI_COUNT=1
BMI_FREQ=3
CHART_FONT='"Arial,14"'
TITLE_FONT='"Times-Roman,24"'
HEIGHT=1.67	# meters
SCP_DESTINATION="zwhite@darkstar.frop.org:public_html/weightlog/"
STOREWEIGHT=false
TERMINAL="png size 1024,768"
TERMINAL_COMPARISON="png size 1024,256"

# Funcitons
showhelp() {
	echo "Usage: $0 [-t <terminal>] [weight] [belly]"
	echo "Interface to log and graph my weight and belly"
	echo
	echo "Options:"
	echo
	echo "         --help         This screen"
	echo "         -t <terminal>  The gnuplot terminal (aqua, png, x11)"
	echo "         weight         Specify a weight to add to the log"
	echo "         belly          Specify a belly size to add to the log"
	echo
	echo "Note: If you specify weight you must also specify a belly size"
	exit 127
}

generate_gnuplot() {
cat << EOF
# Reference: http://theochem.ki.ku.dk/on_line_docs/gnuplot/gnuplot_toc.html

set datafile separator ","
unset border
set font $CHART_FONT
set format x "%b %d"
set key inside left top
set output "weightlog.$1.png"
set pointsize 1.33
set terminal $TERMINAL
set timefmt "%Y %b %d"
set title "Weight and Belly Circumfrence  $FIRSTDATE - $LASTDATE" font $TITLE_FONT
set xdata time
set xtics nomirror
set ytics nomirror
set bmargin 5

# Labels
set label "BMI" at "2011 Jan 24",$bmi
set label "Estimated" at "2011 Apr 1",$estimated rotate by -90
set label "From memory" at "2011 May 1",$from_memory_1 rotate by -90
set label "From memory" at "2011 Jun 1",$from_memory_2 rotate by -90
set label "Before Vacation" at "2011 Aug 1",$before_vacation rotate by -90
set label "After Vacation" at "2011 Aug 9",$after_vacation rotate by -90
set label "Before Vegas" at "2011 Oct 13",$before_vegas rotate by -90
set label "After Vegas" at "2011 Oct 18",$after_vegas rotate by -90
set label "Before Thanksgiving" at "2011 Nov 23",$before_thanksgiving rotate by -90
set label "After Thanksgiving" at "2011 Nov 28",$after_thanksgiving rotate by -90
set label "Before Christmas" at "2011 Dec 17",$before_christmas rotate by -90
set label "After Christmas" at "2012 Jan 01",$after_christmas rotate by -90

# BMI Labels
EOF
}

generate_comparison_gnuplot() {
cat << EOF
# Reference: http://theochem.ki.ku.dk/on_line_docs/gnuplot/gnuplot_toc.html

set datafile separator ","
unset border
set font $CHART_FONT
set format x "%b %d"
set key inside left top
set output "weightlog.comparison.$1.png"
set pointsize 1.33
set terminal $TERMINAL_COMPARISON
set timefmt "%Y %b %d"
set title "Weight and Belly Gain/Loss Per Day  $FIRSTDATE - $LASTDATE" font $TITLE_FONT
set xdata time
set xtics nomirror
set ytics nomirror
set bmargin 5
set grid ytics

EOF
if [ $1 = metric ]; then
cat << EOF
plot "weightlog.comparison.csv" using 1:3 smooth bezier title "Waist Curve" with lines, \
     "" using 1:2 smooth bezier title "Weight Curve" with lines
EOF
else
cat << EOF
plot "weightlog.comparison.csv" using 1:(\$3*0.393700787) smooth bezier title "Waist Gain/Loss (IN)" with lines, \
     "" using 1:(\$2*2.20462262) smooth bezier title "Weight Gain/Loss (LB)" with lines
EOF
fi
}

generate_comparison() {
	PREVWEIGHT=$(head -1 weightlog.csv | cut -f 2 -d ,)
	PREVWAIST=$(head -8 weightlog.csv | tail -f | cut -f 3 -d ,)
	CURWAIST=$PREVWAIST

	while read line; do
		if [ -n "$(echo $line | cut -f 3 -d ,)" ]; then
			CURWAIST=$(echo $line | cut -f 3 -d ,)
		fi
		CURWEIGHT=$(echo $line | cut -f 2 -d ,)
		WEIGHTDIFF=$(echo $CURWEIGHT - $PREVWEIGHT | bc)
		WAISTDIFF=$(echo $CURWAIST - $PREVWAIST | bc)
		if [ "$WAISTDIFF" = "0" ]; then
			echo "$(echo $line | cut -f 1 -d ,),$WEIGHTDIFF,"
		else
			echo "$(echo $line | cut -f 1 -d ,),$WEIGHTDIFF,$WAISTDIFF"
		fi
		PREVWEIGHT=$CURWEIGHT
		PREVWAIST=$CURWAIST
	done < weightlog.csv
}

create_gnuplot() {
if [ $1 = metric ]; then
	bmi=78.25
	bmi_point=77
	estimated=96.5
	from_memory_1=95.5
	from_memory_2=91.5
	before_vacation=88
	after_vacation=87.5
	before_vegas=83
	after_vegas=84.5
	before_thanksgiving=82
	after_thanksgiving=82.5
	before_christmas=81.5
	after_christmas=83
else
	bmi=30
	bmi_point=25.5
	estimated=192
	from_memory_1=186
	from_memory_2=178
	before_vacation=162
	after_vacation=163.5
	before_vegas=158
	after_vegas=161
	before_thanksgiving=140
	after_thanksgiving=143
	before_christmas=144
	after_christmas=149
fi

# Generate our gnuplot stuff
generate_gnuplot $1 > weightlog.$1.gnuplot
generate_comparison > weightlog.comparison.csv
generate_comparison_gnuplot $1 > weightlog.comparison.$1.gnuplot

while read line; do
	DATE=$(echo $line | cut -f 1 -d ,)
	MASS=$(echo $line | cut -f 2 -d ,)
	BMI=$(printf "scale=2\n$MASS/${HEIGHT}^2\n" | bc)
	DAY=$(echo $DATE | cut -f 3 -d ' ')
	if should_show_bmi $DATE; then
		echo "set label \"$BMI\" at \"$DATE\",$bmi_point rotate by -90" >> weightlog.$1.gnuplot
	fi
done < weightlog.csv

if [ $1 = metric ]; then
cat << EOF >> weightlog.$1.gnuplot

plot "weightlog.csv" using 1:3 with points title "Waist (CM)", \
     "" using 1:2 with points title "Weight (KG)", \
     "" using 1:3 smooth bezier title "Waist Curve" with lines, \
     "" using 1:2 smooth bezier title "Weight Curve" with lines
EOF
else
cat << EOF >> weightlog.$1.gnuplot

plot "weightlog.csv" using 1:(\$3*0.393700787) with points title "Waist (IN)", \
     "" using 1:(\$2*2.20462262) with points title "Weight (LB)", \
     "" using 1:(\$3*0.393700787) smooth bezier title "Waist Trend" with lines, \
     "" using 1:(\$2*2.20462262) smooth bezier title "Waist Trend" with lines
EOF
fi
}

should_show_bmi() {
	# $1: The current year
	# $2: The month
	# $3: The day
	case $* in
		"2011 Mar 1")
			return 0
		;;
		"2011 Mar 5")
			return 0
		;;
		"2011 Apr 1")
			return 0
		;;
		"2011 May 1")
			return 0
		;;
		"2011 Jun 1")
			return 0
		;;
		*)
			if [ $BMI_COUNT -eq $BMI_FREQ ]; then
				BMI_COUNT=1
				return 0
			else
				BMI_COUNT=$(($BMI_COUNT + 1))
				return 1
			fi
		;;
	esac
}

# Parse the options
while [ -n "$*" ]; do
	case $1 in
		-h|--help)
			showhelp
		;;
		-t)
			if [ "$2" = "png" ]; then
				TERMINAL="png size 1024,768"
			else
				TERMINAL=$2
			fi
			shift
		;;
		*)
			# Assume that $1 is weight and $2 is belly
			if [ -z "$2" ]; then
				echo Error: You must specify both weight and belly
				showhelp
			elif [ -n "$3" ]; then
				echo Error: Unknown option: $3
				showhelp
			fi
			STOREWEIGHT=true
			WEIGHT=$1
			BELLY=$2
			break
		;;
	esac
	shift
done

# If the user has provided values, store the weight
if [ $STOREWEIGHT = true ]; then
	LAST_DATE=$(tail -1 weightlog.csv | cut -f 1 -d ,)
	LAST_WEIGHT=$(tail -1 weightlog.csv | cut -f 2 -d ,)
	LAST_BELLY=$(tail -1 weightlog.csv | cut -f 3 -d ,)
	DIFF_WEIGHT=$(echo $WEIGHT - $LAST_WEIGHT | bc)
	DIFF_BELLY=$(echo $BELLY - $LAST_BELLY | bc)
	cp weightlog.csv weightlog.csv.bak
	echo $(date '+%Y %b %d'),$WEIGHT,$BELLY >> weightlog.csv
	echo "*** Last Measurement Recorded: $LAST_DATE"
	echo "*** Weight: $WEIGHT - $LAST_WEIGHT = $DIFF_WEIGHT"
	echo "*** Waist: $BELLY - $LAST_BELLY = $DIFF_BELLY"
	echo
fi

# Determine some info about the weight log
FIRSTDATE=$(head -1 weightlog.csv | cut -f 1 -d ,)
LASTDATE=$(tail -1 weightlog.csv | cut -f 1 -d ,)

# Create the gnuplot file and plot the chart
create_gnuplot metric
create_gnuplot sae

for i in metric sae; do
	echo "*** Generating and uploading $i charts"
	gnuplot weightlog.$i.gnuplot
	gnuplot weightlog.comparison.$i.gnuplot
	scp weightlog.$i.png $SCP_DESTINATION/graph_${i}_$(date +%Y_%m_%d).png
	scp weightlog.comparison.$i.png $SCP_DESTINATION/graph_comparison_${i}_$(date +%Y_%m_%d).png
done
if [ $(echo $TERMINAL | cut -f 1 -d ' ') = png ]; then
	echo "*** Uploading miscellania"
	scp weightlog.*.gnuplot $0 weightlog.csv $SCP_DESTINATION/
	open http://darkstar.frop.org/~zwhite/weightlog/
fi
