#!/usr/bin/env bash
#--------------------------------------------------------------------
# Copyright (c) 2015-2023 by P. Wessel
# See LICENSE.TXT file for copying and redistribution conditions.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; version 3 or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# Contact info: http://www.soest.hawaii.edu/PT/GSFML
#--------------------------------------------------------------------
# Bash script to make a single, large-format GMT map of the locations
# of all cross profiles for a given FZ segment.
#
# Author:	Paul Wessel
# Date:		01-DEC-2023 (Requires GMT >= 6)
# Mode:		GMT classic mode
#--------------------------------------------------------------------

. fz_funcs.sh			# Load in FZ-specific shell functions
VGG=@earth_vgg_01m
SCL=0.1
if [ $# -eq 0 ]; then
	version=`fz_get_version`
cat << EOF >&2
	fzmapper $version - Make Mercator map of FZ traces and cross-profiles
	
	Usage: fzmapper [-A] [-F<origfile>] [-G<grid>] [-L<labelint>] [-O] [-S] [-T<prefix>] [-V] [-W<width>[c|i]]

		OPTIONS:
		-A Plot the analysis results from fzanalysis, if available [no results].
		-F <origfile> contains the original FZ track(s).
		-G <grid> is name of global grid file [$VGG].
		-L <labelint> sets how often to annotate profiles [1].
		-O Run as GMT overlay (i.e., pass -O -K) and send to stdout.
		   No PDF is made.
		-S Plot the smooth curve from fzblender, if available [no smooth curve].
		-T sets the profile prefix [fztrack].
		-V Report on progress [quiet].
		-W <width> specifies the map width (e.g., 10i or 50c).
		   Append units c or i [Default uses PROJ_LENGTH_UNIT].
		
EOF
	exit
fi

trap 'fz_cleanup 1' 1 2 3 15	# Set interrup handling
# Default values
W=6
N=1
F=""
blend=0
anal=0
OL=0
verbose=0
prefix=fztrack

while [ ! x"$1" = x ]; do
	case $1
	in
		-A)	anal=1				# Overlay analysis result if possible
			shift;;
		-W*)	W=`fz_get_dim $1`		# Width of map
			shift;;
		-F*)	ORIG=`fz_get_arg $1`;		# Original unsampled tracks
			shift;;
		-G*)	VGG=`fz_get_arg $1`;		# Name of grid file
			shift;;
		-L*)	N=`fz_get_arg $1`;		# Annotate every N'th profile
			shift;;
		-O)	OL=1;				# Plot as PS overlay to stdout
			plot=1;
			shift;;
		-S)	blend=1				# Overlay blend if possible
			shift;;
		-T*)	prefix=`fz_get_arg $1`		# Get file prefix
			shift;;
		-V)	verbose=1;			# Verbose
			shift;;
		-*)	echo "$0: Unrecognized option $1" 1>&2;	# Bad option argument
			exit 1;;
	esac
done

# Make sure we convert to inches
#-----------------------------------------
CFILE=${prefix}_resampled.txt				# The resampled tracks from grdtrack -D
if [ ! -f ${CFILE} ]; then				# Cannot do it yet anyway
	anal=0
	echo "$0: Resampled file ${CFILE} not found - cannot make plot" >&2
	exit
fi
XFILE=${prefix}_cross.txt				# Crossprofiles from fzmodeler
if [ ! -f ${XFILE} ]; then				# Cannot do it yet anyway
	anal=0
	echo "$0: Cross-profile file ${XFILE} not found - cannot make plot" >&2
	exit
fi
TFILE=${prefix}_analysis.txt				# The results from fzmodeler
if [ ! -f ${TFILE} ] && [ ${anal} -eq 1 ]; then		# Cannot do it yet anyway
	anal=0
	echo "$0: Analysis file ${TFILE} not found - ignored" >&2
