#!/bin/sh -efu

. shell-args
. shell-quote

show_help(){
cat <<EOF
map_rescale - modify map-files (rename, crop, scale)

Usage: $PROG <map-file>

Options:
  -q, --quiet                       try to be more quiet;
  -v, --verbose                     print a message for each action;
  -V, --version                     print program version and exit;
  -h, --help                        show this text and exit.

  -g <geom>                         crop to <geom>
  -r <factor>                       rescale by factor
  -n <name>                         set name
  -f <file>                         use image filename (default: from map-file)
  -s <style>                        use colormap style (default: mmb)
  -l <lon0>                         set lon0           (default: from geometry)
  -o <name>                         use basename for output (default _<in name>)

<geom> can be written in m (1000x1000+7500000+6200000)
or km (1x1+7500+6200k)

EOF
exit
}

print_version(){
  echo $PROG version
  exit
}


TEMP="$(getopt -n $PROG -o g:r:n:f:s:l:o:$getopt_common_opts\
                        -l $getopt_common_longopts -- "$@")" ||
    show_usage
eval set -- "$TEMP"

geom=
lon0=
img=
outname=
while :; do
  case "$1" in
  --) shift; break
  ;;
  -g) geom="$2"; shift;
  ;;
  -r) scale="$2"; shift;
  ;;
  -n) name="$2"; shift;
  ;;
  -f) img="$2"; shift;
  ;;
  -s) style="$2"; shift;
  ;;
  -l) lon0="$2"; shift;
  ;;
  -o) outname="$2"; shift
  ;;
  *) parse_common_option "$1"
  ;;
  esac
  shift
done

[ "$#" -ge 1 ] || show_usage "Insufficient arguments."
[ "$#" -le 1 ] || show_usage "Too many arguments."

map="$1"
[ -r "$map" ] || fatal "Can't read map file: $map"
wdir="${map%/*}/"

[ -n "$img" ] || img="$(sed -n '3p' "$map" | tr -d '\r\n')"
[ -s "$img" ] || img="$wdir/${img##*/}"
[ -s "$img" ] || fatal "Can't find image name from map file. Use -f option"

old_name="$(sed -n '2p' "$map" | tr -d '\r\n')"
name="${name-$old_name}" # use name from cmdline if it is defined

if [ -n "$outname" ]; then
  outmap="$wdir$outname.map"
  if   [ -z "${img##*.png}" ]; then outimg="$wdir$outname.png"
  elif [ -z "${img##*.jpg}" ]; then outimg="$wdir$outname.jpg"
  else fatal "Unsupported image format for $img"
  fi
else
  outimg="$img"
  outmap="$map"
  tmpimg="$(mktemp map_rescale.XXXXXX.${img##*/})"
  tmpmap="$(mktemp map_rescale.XXXXXX.${map##*/})"
  cp -f -- "$img" "$tmpimg"
  img="$tmpimg"
  cp -f -- "$map" "$tmpmap"
  map="$tmpmap"
fi



[ -n "${scale:-}" ] || scale=1

[ -n "${style:-}" ] || style=default
cmap="/usr/share/mapsoft/$style.cmap.pnm"
[ -s "$cmap" ] || fatal "Can't find cmap for style $style: $cmap"

geom_regexp="[[:space:]]*\([0-9\.]\+\)x\([0-9\.]\+\)+\([0-9\.]\+\)+\([0-9\.]\+\)\(k\?\)[[:space:]]*"
TMP="$(printf "$geom" |
  sed -n "s/^$geom_regexp\$/W=\1; H=\2; X=\3; Y=\4; K=\5;/p")"

W=;H=;X=;Y=;K=;
[ -z "$geom" -o -n "$TMP" ] || fatal "Bad geometry: $geom"
[ -z "$TMP" ] || eval $TMP
[ "$W" = 0 -o -z "$K" ] || W="${W}000"
[ "$H" = 0 -o -z "$K" ] || H="${H}000"
[ "$X" = 0 -o -z "$K" ] || X="${X}000"
[ "$Y" = 0 -o -z "$K" ] || Y="${Y}000"

