supported() {
	echo "the following games are supported:"
	echo
	printf "\t    name\tdescription\n"
	printf "\t    ----\t-----------\n"

	find $SUPPORTED -type f | grep -v '\.svn' | grep -v 'swp$' | sort |
	while read file; do
		. $file
		printf "\t%8s\t%s\n" "$SHORTNAME" "$LONGNAME"
	done
}
options() {
	echo "game-data-packager arguments:"
	echo "        -i            install the generated package"
	echo "        -n            do not install the generated package (requires -d, default)"
	echo "        -d OUTDIR     write the generated .deb(s) to OUTDIR"
}

usage() {
	echo "usage:"
	printf "\tgame-data-packager [game-data-packager-args] game [game-args]\n"
	echo
	options
	echo
	supported
	echo
	echo "run game-data-packager [game] to see game-specific arguments."
	echo
}

set +u
if [ -n "$DEBUG" ]; then
debug() {
		echo "DEBUG: $*" >&2
}
else
debug() { :; }
fi
set -u

warn() {
	echo "WARNING: $*" >&2
}

## die(string,retcode)
##      end the program, complaining with string on stderr
##      and returning retcode if supplied, 2 if not.
die() { 
    if [ $# -lt 2 ]; then
        RET=2
    else
        RET=$2
    fi
	echo $0: $1 >&2
	exit $RET
}

## verify_md5sum(file,sum)
##      calculates the md5sum of file and compares it to sum.
##      if the sum doesn't match, complains on stderr and causes the program
##      to exit.
verify_md5sum() {
	FILE=$1
	GOODSUM=$2
	SUM=`md5sum $FILE|cut -d' ' -f1`
	[ "$SUM" = "$GOODSUM" ] || die "$FILE's md5 checksum is unknown"
}

## verify_md5sum_alternatives(file,sums)
##      calculates the md5sum of file and compares it to sums (comma-separated).
##      if the sum doesn't match any of them, complains on stderr and causes
##      the program to exit.
verify_md5sum_alternatives() {
	FILE=$1
	GOODSUMS=$2
	SUM=`md5sum $FILE|cut -d' ' -f1`
	case ",$GOODSUMS," in
		(*,$SUM,*)
			;;
		(*)
			die "$FILE's md5 checksum $SUM is unknown"
			;;
	esac
}

## verify_directory(dir)
##      ensures dir is a directory, or complains on stderr
##      and causes the program to exit.
verify_directory() {
	DIR=$1
	[ -d "$DIR" ] || die "$DIR is not a directory" 
}

## verify_file(file)
##      ensures file is a file, or complains on stderr
##      and causes the program to exit.
verify_file() {
	FILE=$1
	[ -f "$FILE" ] || die "$FILE is not a file"
}

## slipstream(deb,relpath,file1,file2...)
##      insert file1,file2... into the deb, under the
##      path 'relpath', relative to the package root, e.g.:
##          slipstream(deb, 'usr/share/doc', 'README', 'copyright')
##              => /usr/share/doc/README
##              => /usr/share/doc/copyright
##      prerequisites:
##        * $WORKDIR must be defined to a directory within which
##          slipstream can do it's work (somewhere writeable)
# TODO: this assumes every file is going to go in the same RELPATH. hmm.
slipstream() {
	DEB="$1"     # the .deb file we are going to mangle
	RELPATH="$2" # relative path in the unpacked .deb
	shift 2

	OLDWD=`pwd`
	cd "$WORKDIR"

	slipstream_permcheck "$DEB"
	slipstream_unpack "$DEB"

	while [ "$#" -gt 0 ]; do
		file="$1"
		destpath="$RELPATH"
		if [ "x${RELPATH%/}" != "x${RELPATH}" ]; then
			# RELPATH ends with /; append the basename of the
			# file (e.g. pak0.pk3)
			destpath="${RELPATH}${file##*/}"
		fi
		slipstream_file "$file" "$destpath"
		shift
	done

	slipstream_instsize
	slipstream_repack "$DEB"
	slipstream_cleanup

	cd "$OLDWD"
}

## slipstream_permcheck(deb)
##      ensures that the file deb can be written to and
##      that the current working directory is writeable
slipstream_permcheck() {
	DEB="$1"

	# ensure we can write to $DEB
	if [ ! -w "$DEB" ]; then
		ls -l "$DEB"
		die "wrong permissions on $DEB (I can't write to it)"
	fi

	# ensure we can write to the workdir
	if [ ! -w . ]; then
		die "cannot write to $PWD"
	fi
}

## slipstream_unpack(deb)
##      unpacks the deb file into "./slipstream_unpacked"
##      and the control data into "./DEBIAN"
slipstream_unpack() {
	DEB="$1"
	dpkg-deb -e "$DEB" "./DEBIAN"
	dpkg-deb -x "$DEB" "./slipstream.unpacked"
}

## slipstream_file(file,destpath)
##      copies the file into "./slipstream_unpacked/$destpath",
##      calculates the files md5sum and adds it to the md5sums
##      file in the control area.
slipstream_file() {
	file="$1"
	destpath="$2"

	cp -p "$file" "./slipstream.unpacked/$destpath"
	chmod 644 "./slipstream.unpacked/$destpath"

	# add a line to md5sums
	cd slipstream.unpacked
	md5sum "$destpath" >> "../DEBIAN/md5sums"
	cd ..
}

##  slipstream_instsize
##      calculates the installed size of the deb, (based on
##      the contents of the ./slipstream_unpacked directory)
##      and writes the result to the control file in the
##      control area.
slipstream_instsize() {
	# figure out the new installed-size
	INSTSIZE=`du -sk ./slipstream.unpacked | cut -f1`
	sed -i  "s/^Installed-Size.*/Installed-Size: $INSTSIZE/" \
		"./DEBIAN/control"
}

## slipstream_repack(deb)
##      writes a new debian package over deb, packing
##      the files from ./slipstream_unpacked inside,
##      using the control area in ./DEBIAN
slipstream_repack() {
	DEB="$1"     # the .deb file we are going to mangle

	# repack
	mv DEBIAN slipstream.unpacked
	# XXX: store output in a temporary file, then cat the file if
	# dpkg-deb fails for some reason. (this is all to hide a non-
	# suppressable "building package foo in ..." message)
	fakeroot dpkg-deb -b slipstream.unpacked "$DEB" >/dev/null

}

## slipstream_cleanup()
##      removes the ./slipstream_unpacked directory.
slipstream_cleanup() {
	rm -rf ./slipstream.unpacked
}

# stuff relating to installing the generated packages ########################

## install_deb(deb)
##      uses sudo and dpkg to install the supplied .deb file
# TODO: configurable priviledge escalation method (not hardcoded sudo)
# TODO: configurable package installation method (not hardcoded dpkg)
install_deb() {
	DEB="$1"
    echo "using su(1) to obtain root privileges and install the package"
	su -c "dpkg -i \"$DEB\""
}

## unravel(path)
##      convert 'path' from relative to absolute
##      if it does not begin with a slash.
unravel() {
	FILE="$1"
	if echo "$FILE" | grep ^/ >/dev/null; then
		:
	else
		# assume a relative path
		FILE="$PWD/$FILE"
	fi

	echo $FILE
}

if [ -f ./debian/changelog ]; then
    GAME_PACKAGE_VERSION=`dpkg-parsechangelog -ldebian/changelog --format \
        rfc822 | grep Version | cut -d' ' -f2`
else
    GAME_PACKAGE_VERSION=`dpkg-query --showformat='${Version}\n' \
        --show game-data-packager`
fi

gdp_unzip() {
    zipfile="$1"
    shift
    if which 7za >/dev/null; then
        debug "using 7za"
        7za e -y "$zipfile" "$@" >/dev/null
    elif which 7z >/dev/null; then
        debug "using 7z"
        7z e -y "$zipfile" "$@" >/dev/null
    else
        debug "using unzip"
        unzip -qqo "$zipfile" "$@"
    fi
}

## ifind(base,file)
##      case-insensitive search for file in base
ifind() {
  base="$1"
  file="$2"
  find "$base" -iwholename "$base/$file"
}
