#!/bin/sh

export LANG=C
export LC_ALL=C

TMP=/tmp/vtsidgram.$$

trap 'bailout "interrupted"' INT QUIT KILL

usage(){
   echo "usage: vtsidgram [options] [source] > imagefile" >&2
   echo "" >&2
   echo "options:" >&2
   echo "  -F start,end   Frequency range, Hz" >&2
   echo "  -T start,end   Time range" >&2
   echo "  -s x,y         Plot size in pixels, default 640,480" >&2
   echo "  -t title       Title for the spectrogram" >&2
   echo "  -g             Display grid" >&2
   echo "  -z zrange      Z range, min:max,  default auto" >&2
   echo "" >&2
   echo "  -o format  Specify output image format" >&2
   echo "             vtsidgram -o? for available formats" >&2
   echo "" >&2
   exit 1
}

cleanup(){
    [ "$TMP" != "" ] && rm -f $TMP.data $TMP.setup
}

bailout(){
   echo "vtsidgram: $*" >&2
   cleanup
   exit 1
}

TITLE=""
FOPT=""
TOPT=""
ZOPT=""
GRID=""
PSIZE="size 640,480"    # Default size
FORMAT="x11 persist"    # Default terminal type

#
#  Parse options
#

OPTS=`getopt -n vtsidgram -o gF:T:t:o:s:z:? -- "$@"`
[ $? != 0 ] && usage

eval set -- "$OPTS"

while :
do
   case "$1" in

      -t) TITLE="$2" ; shift 2 ;;

      -F) FOPT="-F $2" ; shift 2 ;;

      -T) TOPT="-T $2" ; TSPEC="$2" ; shift 2 ;;

      -z) ZOPT="$2" ; shift 2 ;;

      -o) FORMAT="$2" ; shift 2 ;;

      -s) PSIZE="size $2" ; shift 2 ;;

      -g) GRID="set grid" ; shift 1 ;;

      -\?) usage ;;

      --) shift ; break ;;

       *) bailout "getopt error" ;;
   esac
done

#
#  Get gnuplot to list available terminals if we got -o?
#

[ "$FORMAT" = "?" ] && {
   echo "set terminal" | gnuplot 2>&1 | sed '/return for more/d'
   exit 0
}

#
# SID data directory must follow the options
#

[ $# -ne 1 ] && usage
DATADIR=$1

[ "$TITLE" = "" ] && TITLE="$TSPEC $DATADIR"

#
#  Extract the data and convert to the layout required by gnuplot for pm3d.
#  The header record from vtsidex is examined to determine which are the
#  amplitude fields and to establish the frequency of the bins.
#

vtsidex $TOPT $FOPT -ote -oh $DATADIR | 
awk '{
   if( NR == 1)   # Header record
   {
      # ts <field list> spectrum base_freq freq_step nsteps
      # example: ts a0 a1 b spectrum 0.00000 11.71875 8192

      nsf = 0   #  Number of spectrum fields
      naf = 0   #  Number of amplitude fields

      for( i=2; i<=NF && $i != "spectrum"; i++)
      {
         if( substr( $i, 1, 1) == "a")
            aflist[nsf] = ++naf   # List indices of amplitude fields
         nsf++
      }

      base = $(i+1)
      dF = $(i+2)
      nbins = $(i+3)
      next
   }

   # Data records

   if( !Tfirst) Tfirst = $1
   Tlast = $1  

   for( i=0; i<nbins; i++)
   {
      sumsq = 0    # Sum of squared amplitudes
      for( f in aflist)
      {
         n = i * nsf + 2 + f
         sumsq += $n * $n
      }

      rms = sqrt( sumsq / naf)
      if( !rmsmin || rmsmin > rms) rmsmin = rms
      if( rms > rmsmax) rmsmax = rms
      printf( "%d %.4e %.4e\n", int($1), (base + i * dF)/1000, rms)
   }

   printf( "\n")   # Blank line after each isoline
   
}END{

   setup = TMP ".setup"

   Trange = Tlast - Tfirst
   if( Trange < 7200)
   {
      printf( "set format x %c%s%c\n", 39, "%H:%M", 39) >> setup
      printf( "set xtics border mirror out 600\n") >> setup
      printf( "set xlabel %c%s%c\n", 39, "UT HH:MM", 39) >> setup
   }
   else
   if( Trange < 86400)
   {
      printf( "set format x %c%s%c\n", 39, "%H", 39) >> setup
      printf( "set xtics border mirror out 3600\n") >> setup
      printf( "set xlabel %c%s%c\n", 39, "UT Hour", 39) >> setup
   }
   else
   {
      printf( "set format x %c%s%c\n", 39, "%m-%d", 39) >> setup
      printf( "set xtics border mirror out 86400\n") >> setup
      printf( "set xlabel %c%s%c\n", 39, "UT Month-day", 39) >> setup
   }

   # Output frequency and time range to help gnuplot
   printf( "set yrange [%.4e:%.4e]\n",
      base/1000, (base + dF*(nbins-1))/1000) >> setup

   # Output timestamp range, have to fiddle about here quoting the timestamps
   printf( "set xrange [%c%d%c:%c%d%c]\n",
      39, Tfirst, 39, 39, Tlast, 39) >> setup

   # Output a zrange specification
   if( zopt == "")
   {
   #   printf( "set zrange [%.4e:%.4e]\n", rmsmin, rmsmax) >> setup
      printf( "set cbrange [%.4e:%.4e]\n", rmsmin, rmsmax) >> setup
   }
   else
   {
   #   printf( "set zrange [%s]\n", zopt) >> setup
      printf( "set cbrange [%s]\n", zopt) >> setup
   }
}' zopt="$ZOPT" "TMP=$TMP" > $TMP.data


#
#  Run the plot
#

echo "
   set terminal $FORMAT $PSIZE
   set ylabel 'Frequency, kHz'
   set palette color maxcolors 4096
   set pm3d at b interpolate 0,0
   set view map
   set style data pm3d
   $GRID
   set nokey
   set xdata time
   set timefmt '%s'
   set logscale cb
   `cat $TMP.setup`
   set ytics border mirror out
   set title '$TITLE'
   splot '$TMP.data' using 1:2:3
 " | gnuplot

cleanup

