#! /bin/bash
# Last edited on 2023-10-07 02:20:46 by stolfi

# Arguments are ${INFILE} ${PTFILE} ${WINRAD} ${OUNIT} ${OUTPREFIX}
# 
# Takes an input image {INFILE} and a file {PTFILE} with lines "{TAG}
# {X} {Y} {MARKS}", where {X,Y} are coordinates of a feature in
# {INFILE}, {TAG} is the name ("P0", "S12", etc.) of that point, and
# {MARKS} are zero or more marks (crcles, crosses, rectangles, etc to be
# drawn around that feature.
# 
# For each feature in {PTFILE}, the script creates an image
# "{OUTPREFIX}-{TAG}.png" containing a small window of fixed size
# {2*WINRAD+1} (user units) centered on that point, magnified by a
# suitable scale factor, with the {MARKS} drawn over it and the label
# {TAG} at the corner.
# 
# The {TAG} must be a string of letters, digits, or "_". The coordinates
# {X} and {Y} may be fractional, but the window will be synced to whole pixels.
# See "00-Notebook.txt" for the format of {MARKS}.
# 
# The feature {X} {Y} coordinates and the coordinates and dimensions in
# {MARKS} are assumed to be in user coordinates. They will be scaled by
# {1/OUNIT} to get the equivalent in pixels.

INFILE="$1"; shift
PTFILE="$1"; shift
WINRAD="$1"; shift
OUNIT="$1"; shift
OUTPREFIX="$1"; shift

echo "extracting neighborhoods from ${INFILE} according to ${PTFILE} ..." 1>&2
echo "output user unit = ${OUNIT}" 1>&2

WSCALE=8 # Window clip resizing factor.
echo "clip scaling = ${WSCALE}" 1>&2

tag_prev="" # Tag on previous line.
for ptlin in `cat ${PTFILE} | egrep -e '^[A-Za-z][A-Z0-9a-z_]*[ ]' | sort | sed -e 's:[ ]:_:g' -e 's:[ ]*[#].*$::g'` ; do
  ptargs=( `echo "${ptlin}" | sed -e 's:[_]: :g'` )
  tag="${ptargs[0]}"
  xc="${ptargs[1]}"
  yc="${ptargs[2]}"
  mkargs=( ${ptargs[@]:3} )

  if [[ "/${tag}" == "/${tag_prev}" ]]; then
    echo "!! duplicate point tag \"${ptlin}\" -- will overwrite ${OUTFILE}" 1>&2
  fi
  tag_prev="${tag}"
  
  OUTFILE="${OUTPREFIX}-${tag}.png"
  geomargs=( \
    ` gawk \
        -v xc=${xc} -v yc=${yc} \
        -v WINRAD=${WINRAD} \
        -v OUNIT=${OUNIT} \
        ' BEGIN{ \
            ws = 2*int(WINRAD*OUNIT+0.999) + 1; 
            wx = int((xc-WINRAD)*OUNIT + 0.5); 
            wy = int((yc-WINRAD)*OUNIT + 0.5);
            print wz, xlo, ylo;
          } 
        ' \
    ` \
  )
  WSIZE="${geomargs[0]}"
  WX="${geomargs[1]}"
  WY="${geomargs[2]}"
  geom="${WSIZE}x${WSIZE}+${WX}+${WY}"
  
  drawCmds=( \
    ` generate_draw_mark_cmds.gawk \
          -v TAG="${tag}" \
          -v WX=${WX} \
          -v WY=${WY} \
          -v MKARGS="${mkargs[*]}" \
          -v OUNIT=${OUNIT} \
          -v WSCALE=${WSCALE} \
    ` \
  )
  # Hack: replace "_" by " " in each element of {drawCmds} without
  # splitting it into two elements:
  echo "computing the mark drawing commands ..." 1>&2
  i=0;
  while [[ ${i} -lt ${#drawCmds[@]} ]]; do 
    drawCmds[i]="`echo ${drawCmds[i]} | sed -e 's:[_]: :g'`"
    i=$(( $i + 1 ))
  done
  # echo "${drawCmds[*]}" | sed -e 's:-draw:@-draw:g' | tr '@' '\012' 1>&2

  echo "extracting ${OUTFILE} at '${geom}' ..." 1>&2

  WSCALE_PCT=`echo "${WSCALE}*100" | bc -lq`
  convert ${INFILE} \
      -crop "${geom}" \
      -colorspace Gray \
      PGM:- \
    | pnmnorm \
      -bpercent 1 \
      -wpercent 1 \
    | convert PGM:- \
      -filter Box \
      -resize "${WSCALE_PCT}%" \
      -set colorspace RGB \
      -pointsize 32 \
      -fill "green" \
      -stroke "green" \
      -strokewidth 3 \
      -draw "gravity NorthEast text 5,5 '${tag}'" \
      "${drawCmds[@]}" \
      -colorspace sRGB \
      ${OUTFILE}
done