fi
if [ ${OL} -eq 1 ]; then
	PS=/tmp/map.ps					# PostScript plot file
	PSargs="-O -K"
else
	PS=${prefix}_map.ps				# PostScript plot file
	PSargs="-P -K"
	PDF=${prefix}_map.pdf				# Final PDF plot file
fi
. ${prefix}_par.txt					# Read and assign parameters for these profiles
#------------------------------------------------------------------------------------------------------
# All dimensions are now in inches, regardless of what the user's units are.
# Cross-profiles have lon,lat,dist,azimuth,vgg,age,fzdist columns.
# Assign variables and calculate dimensions (inches used throughout)
#------------------------------------------------------------------------------------------------------
ymargin=0.75									# Bottom margin
xmargin=1									# Left margin
gmt set PROJ_ELLIPSOID Sphere							# Since we are plotting VGG
n_cross=`gmt convert -L ${XFILE} | wc -l`					# Number of cross-profiles
ndig=`gmt math -Q ${n_cross} LOG10 FLOOR 1 ADD =`				# Number of digits to use for running numbers
gmt info $XFILE -C -I2/2/2/5/10/10/10/10/10 -fg > $$.info			# Get clean multiples of min/max for each column
xmin=`cut -f1 $$.info`								# West boundary
xmax=`cut -f2 $$.info`								# East boundary
ymin=`cut -f3 $$.info`								# South boundary
ymax=`cut -f4 $$.info`								# North boundary
width2=`gmt math -Q ${W} 2 ${xmargin} MUL ADD =`				# Width of entire plot including margins
R=-R${xmin}/${xmax}/${ymin}/${ymax}						# Region -R option
height=`echo ${xmax} ${ymax} | gmt mapproject ${}R -JM${W}i -Di | cut -f2`	# Map height
height2=`gmt math -Q ${height} 2 $ymargin MUL ADD =`				# Plot height including margins
#------------------------------------------------------------------------------------------------------
# Ready for plotting
if [ ${verbose} -eq 1 ]; then
	echo "fzmapper: Papersize is ${width2}i by ${height2}i" >&2
fi
#------------------------------------------------------------------------------------------------------
if [ $OL -eq 1 ]; then
	PSargs="-O -K"
else
	PSargs="-P -K -X${xmargin}i -Y${ymargin}i --PS_MEDIA=${width2}ix${height2}i"
fi
gmt makecpt -Cgray -T-60/60/5 -Z > $$.cpt		# Make basic -60 to + 60 Eotvos grayscale CPT
xu=`gmt math -Q -0.75 1 ${xmargin} SUB ADD =`		# Placement x for -U logo and label
yu=`gmt math -Q -0.75 1 ${ymargin} SUB ADD =`		# Placement y for -U logo and label
# Lay down VGG image
gmt grdimage ${VGG} -C$$.cpt ${R} -JM${W}i ${PSargs} >| $PS
# Overlay geographic basemap and set -U label
gmt  psbasemap ${R} -JM${W}i -O -B5f1g90 -BWSne -K -U/${xu}i/${yu}i/"${prefix}: Map view" >> $PS
# Draw resampled FZ tracks as blue solid line
gmt psxy -R -J -O -K ${CFILE} -W0.5p,blue >> $PS
# Plot original digitized points as dark blue squares
if [ ! "X${ORIG}" = "X" ]; then
	gmt psxy -R -J -O -K ${ORIG} -Ss0.04i -Gdarkblue >> $PS
fi
P=0
# Make color table for quality weights (0-1)
gmt makecpt -Cpolar -T0/1/0.05 -Z > $$.cpt
cat << EOF >> $$.cpt2
-0.125	red		0.125	red
0.125	orange		0.375	orange
0.375	yellow		0.625	yellow
0.625	lightgreen	0.875	lightgreen
0.875	green		1.125	green
EOF

