#!/bin/sh

# History
# 2024-07-10:  Now includes ALPHA_OVERRIDE_IMAGE
# 2019-08-20:  Added -t option.
# 2017-04-17:  Fixed bug when GIANT_DATA_DIR was used with textures.
# 2014-12-17:  Updated to use GIANT_DATA_DIR in addition to BIO_DATA_DIR
# 2012-04-13:  Initial implementation

data_dir=${GIANT_DATA_DIR%/}

if [ "$data_dir" = "" ]; then
  data_dir=${BIO_DATA_DIR%/}
fi

fixup_fn() {
  fn=${1#$data_dir/}        # remove the workspace path
  fn=${fn#'$BIO_DATA_DIR'/} # remove the string "$BIO_DATA_DIR/"
  fn=${fn#'$GIANT_DATA_DIR'/} # remove the string "$BIO_DATA_DIR/"
  fn=${fn#'$NU_DATA_DIR'/}  # remove the string "$NU_DATA_DIR/"

  (
    cd $data_dir
    if [ ! -f "$fn" ] ; then
      if [ ! -f "$fn.gz" ]; then
        echo "Missing file $fn" 1>&2
        echo ""                 # doesn't exist, returning empty string
      else
        echo "$fn.gz"
      fi
    else
      echo $fn
    fi
  )
}

get_includes() {
# recursively finds include files in the given file using the tagfile utility
# this does not handle infinite recursion currently
# handles compressed files
  base_file=$1
  base_file=`eval echo $base_file`

  if [ x"$base_file" != x"" -a ! -f "$base_file" ]; then
    # choose the compressed version of the file if it exists and the 
    # uncompressed doesn't exist
    if [ -f "${base_file}.gz" ]; then
      base_file="${base_file}.gz"
    fi
  fi

  if [ x"$base_file" != x"" -a -f "$base_file" ]; then
    uncompressed_base_file=${base_file%.gz}

    if [ $uncompressed_base_file != $base_file ]; then
      tmp_uncompressed_base_file=${uncompressed_base_file}.tarprj_$$
      gunzip -c $base_file >$tmp_uncompressed_base_file
      tagfile_file=$tmp_uncompressed_base_file
    else
      tagfile_file=$base_file
    fi

    include_file_names=`tagfile -getfile INCLUDE.FILE_NAME $tagfile_file`

    if [ x"$include_file_names" != x"" ]; then
      # pass the result through xargs to join the output into one line
      echo "$include_file_names" | expand_includes | xargs
    fi

    if [ "$uncompressed_base_file" != "$base_file" ]; then
      rm -f $tmp_uncompressed_base_file
    fi
  fi
}

expand_includes() {
  while read include_file_name; do
    echo "$include_file_name"
    get_includes "$include_file_name"
  done
}


full_path_name() {
  # No leading /
  # must be an easier way to do this
  cwd=`pwd`
  dn=`dirname $1`
  cd $dn
  dir=`/bin/pwd`
  cd $cwd
  echo $dir/`basename $1`
}


topmdlfiles () {
  mdl="$1"
  awk -v data_dir=$data_dir '
    function startswith(x,y)
    {
      return substr(x,1,length(y))==y
    }

    function expand(x)
    {
      gsub("\\$BIO_DATA_DIR/","",x);
      gsub("\\$GIANT_DATA_DIR/","",x);
      gsub("\\$NU_DATA_DIR/","",x);
      if (startswith(x,data_dir"/")) {
        x = substr(x,length(data_dir) + 2)
      }
      return x;
    }

    $1=="TEXTURE" { in_texture = 1; }
    in_texture && $1=="NAME:" { print "FILE: "expand($2); }
    in_texture && $1=="ALPHA_OVERRIDE_IMAGE:" { print "FILE: "expand($2); }
    $1=="}" { in_texture = 0; }
    $1=="INCLUDE" { in_include = 1; }
    in_include && $1=="FILE_NAME:" { print "MODEL: "expand($2) }
    $1=="}" { in_include = 0; }
  ' <"$mdl"
}


if [ $# = 0 ]; then
  echo >&2
  echo "Usage: tarmdl <model>" >&2
  echo "  Creates a tar file with the contents of the given .mdl file." >&2
  echo >&2
  echo "Usage: tarmdl -c <name> <model> [<model>...]" >&2
  echo "  Creates a tar file with the given name that has the contents of" >&2
  echo "  all the given .mdl files." >&2
  echo "  If <name> is -, the tar output is written to stdout." >&2
  echo >&2
  echo "Usage: tarmdl -l <model> [<model>...]" >&2
  echo "  Lists the files relative to the given .mdl file." >&2
  echo >&2
  echo "Usage: tarmdl -t <model> [<model>...]" >&2
  echo "  Show the file types and paths of files directly referenced by" >&2
  echo "  the given .mdl files" >&2
  echo >&2
  exit 1
fi

list_only=0
top_only=0

while [ $# -gt 1 ]; do
  if [ x"$1" = x"-l" ]; then
    list_only=1
    shift
  elif [ x"$1" = x'-t' ]; then
    top_only=1
    shift
  elif [ x"$1" = x"-c" ]; then
    shift
    if [ $# = 0 ]; then
      echo "No tar file specified for -c option." >&2
      exit 1
    fi
    tar_file="$1"
    if [ x"$tar_file" != x"-" ]; then
      # strip off .gz or .tar since it will be added back later.
      # Has the side effect of making .tar.gz optional.
      tar_file=`basename "$tar_file" .gz`
      tar_file=`basename "$tar_file" .tar`
      tar_file=`dirname "$1"`/$tar_file
    fi
    shift
  else
    break
  fi
done

if [ $# -gt 1 ]; then
  if [ $list_only = 0 -a $top_only = 0 ]; then
    if [ x"$tar_file" = x ]; then
      echo "tarmdl: you must use -c with multiple files." >&2
      exit 1
    fi
  fi
fi

if [ $top_only = 1 ]; then
  for file in "$@"; do
    topmdlfiles "$file" || exit 1
  done | sort | uniq || exit 1
  exit 0
fi

input_file=$1

textures=""
models=""
for file in "$@"; do
  if [ $file != "[camera]" ]; then
    if [ ! -f $file ]; then
      echo "No such file: $file" >&2
      exit 1
    fi
    model=`full_path_name $file`
    model_inc=`get_includes $model`
    models="$models $model $model_inc"
  fi
done

new_models=""

for model_path in $models; do
  mdl_textures=`awk '
    $1=="TEXTURE" { in_texture=1; }
    in_texture && $1=="NAME:" { print $2; }
    in_texture && $1=="ALPHA_OVERRIDE_IMAGE:" { print $2; }
    $1=="}" { in_texture=0; }
  ' <$model_path`

  textures="$textures $mdl_textures"
  model=`fixup_fn $model_path`
  new_models="$new_models $model"
done

models=$new_models

new_textures=""
for file in $textures; do
  new_textures="$new_textures `fixup_fn $file`"
done

models=$new_models
textures=$new_textures

cwd=`/bin/pwd`
if [ x"$tar_file" = x"" ]; then
  tar_file="$cwd"/`basename $input_file`
fi

if [ x"$tar_file" != x"-" ]; then
  tar_file=$tar_file.tar.gz
fi

# do the tar command
files="$models $textures"
files=`echo $files | xargs -n 1 | sort | uniq`
if [ $list_only = 1 ]; then
  echo "$files"
else
  cd $data_dir
  echo >&2
  echo "Creating $tar_file" >&2
  echo >&2
  tar c -zvf $tar_file $files
fi
