#!/bin/bash

# xgridfit: a launcher for the Xgridfit compiler.
# Copyright (c) 2006-2009 by Peter S. Baker
# GNU Public License

VERS=@version@
XSLT_DIR=@xgridfit_dir@/lib/
# XSLT_DIR=/usr/local/share/xml/xgridfit/lib/
RUNSCRIPT=xgridfit-python.xsl
TMP_FILE=''
DELTMP=0
PARAMLIST=''
VALID=1
OUTEXT=.py
OUTSCRIPT=''
OUT_TO_FONTFORGE=1
COMPILE_TEMPLATE='xsltproc --xinclude @params@ @outfile-t@ @xslt@ @xgf@'
PARAM_TEMPLATE='--stringparam @pname@ @arg@'
OUTFILE_TEMPLATE='--output @outfile@'
VALID_TEMPLATE='xmllint --xinclude --noout --relaxng @schema@ @xgf@'
COMPILE_JAR=''
VALID_JAR=''
SCHEMA_TYPE='rng'
MKTEMP_CMD='mktemp -t xgridfit.XXXXXXXXXX'
SUPPRESS_COMPILE=1
ECHO_COMMANDS=1
SILENT_MODE=1
ECHO_TIME=1
CANNOT_PIPE=1
SCRIPT_LANG='py'

gettemplates() {
    if [ -f $1 ]
        then
        if grep -q COMPILE_TEMPLATE $1
            then
	    COMPILE_TEMPLATE=`grep COMPILE_TEMPLATE $1 | sed s/COMPILE_TEMPLATE=//`
        fi
	if echo $COMPILE_TEMPLATE | grep -q "@outfile@"
	then
	    echo 1>&2
	    echo "Configuration file $1 is obsolete!" 1>&2
	    echo "Please run xgfconfig -p <processor>." 1>&2
	    echo 1>&2
	    exit 1
	fi
        if grep -q PARAM_TEMPLATE $1
            then
	    PARAM_TEMPLATE=`grep PARAM_TEMPLATE $1 | sed s/PARAM_TEMPLATE=//`
        fi
	if grep -q OUTFILE_TEMPLATE $1
            then
	    OUTFILE_TEMPLATE=`grep OUTFILE_TEMPLATE $1 | sed s/OUTFILE_TEMPLATE=//`
        fi
        if grep -q VALID_TEMPLATE $1
            then
	    VALID_TEMPLATE=`grep VALID_TEMPLATE $1 | sed s/VALID_TEMPLATE=//`
        fi
        if grep -q COMPILE_JAR $1
            then
	    COMPILE_JAR=`grep COMPILE_JAR $1 | sed s/COMPILE_JAR=//`
        fi
        if grep -q VALID_JAR $1
            then
	    VALID_JAR=`grep VALID_JAR $1 | sed s/VALID_JAR=//`
        fi
        if grep -q SCHEMA_TYPE $1
            then
	    SCHEMA_TYPE=`grep SCHEMA_TYPE $1 | sed s/SCHEMA_TYPE=//`
        fi
    fi
}

usage() {
    cat <<Here-is-the-usage-text

usage: xgridfit [options] file.{xgf or xml}

Options:
 -h        display this help message
 -a num    size of TrueType stack
 -A        auto-instruct the font before installing Xgridfit
               programming (merge-mode only)
 -b num    delta break value
 -c yes|no compile functions, control values, pre-program and
               maxp entries (default is "yes")
 -C gray|black|white
           default color of rounded distances (default is "gray")
 -D        delete all instruction-related info before installing
               Xgridfit programming (merge-mode only)
 -d        run in debug mode (output file has extension .debug)
 -e        echo the commands that launch validator and processor
 -E        report the time (in seconds) used for this run of Xgridfit
 -f        Pipe generated script to FontForge; do not save
 -F file   Store font information in a file instead of in FontForge's
               font.persistent object (merge-mode only)
 -g glyph  compile only "glyph"
 -G yes|no initialize graphics state tracking in glyph programs
               (default is "yes")
 -H yes|no auto-hint the font before auto-instructing (default is
               "yes"; has no effect except with -A)
 -i file   file to be input by generated script
 -l py|ff  language of script to be output: Python or native FontForge
               (default is Python)
 -m        run in merge-mode
 -o file   file to be output by generated script
 -O file   script file to be output by Xgridfit
 -p num    push break value
 -P yes|no combine Xgridfit pre-program with the font's prep table
               (merge-mode only; default is "yes")
 -q        run in quiet mode
 -s num    max places in storage area (variables)
 -S name   save script for each glyph in file name_glyphname.py
               (works only with option -l ff)
 -t num    max points in twilight zone
 -T file   temporary file for XInclude results
 -v        show version number and exit
 -V        Validate an Xgridfit program before compiling
 -x        Do not compile. Validation is performed if requested
 -z file   name of separate script file for output of <outfile>
               (works only with options -l ff -S)

Note: Options always override settings in the Xgridfit program file.

Here-is-the-usage-text
}

