#!/bin/sh
# 0.3.1  02/04/2025  Changed output so it reports the path of the created
#                    tar file at the end.
#        12/18/2024  Fixed missing .wcam files
# 0.3.0  08/19/2019  Added -t option.
# 0.2.4  04/26/2017  Fixed missing .mtl files
# 0.2.3  04/07/2017  Fixed bad error messages if mdl files were missing.
# 0.2.2  08/19/2016  Fixed path resolving issues with asfs and skins.
# 0.2.1  01/21/2016  Support for ASFs referenced in AMCs
#                    Support for OBJs referenced in ASFs
#        12/17/2014  Updated to handle GIANT_DATA_DIR environment variable.
# 0.2.0  06/03/2011  Updated to release version.
# 0.1.0n 06/17/2009  Support for INCLUDEs in dof files.
# 0.1.0m 03/03/2009  Fixed a bug where it would report missing files
#                    if you didn't run taranim from the root of the workspace.
# 0.1.0l 03/02/2009  Support for INCLUDEs in mdl and scl files.
# 0.1.0k 10/02/2008  Better output for -l
# 0.1.0i 04/09/2007  Replaced -m option with -movies and -nomovies options.
# 0.1.0h 04/09/2007  Added -m option.
# 0.1.0g 01/17/2007  Changed the behavior to fix a problem where absolute paths
#                    sometimes were being used unneccisarily.
# 0.1.0f 11/21/2006  Added ability to specify "-" with -c option to output to
#                    stdout.
# 0.1.0e 05/19/2006  Fixed handling of extracting textures from gzipped models.
# 0.1.0d 03/23/2006  Added ability to make multiple anims.
#                    Added -c option.
#        06/03/2005  Fixed problem with movies not having relative path.
#        01/19/2005  Added support for MOVIE tags.
#        01/19/2005  Fixed bug with including sub-anims twice.
#        02/04/2004  Now handles gzipped files.
#        02/04/2004  Now includes textures and non-inlined sub-animations
# 0.1.0  12/27/2001  Initial version.
#
if [ $# = 0 ]; then
  echo "" >&2
  echo "taranim 0.3.1" >&2
  echo >&2
  echo "Usage: taranim [<options>] <anim file>" >&2
  echo "  Create a tar file for the given animation." >&2
  echo >&2
  echo "Usage: taranim -c <tar file> [<options>] <anim file> [<anim file> ...]" >&2
  echo "  Create a tar file for the given animations." >&2
  echo >&2
  echo "Usage: taranim -c - [<options>] <anim file> [<anim file> ...]" >&2
  echo "  Create a tar file for the given animations and write the output" >&2
  echo "  to stdout." >&2
  echo >&2
  echo "Usage: taranim -l [<options>] <anim file> [<anim file> ...]" >&2
  echo "  Only list files that would go in the tar file." >&2
  echo >&2
  echo "Usage: taranim -t [<options>] <anim file> [<anim file> ...]" >&2
  echo "  Lists the files directly used by the animation." >&2
  echo >&2
  echo "Options:" >&2
  echo "  -movies         : Always include movie files." >&2
  echo "  -nomovies       : Never include movie files." >&2
  echo >&2
  exit 1
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
}


list_only=0
top_only=0
include_movies=p
suboptions=""

data_dir=${GIANT_DATA_DIR%/}

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

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
  elif [ x"$1" = x"-movies" ]; then
    shift
    include_movies=1
    suboptions="-movies"
  elif [ x"$1" = x"-nomovies" ]; then
    shift
    include_movies=0
    suboptions="-nomovies"
  else 
    break
  fi
done

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

# platform check

uname_out=`uname`
if [ `expr $uname_out : 'IRIX'` = 4 ]; then
  AWK=nawk
elif [ "$uname_out" = "Linux" ]; then
  AWK=awk
else
  echo "Unknown platform." >&2
  exit 1
fi

anim_file="$1"
shift
if [ ! -f "$anim_file" ]; then
  echo >&2
  echo "Animation file: \"$anim_file\" does not exist." >&2
  echo >&2
  exit 1
fi

