#!/bin/sh
#
#   Usage: ncgm2pdf [options] file.ncgm|dir_name [file.ncgm ...] [dir_name ...]
# Purpose: Convert NCAR graphics meta files (ncgm aka gmeta) to pdf
#
# If the input file is named "file.ncgm" then the output file will be
# named "file.pdf"
#
# If a directory name appears on the command line then all *.ncgm files found
# in that directory will be converted to PDF.
#
# Output pdf files will be placed into a subdirectory of the directory
# that contains the gmeta file. This subdirectory will be named "PDF".
#
# Options:
# All options begin with a dash (-) and must appear before any other command line arg
# Single letter options may be combined, as in "ncgm2pdf -fx dir ..."
#   -a   ...convert all *.ncgm files found in this directory
#           When -a is used any file or directory names found on the
#           command line are ignored.
#   -f   ...force overwrite of existing pdf files
#   -x   ...expand each multi page output pdf file
#           Create a sub directory named "expanded_file" containing a
#           number of pdf files, each containing a single page per file.
#   -v   ...increase verbosity
#   -q   ...run quietly, keeping screen output to a minimum
#   -h   ...display usage info
########################################################################
#
# Larry Solheim Jun,2009

FULLPATH=`type $0|awk '{print $3}'` # pathname of this script
Runame=`basename $FULLPATH`
usage() {
  [ -n "$1" ] && echo >&2 "${Runame}:" "$@"
  echo >&2 " "
  sed >&2 -n '/^###/q; s/^#$/# /; s/^ *$/# /; 3,$s/^# //p;' "$FULLPATH"
  exit 1;
}

bail(){
  cmd=''
  while getopts c: opt
  do
    case $opt in
      c) cmd="$OPTARG" ;;
    esac
  done
  shift `expr $OPTIND - 1`
  [ -n "$cmd" ] && $cmd
  echo "${Runame}: *** ERROR *** $*"
  exit 1
}

# A time stamp used with temporary file names
stamp=`date "+%j%H%M%S"$$`

# Initialize variables and set defaults
verbose=1
PTITLE=''

# convert_all = 1 flags conversion of all *.ncgm files found in the current dir
# Otherwise a list of names or directories must be supplied on the command line
convert_all=0

# expand = 1 means create individual pdfs of each page in the original file
expand=0

# force = 1 means overwrite any existing pdf files
force=0

# quiet = 1 means no produce no output, except error messages
quiet=0

# The value of depth is used to set or not set a string that will be prefixed to
# certain path names for use in diagnostic output
depth=0

# pdfdir is the name of a subdir into which all new pdf files will be placed
pdfdir="PDF"

# Some NCAR graphics programs are required to manipulate ncgm files
MED=$NCARG_ROOT/bin/med
CTRANS=$NCARG_ROOT/bin/ctrans
NCGMSTAT=$NCARG_ROOT/bin/ncgmstat

# Check for availability of these commands
type $MED      >/dev/null || MED=''
type $CTRANS   >/dev/null || bail "ctrans is required"
type $NCGMSTAT >/dev/null || NCGMSTAT=''
type ps2ps     >/dev/null || bail "ps2ps is required"
type ps2pdf    >/dev/null || bail "ps2pdf is required"

# process command line arguments
while getopts adfo:hqvx opt
do
  case $opt in
    a) convert_all=1 ;;
    f) force=1 ;;
    q) quiet=1 ;;
    d) depth=1 ;;
    x) expand=1 ;;
    o) outfile="$OPTARG" ;;
    v) verbose=`expr $verbose + 1` ;;
    h) usage ;;
    -) shift; break ;; # end of options
    ?) usage $USAGE   ;;
  esac
done
shift `expr $OPTIND - 1`

# Reset verbose if running quiet
[ $quiet -eq 1 ] && verbose=0

if [ $convert_all -eq 1 ]; then
  # Convert every *.ncgm file in the cwd
  inlist=`ls -1 *.ncgm`
  [ -z "$inlist" ] && usage "No .ncgm files were found in `pwd`"