# Process each crossing profile individually
while [ ${P} -lt ${n_cross} ]; do
	item=`echo ${P} ${ndig} | awk '{printf "%*.*d\n", $2, $2, $1}'`	# Format an integer as profile identifier
	gmt convert -Q$P ${XFILE} > $$.raw				# Extract the next profile to plot (includes the segment header)
	grep -v '>' $$.raw > $$.tmp					# Get this cross profile without header
	header=`head -1 $$.raw`						# Get this cross profile's header
	az=`fz_get_item "${header}" az`					# Extract the azimuth of this profile
	tail -1 $$.raw | cut -f1,2 > $$.tail				# Place the end coordinates of profile in file $$.tail
	
	gmt psxy $$.tmp -R -J -O -K -Wfaint,lightblue >> $PS		# Plot cross-profile as faint, lightblue lines
	go=`gmt math -Q ${P} ${N} MOD 0 EQ =`				# Determine when to annotate profiles
	if [ ${go} -eq 1 ]; then					# OK, want to place text ID for this cross profile
		side=`gmt math -Q ${az} 180 LT =`			# Determine which side to place profile label
		if [ ${side} -eq 1 ]; then
			awk '{ printf "%s %s %s LM %s\n", $1, $2, '"${az}"', '"${item}"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS
		else
			awk '{ printf "%s %s %s RM %s\n", $1, $2, '"${az}"', '"${item}"'}' $$.tail | gmt pstext -R -J -A -O -K -Dj0.15i/0.05ivfaint -F+f6p,Helvetica+a+j -C0.015i -To -Gwhite -W0.5p >> $PS
		fi
	fi
	P=`expr ${P} + 1`						# Goto next profile
done
# Plot resampled digitized line in magenta
gmt psxy -R -J -O -K ${CFILE} -W0.25p,magenta >> $PS
# Plot empirical trough locations in red
x=`fz_col_id XD0`
y=`fz_col_id YD0`
if [ ${anal} -eq 1 ]; then
	gmt psxy ${TFILE} -R -J -O -K -Sc0.02i -Gred -i${x},${y} >> $PS
	# Plot blend trough locations in green
	x=`fz_col_id XB0`
	y=`fz_col_id YB0`
	gmt psxy ${TFILE} -R -J -O -K -Sc0.02i -Ggreen3 -i${x},${y} >> $PS
	# Plot edge blend locations in blue
	x=`fz_col_id XE0`
	y=`fz_col_id YE0`
	gmt psxy ${TFILE} -R -J -O -K -Sc0.02i -Gblue -i${x},${y} >> $PS
fi
if [ ${blend} -eq 1 ]; then
	BFILE=${prefix}_blend.txt				# Blended solution from fzblender
	if [ -f ${BFILE} ]; then
		# Plot best blend model as cyan line with colored circles reflecting quality
		gmt psxy ${BFILE} -R -J -O -K -W0.5p,cyan >> $PS
		gmt psxy ${BFILE} -R -J -O -K -Sc0.03i -C$$.cpt2 -i0,1,5 >> $PS
		# Add error bounds as dashed orange lines
		gmt psxy ${BFILE} -R -J -O -K -W0.25p,orange,- -i6,7 >> $PS
		gmt psxy ${BFILE} -R -J -O -K -W0.25p,orange,- -i8,9 >> $PS
	else
		echo "$0: Blend file ${BFILE} not found - ignored" >&2
	fi
fi
if [ ${OL} -eq 1 ]; then
	cat ${PS}
else
	# Finalize plot
	gmt psxy -R -J -O -T >> ${PS}
	# Convert the PS to a PDF file
	gmt psconvert -Tf ${PS}
	# Delete temporary files and the PS file
	os=`uname -s`
	if [ ${verbose} -eq 1 ]; then
		echo "fzmapper: Final map is called ${PDF}" >&2
	fi
	if [ ${os} = "Darwin" ]; then
		open ${PDF}
	fi
fi

rm -f ${PS}
fz_cleanup 1