fixup_fn() {
  fn=${1#$data_dir/}          # remove the substring equal to the workspace
                              # directory
  fn=${fn#'$BIO_DATA_DIR'/}   # remove the string "$BIO_DATA_DIR/"
  fn=${fn#'$GIANT_DATA_DIR'/} # remove the string "$GIANT_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
  )
}

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

anim_file=`full_path_name $anim_file`

anims=`
  $AWK '
    $1=="ANIMATION:" { print $2 }
  ' <$anim_file
`

models=`
  $AWK '
    $1=="MODEL:" { print $2 }
  ' <$anim_file
`

if [ $top_only != 1 ]; then
  models=`echo $models | xargs -n 1 | expand_includes | xargs`
fi

mappings=`
  $AWK '
    $1=="MAPPING:" { print $2 }
  ' <$anim_file
`
if [ $top_only != 1 ]; then
  mappings=`echo $mappings | xargs -n 1 | expand_includes | xargs`
fi

motions=`
  $AWK '
    $1=="MOTION:" { print $2 }
  ' <$anim_file
`

scalings=`
  $AWK '
    $1=="SCALING:" { print $2 }
  ' <$anim_file
`

if [ $top_only != 1 ]; then
  scalings=`echo $scalings | xargs -n 1 | expand_includes | xargs`
fi


audios=`
  $AWK '
    $1=="AUDIO:" { print $2 }
    $1=="FILENAME:" { print $2 }
  ' <$anim_file
`

movies=`
  $AWK '
    $1=="MOVIE:" { print $2 }
  ' <$anim_file
`

objs=`
  $AWK '
    $1=="WAVEFRONT_OBJ:" { print $2 }
  ' <$anim_file
`

wcams=`
  $AWK '
    $1=="WCAM:" { print $2 }
  ' <$anim_file
`

asfs=`
  $AWK '
    $1=="ASF:" { print $2 }
  ' <$anim_file
`

amcs=`
  $AWK '
    $1=="AMC:" { print $2 }
  ' <$anim_file
`

extra_asfs=`
  for amc in $amcs; do
    amc=$(eval echo $amc)
    $AWK '
      $1==":asf" { print $2 }
    ' <$amc
  done
`

asfs="$asfs $extra_asfs"

extra_objs=`
  for asf in $asfs; do
    asf=$(eval echo $asf)
    $AWK '
      $1=="path" {
        gsub("\"","",$2)
        print $2
      }
    ' <$asf
  done
`
objs="$objs $extra_objs"

mtls=`
  for obj in $objs; do
    obj=$(eval echo $obj)
    $AWK -v objdir=$(dirname $obj) '
       $1=="mtllib" { print objdir"/"$2 }
    ' <$obj
  done
`

#
# To make it so that the command can be executed from any directory,
# we have to create the tar file as if we are in the $BIO_DATA_DIR
# so it will extract properly when extracted to the $BIO_DATA_DIR
#

cwd=`/bin/pwd`

if [ x"$tar_file" = x"" ]; then
  tar_file="$cwd"/`basename $anim_file`
fi

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


#
# process the file names so they tar up nicely relative to $BIO_DATA_DIR.
# set the file names to nothing if they do not exist.
#

anim_file=`fixup_fn $anim_file`

for file in $models; do
  if [ $file != "[camera]" ]; then
    model=`fixup_fn $file`
    model_path=`eval echo $file`
    if [ "$model" != "" ]; then
      if [ $top_only = 0 ]; then
        mdl_textures=`awk '
          $1=="TEXTURE" { in_texture=1; }
          in_texture && $1=="NAME:" { print $2; }
          $1=="}" { in_texture=0; }
        ' <$model_path`
        textures="$textures $mdl_textures"
      fi
      new_models="$new_models $model"
    fi
  fi
done

models=$new_models

for file in $mtls; do
  if [ -f $file ]; then
    mtl_textures=`awk '$1=="map_Ka" || $1=="map_Kd" { print $2 }' $file`
    textures="$textures $mtl_textures"
  fi
done

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

for file in $mappings; do
  if [ $file != "[camera]" ]; then
    new_mappings="$new_mappings `fixup_fn $file`"
  fi
done
mappings=$new_mappings

for file in $motions; do
  new_motions="$new_motions `fixup_fn $file`"
done

motions=$new_motions

for file in $scalings; do
  new_scalings="$new_scalings `fixup_fn $file`"
done

scalings=$new_scalings

for file in $audios; do
  new_audios="$new_audios `fixup_fn $file`"
done

audios=$new_audios

for file in $objs; do
  new_objs="$new_objs `fixup_fn $file`"
done

objs=$new_objs

for file in $mtls; do
  new_mtls="$new_mtls `fixup_fn $file`"
done

mtls=$new_mtls

new_wcams=""

for file in $wcams; do
  new_wcams="$new_wcams `fixup_fn $file`"
done

wcams=$new_wcams


for file in $asfs; do
  new_asfs="$new_asfs `fixup_fn $file`"
done

asfs=$new_asfs

for file in $amcs; do
  new_amcs="$new_amcs `fixup_fn $file`"
done

amcs=$new_amcs
sub_anim_files=""

if [ $top_only = 0 ]; then
  for file in $anims; do
    anim=`eval echo $file`
    sub_anim_files="$sub_anim_files `taranim -l $suboptions $anim`"
  done
else
  for file in $anims; do
    anim=`eval echo $file`
    anim=`fixup_fn "$anim"`
    sub_anim_files="$sub_anim_files $anim"
  done
fi

new_movies=""

for file in $movies; do
  if [ $include_movies = 1 ]; then
    answer=y
  elif [ $include_movies = 0 ]; then
    answer=n
  else
    echo -n "Include movie file $file? " >&2
    read answer
  fi
  if [ x"$answer" = x"y" ]; then
    new_movies="$new_movies `fixup_fn $file`"
  fi
done

movies=$new_movies
rest_files=""
if [ $# -gt 0 ]; then
  for file in "$@"; do
    rest_files="$rest_files "`taranim -l $suboptions "$file"` || exit 1
  done
fi


if [ $top_only = 1 ]; then
  for anim in $sub_anim_files; do
    echo "ANIMATION: $anim"
  done
  for model in $models; do
    echo "MODEL: $model"
  done
  for mapping in $mappings; do
    echo "MAPPING: $mapping"
  done
  for motion in $motions; do
    echo "MOTION: $motion"
  done
  for scaling in $scalings; do
    echo "SCALING: $scaling"
  done
  for file in $asfs $amcs $audios $objs $mtls $wcams $movies $rest_files; do
    echo "FILE: $file"
  done
  exit 0
fi

# do the tar command
files="$anim_file $models $textures $mappings $motions $scalings $asfs $amcs $audios $objs $mtls $wcams $movies $sub_anim_files $rest_files"
files=`echo $files | xargs -n 1 | sort | uniq`
if [ $list_only = 1 ]; then
  echo "$files"
else
  cd $data_dir
  tar c -zvf $tar_file $files || exit 1
  echo >&2
  echo "Created $tar_file" >&2
  echo >&2
fi