else
  [ $# -eq 0 ] && \
   usage "At least one file name or directory name is required unless the -a option is used."
  inlist="$*"
fi

# Remember where we are now
CWD=`pwd`

if [ $depth -eq 1 ]; then
  # Prefix certain diagnotic comments with this dir name
  dirpfx=`echo $CWD|sed 's/^.*\/\(.*\)/\1\//'`${pdfdir}/
else
  dirpfx="$pdfdir/"
fi

for fname in $inlist; do

  # Ensure we start the each interation in the correct dir
  cd $CWD

  if [ -d "$fname" ]; then
    # If fname is a dir then cd there and run this script
    # converting all ncgm files found in that dir
    cd $fname
    curr_opts='-a -d'
    [ $force -eq 1 ] && curr_opts="$curr_opts -f"
    [ $quiet -eq 1 ] && curr_opts="$curr_opts -q"
    [ $expand -eq 1 ] && curr_opts="$curr_opts -x"
    $FULLPATH $curr_opts
    cd $CWD
  else
    # This should be an ordinary file
    [ -s $fname ] || bail "${dirpfx}$fname is missing or empty"
    [ $verbose -gt 1 ] && echo "processing ${dirpfx}$fname"

    # If a subdir named "$pdfdir" does not exist create it
    [ ! -d "$pdfdir" ] && mkdir -m 775 $pdfdir

    cd $pdfdir || bail "Unable to cd $pdfdir"

    # Verify that the output pdf file does not exist or
    # that the force option was invoked by the user
    pdfout=`basename $fname .ncgm`.pdf
    if [ -s "$pdfout" -a $force -eq 0 ]; then
      [ $verbose -gt 0 ] && \
        echo "*** WARNING *** ${dirpfx}$pdfout \texists. Use -f to force overwrite."
      continue
    fi

    # Convert to postscript
    basencgm=`basename $fname .ncgm`
    thisps=_${stamp}_${basencgm}.ps
    $CTRANS -d ps.color ${CWD}/$fname > $thisps || \
      bail -c "rm $thisps" "Cannot convert ${dirpfx}$fname to ps."

    # Run this ps file through ps2ps in an attempt to optimize somewhat
    ps2ps $thisps ${thisps}_tmp
    mv ${thisps}_tmp $thisps

    # Convert to pdf
    ps2pdf $thisps $pdfout || bail "Cannot convert ${dirpfx}$fname to pdf."
    chmod a+r $pdfout
    [ $verbose -gt 0 ] && echo "Created file ${dirpfx}$pdfout"

    if [ $expand -eq 1 ]; then
      # Create a subdirectory named for the current file and
      # cd there to expand the current ps file
      expand_dir=expanded_$basencgm
      if [ -d "$expand_dir" ]; then
        # remove this dir and recreate it when the user
        # has invoked the force option
        if [ $force -eq 1 ]; then
          rm -fr $expand_dir || bail "Cannot remove ${dirpfx}$expand_dir"
          mkdir -m 775 $expand_dir
        fi
      else
        # Otherwise create this dir
        mkdir -m 775 $expand_dir
      fi
      # Put a copy of the current ps file in the expand dir then cd there
      # and create individual pdf files for each page in the ps file
      cp $thisps $expand_dir || bail "Cannot cp $thisps $expand_dir"
      cd $expand_dir || bail "Cannot cd $expand_dir"
      # ps2ps wants the output name on the command line but doesn't use it
      # Instead, ps files for each page are created and named according to
      # the OutputFile template
      ps2ps -sOutputFile=_%03d_$thisps $thisps ${thisps}_tmp || \
        bail "Unable to expand ${dirpfx}$fname to one file per page."
      rm $thisps
      # Test for ps files
      pslist=`ls -1 _[0-9][0-9][0-9]*.ps 2>/dev/null`
      [ -z "$pslist" ] && bail "Unable to find any postscript files in ${dirpfx}$expand_dir"
      for psfile in _[0-9][0-9][0-9]*.ps; do
        pfx=`echo $psfile|sed 's/^\(_[0-9][0-9]*\)_.*$/\1/'`
        pdffile="page${pfx}.pdf"
        if [ -s $pdffile -a $force -eq 0 ]; then
          # Do not overwrite the pdf file when the user has invoked the force option
          rm $psfile
          [ $verbose -gt 0 ] && \
            echo "*** WARNING *** ${dirpfx}$expand_dir/$pdffile \texists. Use -f to force overwrite."
          continue
        fi
        ps2pdf $psfile $pdffile
        chmod a+r $pdffile
        rm $psfile
        [ $verbose -gt 0 ] && echo "Created file ${dirpfx}$expand_dir/$pdffile"
      done
      cd $CWD/$pdfdir
    fi

    # Cean up
    rm $thisps
  fi

done