if [ -n "$verbose" ]; then
  echo "map:        $map -> $outmap"
  echo "image:      $img -> $outimg"
  echo "name:       $old_name -> $name"
  echo "scale:      $scale"
  echo "cmap style: $style"
  echo "lon0:       $lon0"
fi

zone="$(printf "$X" | head -c -6)"
X="$(printf "$X" | tail -c 6)"
[ -z "$zone" -o -n "$lon0" ] || lon0="$((6*$zone-3))"

[ -z "$geom" -o -n "$lon0" ] ||
  fatal "Geometry is set but lon0 can't be found. Use -l option."

dW=;dH=;dX=;dY=;dK=;
if [ -n "$geom" ]; then
  dst_geom="$(echo "bb_bck ${W}x${H}+${X}+${Y}" |
    convs_map2pt "$map" pulkovo tmerc "lon0=$lon0")"
  TMP="$(printf "$dst_geom" |
    sed -n "s/^$geom_regexp\$/dW=\1; dH=\2; dX=\3; dY=\4; dK=\5;/p")"

  [ -z "$dst_geom" -o -n "$TMP" ] || fatal "Bad geometry: $dst_geom"
  [ -z "$TMP" ] || eval $TMP
  [ "$dW" = 0 -o -z "$dK" ] || dW="${dW}000"
  [ "$dH" = 0 -o -z "$dK" ] || dH="${dH}000"
  [ "$dX" = 0 -o -z "$dK" ] || dX="${dX}000"
  [ "$dY" = 0 -o -z "$dK" ] || dY="${dY}000"
  echo "map_geom:   ${W}x${H}+$X+$Y"
  echo "img_geom:   ${dW}x${dH}+$dX+$dY"
fi



# cropping and rescaling image

cmd=
if   [ -z "${img##*.png}" ]; then cmd="pngtopnm $img"
elif [ -z "${img##*.jpg}" ]; then cmd="djpeg $img"
else fatal "Unsupported image format for $img"
fi

if [ -n "$dW" -a -n "$dH" -a -n "$dX" -a -n "$dY" ]; then
  cmd="$cmd | pnmcut $dX $dY $dW $dH"
fi

if [ "$(echo "$scale != 1" | bc)" = 1 ]; then
  cmd="$cmd | pnmscale $scale"
fi

if [ -z "${img##*.png}" ]; then
  cmd="$cmd | pnmremap -mapfile=$cmap"
  [ -n "$verbose" ] || cmd="$cmd 2> /dev/null"
fi

if   [ -z "${img##*.png}" ]; then cmd="$cmd | pnmtopng > $outimg"
elif [ -z "${img##*.jpg}" ]; then cmd="$cmd | cjpeg > $outimg"
else fatal "Unsupported image format for $img"
fi

[ -n "$verbose" ] &&
   echo "Executing: $cmd" ||
   cmd="$cmd 2> /dev/null"
eval $cmd

# cropping and rescaling map

cmd="mapsoft_convert"

if [ -n "$dX" -a -n "$dY" ]; then
  cmd="$cmd --shift_maps=-$dX,-$dY"
fi

if [ "$scale" != "1" ]; then
  cmd="$cmd --rescale_maps=$scale"
fi

cmd="$cmd $map -o $outmap"

[ -n "$verbose" ] &&
   echo "Executing: $cmd" ||
   cmd="$cmd 2> /dev/null"
eval $cmd

# setting new name and file
quote_sed_regexp_variable outimg_q "${outimg##*/}"
quote_sed_regexp_variable name_q   "$name"
sed -i "3s/^.*\$/$outimg_q\r/" "$outmap"
sed -i "2s/^.*\$/$name_q\r/"   "$outmap"

[ -z "${tmpmap:-}" ] || rm -f -- "$tmpmap"
[ -z "${tmpimg:-}" ] || rm -f -- "$tmpimg"