fixparam () {
    PARAMLIST=$PARAMLIST' '`echo $PARAM_TEMPLATE | sed -e "s%@pname@%$1%" -e "s%@arg@%$2%"`
}

parseopts () {
  while getopts "AdDefEhmqvVxa:b:c:C:F:g:G:H:i:l:o:O:p:P:s:S:t:T:z:" optname
    do
    case "$optname" in
      "a")
        fixparam max-stack $OPTARG
        ;;
      "A")
        fixparam auto-instr yes
        ;;
      "b")
        fixparam delta-break $OPTARG
        ;;
      "c")
        fixparam compile-globals $OPTARG
        ;;
      "C")
        fixparam color $OPTARG
        ;;
      "d")
        RUNSCRIPT=xgridfit-debug.xsl
        OUTEXT=.debug
	CANNOT_PIPE=0
        ;;
      "D")
        fixparam delete-all yes
        ;;
      "e")
        ECHO_COMMANDS=0
	;;
      "E")
	ECHO_TIME=0
	;;
      "f")
	OUT_TO_FONTFORGE=0
	COMPILE_TEMPLATE=`echo $COMPILE_TEMPLATE | sed -e "s/ @outfile-t@//"`
	;;
      "F")
	fixparam datafile $OPTARG
        ;;
      "g")
        fixparam glyph-select $OPTARG
        ;;
      "G")
        fixparam init-graphics $OPTARG
        ;;
      "h")
        usage
        exit 0
        ;;
      "H")
        fixparam auto-hint $OPTARG
        ;;
      "i")
        fixparam infile $OPTARG
        ;;
      "l")
	    case $OPTARG in
		ff | fontforge | FontForge | FONTFORGE)
		    RUNSCRIPT=xgridfit.xsl
		    OUTEXT=.pe
		    SCRIPT_LANG='ff'
		    ;;
		py | python | Python | PYTHON)
		    RUNSCRIPT=xgridfit-python.xsl
		    OUTEXT=.py
		    SCRIPT_LANG='py'
		    ;;
		*)
		    echo "-l option must be either ff or py"
		    exit 1
		    ;;
	    esac
	;;
      "m")
	    RUNSCRIPT=xgridfit-merge.xsl
	    OUTEXT=.py
	    SCRIPT_LANG='py'
	    ;;
      "o")
        fixparam outfile $OPTARG
        ;;
      "O")
        OUTSCRIPT=$OPTARG
        ;;
      "p")
        fixparam push-break $OPTARG
        ;;
      "P")
        fixparam combine-prep $OPTARG
        ;;
      "q")
        fixparam silent-mode yes
	SILENT_MODE=0
        ;;
      "s")
        fixparam max-storage $OPTARG
        ;;
      "S")
        fixparam outfile-base $OPTARG
	CANNOT_PIPE=0
        ;;
      "t")
        fixparam max-twilight-points $OPTARG
        ;;
      "T")
        TMP_FILE=$OPTARG
	DELTMP=1
	if [ -f $TMP_FILE ]
	    then
	    mv -f $TMP_FILE ${TMP_FILE}.bak
	fi
        ;;
      "v")
        echo $VERS
        exit 0
        ;;
      "V")
        VALID=0
        ;;
      "x")
	SUPPRESS_COMPILE=0
	;;
      "z")
        fixparam outfile-script-name $OPTARG
	CANNOT_PIPE=0
        ;;
      "\?")
        usage 1>&2
        exit 1
        ;;
      ":")
        usage 1>&2
        exit 1
        ;;
      *)
        usage 1>&2
	exit 1
        ;;
    esac
  done
  return $OPTIND
}

