#!/bin/sh
#
# plotposn - generate position plot from ProAnalyst's exported limb coordinates
#
# Usage: plotposn [-n num] [-s rec] [-e rec] [-c col] [-m mul] [-g gap] [-1] \
#			[-b] [-r] [-v] input.csv > output.plt
#
# where: -n num	specifies a frame rate divisor for reducing the amount of
#		output, such that only the first of each "num" input records
#		will appear in the output (default is 1, to use all records)
#	 -s rec	specifies the starting record number (default is 1)
#	 -e rec	specifies the ending record number (default is all)
#		only the records between the specified start and end will
#		be included in the output.  If instead of a record number,
#		the start or end is specified as a time value followed by "s"
#		(for seconds), then the record with a matching time value in
#		column 2 will be used as the start or end. If the record number
#		is followed by "i" (for index) the record with a matching index
#		value in column 1 will be used.  If the number is followed by
#		"ss" it is taken as seconds from the start, i.e. the first
#		record.
#	 -c col	specifies the column of the X coordinate of the feature to plot
#		(default is 3)
#	 -m mul	specifies the scaling factor by which the coordinates will be
#		multiplied (default is 1). By default, the figures are scaled
#		so that numbers in the CSV input file represent centimeters on
#		the 25x18cm drawing region of a plotter page. You can also use
#		"auto" to automatically scale the plot to the full page.
#	 -1	specifies that -1,-1 coordinate pairs should be excluded
#	 -b	specifies that a scale bar should be shown at the bottom left
#	 -r	specifies that data should be rotated (counter-clockwise)
#	 -v	specifies verbose output, which will show some calculated
#		parameters
#	 input.csv is the name of the file exported from ProAnalyst
#		other similarly-formatted CSV files may be used as well, as
#		the index and time columns aren't needed if you don't use the
#		"i", "s", or "ss" after the number in the -s and -e options
#	 output.plt is the name of the HPGL plot file that is output
#
# Copyright (c) 2018, Gilles Detillieux, Spinal Cord Research Centre,
# University of Manitoba.  All Rights Reserved.
#

nopt=1
sopt=1
eopt=2000000000
copt=3
mopt=1
m1opt=0
bopt=0
ropt=0
vopt=0
while :
do
	case "$1" in
	-\?|-help|--help)	sed -n '3,/^# Univ/s/^#/ /p' "$0"; exit ;;
	-n[0-9]*)	nopt=`expr "x$1" : 'x-n\(.*\)'`; shift ;;
	-n)	shift; nopt="$1"; shift ;;
	-s[-0-9]*)	sopt=`expr "x$1" : 'x-s\(.*\)'`; shift ;;
	-s)	shift; sopt="$1"; shift ;;
	-e[-0-9]*)	eopt=`expr "x$1" : 'x-e\(.*\)'`; shift ;;
	-e)	shift; eopt="$1"; shift ;;
	-c[0-9]*)	copt=`expr "x$1" : 'x-c\(.*\)'`; shift ;;
	-c)	shift; copt="$1"; shift ;;
	-m[-.0-9]*)	mopt=`expr "x$1" : 'x-m\(.*\)'`; shift ;;
	-m)	shift; mopt="$1"; shift ;;
	-1)	m1opt=1; shift ;;
	-b)	bopt=1; shift ;;
	-r)	ropt=1; shift ;;
	-v)	vopt=1; shift ;;
	-*)	set --; break ;;
	*)	break ;;
	esac
done

case "$#" in
0)	echo "Usage: plotposn [-n num] [-s rec] [-e rec] [-c col] [-m mul] [-1] \\
		[-b] [-r] [-v] input.csv > output.plt
	or plotposn --help	for detailed usage information" >&2; exit 1 ;;
esac

