#!/bin/sh

die() {
	echo "$@" >&2
	exit 1
}

# Handle arguments

if [ "$1" != "--help" ] && [ "$1" != "-h" ] ; then
	cd="$(readlink -f "$1")"
	patch="$(readlink -f "$2")"
fi

[ "$patch" = "" ] && die "\
Usage: install-cd path/to/mount/point/ path/to/ArxFatalis_1.21_MULTILANG.exe [output_dir]
or     install-cd path/to/cd.iso path/to/ArxFatalis_1.21_MULTILANG.exe [output_dir]

This script can be used to install the Arx Fatalis data from a CD or ISO.
Files will be verified and renamed as needed by Arx Libertatis.

ArxFatalis_1.21_MULTILANG.exe can be downloaded from the official Arx Fatalis website
at http://www.arkane-studios.com/uk/arx_downloads.php
If you know the language of your CD, you can use the language-specific patch instead."

if [ "$3" = "" ]
	then destdir="$(pwd)"
	else destdir="$(readlink -f "$3")"
fi

cd "$(dirname "$0")"
here="$(pwd)"

echo "Installing Arx Fatalis CD data from \"$cd\" to \"$destdir\".
"

[ -f "$here/install-verify" ] || die "Missing install-verify script."
install_verify_sourced=1
. "$here/install-verify"

# Check for required commands

cabextract=`which cabextract 2> /dev/null`
innoextract=`which innoextract 2> /dev/null`

[ -f "$cabextract" ] \
	|| die "Please install cabextract (http://www.cabextract.org.uk/)"

[ -f "$innoextract" ] \
	|| die "Please install innoextract (http://innoextract.constexpr.org/)"

[ -e "$cd" ] || die "$cd does not exist"
[ -f "$patch" ] || die "$patch does not exist"

if [ ! -d "$cd" ] ; then
	
	fuseiso=`which fuseiso 2> /dev/null`
	fusermount=`which fusermount 2> /dev/null`
	mount=`which mount 2> /dev/null`
	umount=`which umount 2> /dev/null`
	isoinfo=`which isoinfo 2> /dev/null`
	
	if [ ! -f "$fuseiso" ] || [ ! -f "$fusermount" ] ; then
		if [ ! -f "$mount" ] || [ ! -f "$umount" ] || [ "$(id -u)" != "0" ] ; then
			if [ ! -f "$isoinfo" ] ; then
				die "Please install one of the following:
 - fuse and fuseiso (http://fuseiso.sourceforge.net/)
 - mount (and run this script as root)
 - isoinfo from cdrkit (http://cdrkit.org/) or cdrtools (http://cdrecord.berlios.de/)
or manually mount/extract the iso and specify the directory."
			fi
		fi
	fi
fi

# Verify input file

patch_checksum="$("$md5sum" -b "$patch" | sed 's/ .*//')"

case "$patch_checksum" in
	'e66abe5edb113d3e71194b61010a05f3') patch_lang='english' ;;
	'5c877cb679674808587c7acc63e29068') patch_lang='spanish' ;;
	'eb88e3f1be6118f51c544c7b269033d7') patch_lang='french' ;;
	'b9941fd97f2b831806b43e20e014973b') patch_lang='german' ;;
	'a3135aaa71363deec2e72aa8184f48da') patch_lang='italian' ;;
	'00dfbd2698786a298899f148b02fcaea') patch_lang='russian' ;;
	'364c405b26d3c480d516724010c7ecac') patch_lang='multilang' ;;
	*) die "Patch checksum mismatch, got $patch_checksum!" ;;
esac
echo "Patch language: $patch_lang
"

# Prepare output and temp dirs

mkdir -p "$destdir" || exit 1

tempdir="$destdir/arx-install-cd-temp"
srcdir="$tempdir/src"
patchdir="$tempdir/patch"

if [ ! -d "$cd" ] ; then
	iso="$cd"
	cd="$tempdir/cd"
fi

unmount_iso() {
	"$fusermount" -u "$cd" > /dev/null 2>&1
	"$umount" "$cd" > /dev/null 2>&1
}

unmount_iso
rm -rf "$tempdir" 2> /dev/null
mkdir "$tempdir" || exit 1
mkdir "$srcdir" || exit 1
mkdir "$patchdir" || exit 1
cd "$tempdir" || exit 1

# Mount / extract CD image

if [ ! -d "$cd" ] ; then
	
	mkdir "$cd"
	
	mounted=0
	
	if [ -f "$fuseiso" ] && [ -f "$fusermount" ] ; then
		"$fuseiso" "$iso" "$cd" && mounted=1
	fi
	
	if [ $mounted = 0 ] && [ -f "$mount" ] && [ -f "$umount" ] && [ "$(id -u)" = "0" ] ; then
		"$mount" -o loop,ro "$iso" "$cd" && mounted=2
	fi
	
	if [ $mounted = 0 ] && [ -f "$isoinfo" ] ; then
		
		extract_iso() {
			"$isoinfo" -i "$iso" -x "$1" > "$cd/$2"
			[ -s "$cd/$2" ] || rm -f "$cd/$2"
		}
		
		extract_iso "/HANDBUCH/ARX_HAND.PDF;1" "arx_handbuch.pdf"
		
		   extract_iso "/SETUP1.CAB;1" "setup1.cab" \
		&& extract_iso "/SETUP2.CAB;1" "setup2.cab" \
		&& extract_iso "/SETUP3.CAB;1" "setup3.cab" \
		&& mounted=3
	fi
	
	[ $mounted != 0 ] || die "Error mounting ISO image - mount manually and specify the dir."
	
	trap unmount_iso INT QUIT TERM EXIT
	
fi

# Extract source files

cd "$srcdir" && find "$cd" -iname "setup*.cab" -exec "$cabextract" {} \;

# Detect language

cd "$srcdir" && detect_language

[ "$patch_lang" = "multilang" ] || [ "$patch_lang" = "$data_lang" ] \
	|| die "Patch language ($patch_lang) does not match data language ($data_lang)!"

# Extract patch files

cd "$patchdir" && "$innoextract" --lowercase --language="$data_lang" "$patch"

# Install required files

cd "$tempdir"

for f in "$@" ; do
	
	dst="$destdir/$f"
	
	dir="$(dirname "$f")"
	file="$(basename "$f" | sed 's/[^[:alnum:]_-]/\\&/g')"
	file_default="$(echo "$file" | sed 's/^\(.*\)\(\.[^.]*\)$/\1_default\2/g')"
	
	mkdir -pv "$destdir/$dir"
	rm "$dst" > /dev/null 2>&1
	
	[ -f "$dst" ] || find "patch" -iname "$file" -exec mv -fv {} "$dst" \;
	[ -f "$dst" ] || find "src" -iname "$file" -exec mv -fv {} "$dst" \;
	[ -f "$dst" ] || find "$cd" -iname "$file" -exec cp -fv {} "$dst" \;
	
	[ -f "$dst" ] || find "src" -iname "$file_default" -exec mv -fv {} "$dst" \;
	[ -f "$dst" ] || find "$cd" -iname "$file_default" -exec cp -fv {} "$dst" \;
	
	[ -f "$dst" ] && chmod "--reference=$destdir" "$dst" > /dev/null 2>&1
	[ -f "$dst" ] && chmod -x "$dst" > /dev/null 2>&1
	
done

# Cleanup temporary files

unmount_iso
rm -rf "$tempdir"

# Verify installed files

cd "$destdir" && verify_checksums