runscript () {
    if [ $OUT_TO_FONTFORGE -eq 0 -a $CANNOT_PIPE -eq 0 ]
	then
	echo "Error: -d, -S and -z options are incompatible with -f" 1>&2
	exit 1
    fi
    START_TIME=`date +"%s"`
    for f in "$@"
      do
      if [ ! -f "$f" ]; then
          echo "Error: file $f not found" 1>&2
          exit 1
      fi
      HAVE_TMP_FILE=1
      grep -q "http://www\.w3\.org/2001/XInclude" $f
      USING_XINCLUDE=$?
      echo $COMPILE_TEMPLATE | grep -q "xsltproc"
      COMPILER_CAN_XINCLUDE=$?
      echo $VALID_TEMPLATE | grep -q "xmllint"
      VALIDATOR_CAN_XINCLUDE=$?
      test $VALIDATOR_CAN_XINCLUDE -ne 0 -a $VALID -eq 0
      VALIDATOR_NEEDS_TMP_FILE=$?
      test $COMPILER_CAN_XINCLUDE -ne 0 -o $VALIDATOR_NEEDS_TMP_FILE -eq 0
      UNABLE_TO_XINCLUDE=$?
      if [ $UNABLE_TO_XINCLUDE -eq 0 -a $USING_XINCLUDE -eq 0 ]
          then
	  if [ ${#TMP_FILE} -eq 0 ]
	      then
	      if uname | grep -q "Darwin"
		  then
		  MKTEMP_CMD='mktemp -t xgridfit'
	      fi
	      TMP_FILE=`$MKTEMP_CMD` || exit 1
	  fi
	  xmllint --xinclude $f >> $TMP_FILE || exit 1
	  HAVE_TMP_FILE=0
      fi
      BASENAME=$f
      if echo $BASENAME | grep -q "\.xgf$"
          then
          BASENAME=`basename $BASENAME .xgf`
      elif echo $BASENAME | grep -q "\.xml$"
          then
          BASENAME=`basename $BASENAME .xml`
      fi
      OSCRIPT=$OUTSCRIPT
      if [ ${#OSCRIPT} -eq 0 ]
          then OSCRIPT=${BASENAME}${OUTEXT}
      fi
      OUTFILE_T=`echo $OUTFILE_TEMPLATE | sed -e "s%@outfile@%$OSCRIPT%"`
      if [ $VALID -eq 0 ]
        then
	  if [ $USING_XINCLUDE -eq 0 -a $VALIDATOR_NEEDS_TMP_FILE -eq 0 ]
	      then
	      TMP_FILE_NAME=$TMP_FILE
	      else
	      TMP_FILE_NAME=$f
	  fi
          SCHEMA=@xgridfit_dir@/schemas/xgridfit.$SCHEMA_TYPE
#         SCHEMA=/usr/local/share/xgridfit/schemas/xgridfit.$SCHEMA_TYPE
	  if [ $SILENT_MODE -ne 0 ]
	      then
              echo "Validating against $SCHEMA ..."
	  fi
          CMD_FINAL=`echo $VALID_TEMPLATE | sed -e "s%@schema@%$SCHEMA%" \
                  -e "s%@xgf@%$TMP_FILE_NAME%" \
                  -e "s%@jar@%$VALID_JAR%"`
	  if [ $ECHO_COMMANDS -eq 0 ]
	      then
	      echo $CMD_FINAL
	  fi
          eval $CMD_FINAL
          if [ $? -ne 0 ]
              then
              exit 1
          fi
      fi
      if grep -q "<xgridfit" $f
          then
	  if [ $COMPILER_CAN_XINCLUDE -ne 0 -a $USING_XINCLUDE -eq 0 ]
	      then
	      TMP_FILE_NAME=$TMP_FILE
	      else
	      TMP_FILE_NAME=$f
	  fi
          CMD_FINAL=`echo $COMPILE_TEMPLATE | sed -e "s%@outfile-t@%$OUTFILE_T%" \
                  -e "s%@xslt@%${XSLT_DIR}${RUNSCRIPT}%" \
                  -e "s%@xgf@%$TMP_FILE_NAME%" \
                  -e "s%@params@%$PARAMLIST%" \
                  -e "s%@jar@%$COMPILE_JAR%"`
	  if [ $OUT_TO_FONTFORGE -eq 0 ]
	  then
	      which fontforge > /dev/null
	      if [ $? -eq 0 ]
	      then
		  CMD_FINAL=$CMD_FINAL" | fontforge -lang=$SCRIPT_LANG -script -"
	      else
		  echo "Error: -f option requires FontForge" 1>&2
		  exit 1
	      fi
	  fi
	  if [ $ECHO_COMMANDS -eq 0 ]
	      then
	      echo $CMD_FINAL
	  fi
	  if [ $SUPPRESS_COMPILE -ne 0 ]
	      then
              eval $CMD_FINAL
	  fi
      else
          echo "Error: file \"$f\" does not exist or contains no <xgridfit> element." 1>&2
      fi
      if [ $HAVE_TMP_FILE -eq 0 -a $DELTMP -eq 0 ]
	  then
	  rm -f $TMP_FILE
      fi
    done
    END_TIME=`date +"%s"`
    if [ $ECHO_TIME -eq 0 ]
    then
	echo "Finished in "$(( $END_TIME - $START_TIME ))" seconds"
    fi
}

if [ $# -lt 1 ]
    then
    usage 1>&2
    exit 1
fi
gettemplates @xgridfit_dir@/settings
# gettemplates /usr/local/share/xgridfit/settings
gettemplates ~/.xgridfit
if [ "$XGRIDFIT_OUTPUT_LANG" ]
    then
    case "$XGRIDFIT_OUTPUT_LANG" in
	py | python | PY | Python | PYTHON)
	    RUNSCRIPT=xgridfit-python.xsl
	    SCRIPT_LANG='py'
	    OUTEXT=.py
	    ;;
	ff | fontforge | FF | FontForge | FONTFORGE)
	    RUNSCRIPT=xgridfit.xsl
	    SCRIPT_LANG='ff'
	    OUTEXT=.pe
	    ;;
    esac
fi
parseopts "$@"
argstart=$?
runscript "${@:$argstart}"