awk -F, 'BEGIN {
		n = '"$nopt"'
		starttime = ""
		sttrel = 0
		start = "'"$sopt"'"
		if (start ~ /.*[is]$/) {
			sttcol = 2
			if (start ~ /.*i$/) sttcol = 1
			if (start ~ /.*ss$/) sttrel = 1
			starttime = start
			sub(/[is]s*$/, "", starttime)
			starttime = starttime * 1.0;
			start = 2^30;
		} else
			start += 0;
		endtime = ""
		entrel = 0
		end = "'"$eopt"'"
		if (end ~ /.*[is]$/) {
			entcol = 2
			if (end ~ /.*i$/) entcol = 1
			if (end ~ /.*ss$/) entrel = 1
			endtime = end
			sub(/[is]s*$/, "", endtime)
			endtime = endtime * 1.0;
			end = 2^30;
		} else
			end += 0;
		stcol = '"$copt"'
		mult = "'"$mopt"'"
		nominus1 = '"$m1opt"'
		bars = '"$bopt"'
		rotate = '"$ropt"'
		verbose = '"$vopt"'
		irec = 0
		orec = 0
		xmin = 0
		xmax = 0
		ymin = 0
		ymax = 0
		xoff = 0
		yoff = 0
		dsum = 0
	}
	/^[ 	]*-*[0-9][-+e.0-9]*,/ && NF >= stcol+1 {
		if (sttrel && irec == 0 && NF >= sttcol)
			starttime += $(sttcol)
		if (starttime != "" && NF > sttcol && $(sttcol)*1.0 >= starttime) {
			starttime = ""
			start = irec+1
		}
		if (entrel && irec == 0 && NF >= entcol)
			endtime += $(entcol)
		if (endtime != "" && NF > entcol && $(entcol)*1.0 > endtime) {
			endtime = ""
			end = irec
		}
		if (irec == 0) {
			if (sttcol > 0 && sttcol <= NF)
				frec = $(sttcol)
			else
				frec = irec
			if (entcol > 0 && entcol <= NF)
				ferec = $(entcol)
			else
				ferec = irec
		}
		if (sttcol > 0 && sttcol <= NF)
			lrec = $(sttcol)
		else
			lrec = irec
		if (entcol > 0 && entcol <= NF)
			lerec = $(entcol)
		else
			lerec = irec
		if (++irec >= start && irec <= end && (irec-start) % n == 0) {
		    if (nominus1 == 0 || $(stcol) != -1 || $(stcol+1) != -1) {
			++orec
			x[orec] = $(stcol)-xoff
			y[orec] = $(stcol+1)-yoff
			if (orec <= 1 || xmin > x[orec])
				xmin = x[orec]
			if (orec <= 1 || xmax < x[orec])
				xmax = x[orec]
			if (orec <= 1 || ymin > y[orec])
				ymin = y[orec]
			if (orec <= 1 || ymax < y[orec])
				ymax = y[orec]
			if (orec > 1) {
				dx = x[orec]-x[orec-1]
				dy = y[orec]-y[orec-1]
				dsum += sqrt(dx*dx + dy*dy)
			}
		    }
		}
	}
	END {
		imult = mult
		if (imult ~ /auto/) {
			if (rotate) {
				mult = 7200 / (xmax-xmin)
				if (mult > 10000 / (ymax-ymin))
					mult = 10000 / (ymax-ymin)
			} else {
				mult = 7200 / (ymax-ymin)
				if (mult > 10000 / (xmax-xmin))
					mult = 10000 / (xmax-xmin)
			}
			if (verbose)
				printf("auto mult=%g\n",mult*25.0/10000.0) >> "/dev/stderr"
		} else {
			mult *= 10000.0/25.0
		}
		xoff = 80
		yoff = 320
		if (orec == 0) {
			if (irec == 0)
				printf("plotposn: no input records found in data file\n") >> "/dev/stderr"
			else {
				printf("plotposn: no matching records found within specified start and end\n") >> "/dev/stderr"
				if (sttrel) {
					lrec -= frec
					frec = 0
				}
				if (sttcol == entcol && sttrel == entrel)
					printf("          start and end should be between %g and %g\n", frec, lrec) >> "/dev/stderr"
				else {
					if (entrel) {
						lerec -= ferec
						ferec = 0
					}
					printf("          start should be between %g and %g, end between %g and %g\n", frec, lrec, ferec, lerec) >> "/dev/stderr"
				}
			}
		}
		if (verbose) {
			printf("start=%g, end=%g, irec=%g, orec=%g, n=%g\n",start,end,irec,orec,n) >> "/dev/stderr"
			printf("xmin=%g, xmax=%g, ymin=%g, ymax=%g, mult=%g\n",xmin,xmax,ymin,ymax,mult/400) >> "/dev/stderr"
			printf("total distance=%g\n",dsum) >> "/dev/stderr"
		}
		printf("PU;PA;SC80,10080,320,7520;\nPU;")
		if (bars) {
			printf("SP1;\n")
			len = 500
			while (len*mult > 2000)
				len /= 10
			barsize = int(len*mult)
			printf("PU%d,%d;PD%d,%d;\n", xoff, yoff+barsize, xoff, yoff)
			printf("PU%d,%d;LB%g\003;\n", xoff+50, yoff+barsize/2, len)
#			printf("PU%d,%d;PD%d,%d;PD%d,%d;\n", xoff, yoff+barsize, xoff, yoff, xoff+barsize, yoff)
#			printf("PU%d,%d;LB%g\003;\n", xoff+50, yoff+barsize*2/3, len)
#			printf("PU%d,%d;LB%g\003;\n", xoff+50+barsize*2/3, yoff+50, len)
		}
		if (imult !~ /auto/) {
			xmin = 0
			ymin = 0
		} else if (rotate) {
			t = ymin
			ymin = xmin
			xmin = -t
		}
		printf("SP2;\n")
		p = "PU"
		for (i = 1; i <= orec; ++i) {
			if (rotate) {
				t = y[i]
				y[i] = x[i]
				x[i] = 10000.0/mult - t
			}
			x[i] = int((x[i]-xmin)*mult+xoff)
			y[i] = int((y[i]-ymin)*mult+yoff)
			printf("%s%d,%d;", p, x[i], y[i])
			p = "PD"
			printf("\n")
		}
	}' ${@+"$@"}
