#!/bin/bash

###############################################################################
# UExtract v4.9 by JakeSFR (a.k.a. SFR)'2013-2022                             #
# GNU GPL v2 applies                                                          #
###############################################################################

MYPATH="$(dirname "$(readlink -f "$0")")"
PATH="${MYPATH}/bin:${PATH}"
LD_LIBRARY_PATH="${MYPATH}/bin:${LD_LIBRARY_PATH}"

APPNAME="$(sed -n 's/^APPNAME="\(.*\)".*/\1/p' "${MYPATH}/uextract")"

export TEXTDOMAINDIR="${MYPATH}/locale"
export TEXTDOMAIN=uextract
export OUTPUT_CHARSET=UTF-8

WORKDIR="/tmp/uextract_apprun.${USER}.${$}"

if ! type gettext >/dev/null 2>&1; then
	gettext() { echo "$@"; };
	export -f gettext
fi

if ! mkdir -p "$WORKDIR"; then
	echo "$(gettext 'Cannot create temporary directory! Aborting...')"
	exit 1
fi

trap '[ -d "${WORKDIR}" ] && rm -rf "${WORKDIR}"; exit' 0 INT HUP TERM

BACKENDS="${WORKDIR}/backends"
DEPENDENCIES="${WORKDIR}/dependencies"

TMPEXEC="${WORKDIR}/uextract_exec_${USER}.${$}"

CUR_LANG="${LANG:0:2}"
[ "$LANGUAGE" ] && CUR_LANG="${LANGUAGE:0:2}"

LINKS="${MYPATH}/doc/LINKS.txt"
FILETYPES="${MYPATH}/doc/FILETYPES.txt"
if [ -f "${MYPATH}/doc/FILETYPES_${CUR_LANG}.txt" ]; then
	FILETYPES="${MYPATH}/doc/FILETYPES_${CUR_LANG}.txt"
fi

type gtkdialog4 >/dev/null 2>&1 && GTKDIALOG=gtkdialog4 || GTKDIALOG=gtkdialog
type ${GTKDIALOG} >/dev/null 2>&1 && GUI=gtkdialog || GUI=xdialog

if [ "$GUI" = 'gtkdialog' ]; then
	GTKDLG_VER="$(LANG=C $GTKDIALOG --version 2>/dev/null)"

	# If gtkdialog is 0.7.20 or older, don't use hseparator/vseparator!
	GTKDLG_MIN_VER='0.7.21'
	GTKDLG_CUR_VER="$(echo "$GTKDLG_VER" | sed -n 's|.*version \([0-9\.]\+\) .*|\1|p')"
	if [ $(printf "%03d%03d%03d%03d%03d" ${GTKDLG_CUR_VER//./ }) -lt $(printf "%03d%03d%03d%03d%03d" ${GTKDLG_MIN_VER//./ }) ]; then
		HSEP=''
		VSEP=''
	else
		HSEP='<hseparator></hseparator>'
		VSEP='<vseparator></vseparator>'
	fi
	
	# Needed for GTK3 to make the text reasonably wide, so it doesn't wrap every 5 chars or so,
	# but it breaks GTK2, so have to apply accordingly
	if echo "$GTKDLG_VER" | grep -qw 'GTK+ 3'; then
		GTK3_FIX=' space-fill="true" space-expand="true"'
	else
		GTK3_FIX=''
	fi
	
	# Check for VTE availability
	if echo "$GTKDLG_VER" | grep -qw 'VTE'; then
		GTKDLG_VTE='true'
	else
		GTKDLG_VTE='false'
	fi
	
fi

# Custom GTK2/3 styles for textview
mkdir -p "${WORKDIR}/gtk-3.0"

# GTK2
CUSTOM_GTK2="${WORKDIR}/gtkrc"
cat > "$CUSTOM_GTK2" <<EOF
style 'fixed_font' {
font_name="Monospace"
}
widget '*Text*' style 'fixed_font'
class '*GtkText*' style 'fixed_font'
EOF

# GTK3
CUSTOM_GTK3="${WORKDIR}/gtk-3.0/gtk.css"
cat > "$CUSTOM_GTK3" <<EOF
textview {
font-family: monospace;
}
EOF

export MYPATH WORKDIR CUSTOM_GTK2 APPNAME GTKDIALOG FILETYPES LINKS BACKENDS DEPENDENCIES

# -----------------------------------------------------------------------------

func_show_dialog() {
	
	local g_width g_height x_width x_height label input_file

	if [ "$1" = 'all' ]; then

		"${MYPATH}/uextract" -b | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g" | tail -n +5 | head -n -1 > "${BACKENDS}"
		#"${MYPATH}/uextract" -d | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g" | tail -n +5 | head -n -1 > "${DEPENDENCIES}"

		echo '
		<window title="'${APPNAME}'" image-name="'${MYPATH}/UExtract.png'" window-position="1">
			<vbox>
				
				<notebook labels="'$(gettext 'Filetypes')'|'$(gettext 'Weblinks')'|'$(gettext 'Backends')'|'$(gettext 'Dependencies')'" space-fill="true" space-expand="true">

					<edit editable="false" cursor-visible="false">
						<width>780</width>
						<height>400</height>
						<input file>'${FILETYPES}'</input>
					</edit>

					<edit editable="false" cursor-visible="false">
						<input file>'${LINKS}'</input>
					</edit>

					<edit editable="false" cursor-visible="false">
						<input file>'${BACKENDS}'</input>
					</edit>

				</notebook>

				<hbox homogeneous="true" space-fill="false" space-expand="false">
					<button has-focus="true">
						<label>'$(gettext "Close")'</label>
						<input file stock="gtk-close"></input>
					</button>
				</hbox>

			</vbox>
		</window>
		' | GTK2_RC_FILES="${CUSTOM_GTK2}:${HOME}/.gtkrc-2.0" XDG_CONFIG_HOME="${WORKDIR}" $GTKDIALOG -s >/dev/null 2>&1 &
		
		return
	fi

	case "$1" in
		'filetypes')
			g_width=780
			g_height=400
			x_width=98
			x_height=32
			label="$(gettext 'Filetypes')"
			input_file="${FILETYPES}"
			;;

		'backends')
			g_width=400
			g_height=400
			x_width=51
			x_height=32
			label="$(gettext 'Backends')"
			input_file="${BACKENDS}"
			"${MYPATH}/uextract" -b | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g" | tail -n +5 | head -n -1 > "${BACKENDS}"
			;;

		'dependencies')
			g_width=400
			g_height=400
			x_width=51
			x_height=32
			label="$(gettext 'Dependencies')"
			input_file="${DEPENDENCIES}"
			"${MYPATH}/uextract" -d | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g" | tail -n +5 | head -n -1 > "${DEPENDENCIES}"
			;;

		'weblinks')
			g_width=780
			g_height=400
			x_width=98
			x_height=32
			label="$(gettext 'Weblinks')"
			input_file="${LINKS}"
			;;
	esac


	if [ "$GUI" = 'gtkdialog' ]; then

		echo '
		<window title="'${APPNAME}'" image-name="'${MYPATH}/UExtract.png'" window-position="1">
			<vbox>

				<text use-markup="true">
					<label>"<span size='"'x-large'"'><b>'${label}'</b></span>"</label>
				</text>

				<edit editable="false" cursor-visible="false">
					<width>'${g_width}'</width>
					<height>'${g_height}'</height>
					<input file>'${input_file}'</input>
				</edit>

				<hbox homogeneous="true">
					<button has-focus="true">
						<label>'$(gettext "Close")'</label>
						<input file stock="gtk-close"></input>
					</button>
				</hbox>

			</vbox>
		</window>
		' | GTK2_RC_FILES="${CUSTOM_GTK2}:${HOME}/.gtkrc-2.0" XDG_CONFIG_HOME="${WORKDIR}" $GTKDIALOG -s #--styles "${CUSTOM_GTK}"	# not supported in older Gtkdialog versions

	else

		Xdialog --fixed-font \
				--rc-file "${CUSTOM_GTK2}" \
				--center \
				--no-cancel \
				--title "${APPNAME}" \
				--backtitle "${label}" \
				--textbox "${input_file}" "${x_height}" "${x_width}"

	fi

}

export -f func_show_dialog

# -----------------------------------------------------------------------------

func_input_files() {

	if [ "$GUI" = 'gtkdialog' ]; then

		CHOOSER="$(echo '
		<window title="'${APPNAME}'" image-name="'${MYPATH}/UExtract.png'" window-position="1">
			<vbox>

				<text use-markup="true">
					<label>"<span size='"'x-large'"'><b>'$(gettext 'Select file to extract')'</b></span>"</label>
				</text>

				'${HSEP}'

				<chooser action="0" space-fill="true" space-expand="true">
					<variable>varCHOOSER</variable>
					<default>'${HOME}'</default>
					<width>600</width>
					<height>400</height>
					<action when="file-activated">echo "CHOOSER=\"$varCHOOSER\""</action>
					<action when="file-activated">EXIT:OK</action>
				</chooser>

				<hbox space-fill="false" space-expand="false">

					<button space-fill="false" space-expand="false">
						<input file stock="gtk-info"></input>
						<action>func_show_dialog all</action>
					</button>

					<text space-fill="true" space-expand="true"><label>""</label></text>

					<hbox homogeneous="true" space-fill="true">
						<button ok>
							<action>echo "CHOOSER=\"$varCHOOSER\""</action>
							<action>closewindow:varCHOOSER</action>
						</button>
						<button cancel>
							<action>closewindow:varCHOOSER</action>
						</button>
					</hbox>
				</hbox>

			</vbox>

		</window>
		' | $GTKDIALOG -s)"

		IFILES="$(echo "$CHOOSER" | grep '^CHOOSER=' | sed -n 's/.*="\(.*\)"/\1/p')"
		eval $(echo "$CHOOSER" | grep '^EXIT=')
		
		if ([ "$EXIT" = 'closewindow' ] || [ "$EXIT" = 'OK' ]) && [ "$IFILES" ]; then
			return 0
		else
			return 1
		fi

	else

		IFILES="$(Xdialog --stdout \
						--no-buttons \
						--center \
						--title "$APPNAME" \
						--backtitle "$(gettext 'Select file to extract')" \
						--fselect "" 0 0 2>/dev/null)"

		[ $? -eq 0 ] && return 0 || return 1

	fi

}

# -----------------------------------------------------------------------------

func_output_dir() {

	if [ "$GUI" = 'gtkdialog' ]; then

		CHOOSER="$(echo '
		<window title="'${APPNAME}'" image-name="'${MYPATH}/UExtract.png'" window-position="1">
			<vbox>

				<text use-markup="true">
					<label>"<span size='"'x-large'"'><b>'$(gettext 'Select output directory')'</b></span>"</label>
				</text>

				<hbox homogeneous="true">
					<text'${GTK3_FIX}'>
						<variable>varSELECTION</variable>
						<input>echo -n "$varCHOOSER"</input>
					</text>
				</hbox>

				'${HSEP}'

				<chooser action="2" space-fill="true" space-expand="true">
					<variable>varCHOOSER</variable>
					<default>$(pwd)</default>
					<width>600</width>
					<height>400</height>
					<action when="selection-changed">refresh:varSELECTION</action>
				</chooser>

				<hbox space-fill="false" space-expand="false">

					<hbox space-fill="false" space-expand="false">
						<vbox homogeneous="true" space-fill="false" space-expand="false">
							<button space-fill="false" space-expand="false">
								<input file stock="gtk-info"></input>
								<action>func_show_dialog all</action>
							</button>
						</vbox>
						'${VSEP}'
					</hbox>

					<vbox spacing="0">
						<checkbox>
							<default>true</default>
							<variable>varAUTOCLOSE</variable>
							<label>'$(gettext 'Auto close output window on successful completion')'</label>
						</checkbox>

						<checkbox>
							<default>false</default>
							<variable>varLISTMODE</variable>
							<label>'$(gettext 'List contents instead of extracting')'</label>
							<action>if true disable:varAUTOCLOSE</action>
							<action>if true disable:varCHOOSER</action>
							<action>if false enable:varAUTOCLOSE</action>
							<action>if false enable:varCHOOSER</action>
						</checkbox>
					</vbox>

					<text space-fill="true" space-expand="true"><label>""</label></text>

					<vbox homogeneous="true" space-fill="false" space-expand="false">
						<hbox>
							<text space-fill="true" space-expand="true"><label>""</label></text>
							<hbox homogeneous="true" space-fill="true">
								<button ok>
									<action>echo "CHOOSER=\"$varCHOOSER\""</action>
									<action>echo "AUTOCLOSE=\"$varAUTOCLOSE\""</action>
									<action>echo "LISTMODE=\"$varLISTMODE\""</action>
									<action>closewindow:varCHOOSER</action>
								</button>
								<button cancel>
									<action>closewindow:varCHOOSER</action>
								</button>
							</hbox>
						</hbox>
					</vbox>

				</hbox>

			</vbox>

		</window>
		' | $GTKDIALOG -s)"

		CUSTOMDIR="$(echo "$CHOOSER" | grep '^CHOOSER=' | sed -n 's/.*="\(.*\)"/\1/p')"
		eval $(echo "$CHOOSER" | grep -E '^EXIT=|^AUTOCLOSE=|^LISTMODE=')
		if [ "$EXIT" = 'closewindow' ] && ([ "$CUSTOMDIR" ] || [ "$LISTMODE" ]); then
			return 0
		else
			return 1
		fi

	else
	
		CUSTOMDIR="$(Xdialog --stdout \
							 --center \
							 --title "$APPNAME" \
							 --backtitle "$(gettext 'Select output directory')" \
							 --check "$(gettext 'Auto close output window on successful completion')" on \
							 --dselect "${CURRENTDIR}" 0 0 2>/dev/null)"
		
		RETCODE=$?

		LISTMODE='false'
		AUTOCLOSE="$(echo "$CUSTOMDIR" | tail -n 1)"
		CUSTOMDIR="$(echo "$CUSTOMDIR" | head -n -1)"
		
		[ "$AUTOCLOSE" = 'checked' ] && AUTOCLOSE='true' || AUTOCLOSE='false'
		[ $RETCODE -eq 0 ] && return 0 || return 1
	
	fi

}

# =============================================================================

### START

case "$1" in

	--filetypes)
		func_show_dialog filetypes
		exit
		;;

	--backends)
		func_show_dialog backends
		exit
		;;

	--dependencies)
		func_show_dialog dependencies
		exit
		;;

	--weblinks)
		func_show_dialog weblinks
		exit
		;;

esac

# -----------------------------------------------------------------------------

IFILES=( "$@" )

if [ ${#IFILES[@]} -eq 0 ]; then
	while [ ! "$IFILES" ] || [ -d "$IFILES" ]; do
		func_input_files || exit 1
	done
fi

CURRENTDIR="${IFILES[0]%/*}/"
cd -- "$CURRENTDIR" || exit 1

func_output_dir || exit 1

# =============================================================================

export PS1="# "

[ "$LISTMODE" = 'true' ] && LM='-l' || LM=''

if [ "$GUI" != 'gtkdialog' ] || [ "$GTKDLG_VTE" != 'true' ] || [ ! -z "$UEXTRACT_TERM" ]; then

	echo '#! /bin/bash
trap "'"rm -rf $WORKDIR"'" EXIT
'${MYPATH}'/uextract "$@"
RETVAL=$?
rm -f '${TMPEXEC}'' > "$TMPEXEC"

	if [ "$AUTOCLOSE" = "true" ] && [ "$LISTMODE" != 'true' ]; then
		echo '[ $RETVAL -eq 0 ] && exit' >> "$TMPEXEC"
	fi

	echo '/bin/sh' >> "$TMPEXEC"

	chmod +x "$TMPEXEC"

	for i in $UEXTRACT_TERM defaultterm urxvt uxterm rxvt xterm roxterm lxterminal termit sakura; do
		type "$i" >/dev/null 2>&1 && { EXEC_TERMINAL="$i"; break; }
	done

	exec $EXEC_TERMINAL -T "$APPNAME" -e ${TMPEXEC} ${LM} -o "$CUSTOMDIR" "${IFILES[@]}"

else

	echo "clear; trap 'rm -rf $WORKDIR' EXIT" > "$TMPEXEC"
	
	CUSTOMDIR="${CUSTOMDIR//\'/\'\"\'\"\'}"
	echo -n "${MYPATH}/uextract ${LM} -o '$CUSTOMDIR'" >> "$TMPEXEC"
	
	for FILE in $(seq 0 $((${#IFILES[@]}-1))); do
		IFILES[$FILE]="${IFILES[$FILE]//\'/\'\"\'\"\'}"
		echo -n " '${IFILES[$FILE]}'" >> "$TMPEXEC"
	done

	chmod +x "$TMPEXEC"

	export MAIN='
	<window title="'${APPNAME}'" image-name="'${MYPATH}/UExtract.png'">
		<vbox>
			<terminal argv0="/bin/sh"
				scrollback-lines="100000"
				has-focus="true"
				text-background-color="#ffffff"
				text-foreground-color="#000000">
				<variable>vte0</variable>
				<width>83</width>
				'$(if [ "$AUTOCLOSE" = "true" ] && [ "$LISTMODE" != 'true' ]; then
					echo '<input>echo "HISTFILE=; printf \"\033c\";' ${TMPEXEC}' && exit"</input>'
				else
					echo '<input>echo "HISTFILE=; printf \"\033c\";' ${TMPEXEC}'"</input>'
				fi)'
				<action signal="child-exited">exit:EXIT</action>
			</terminal>
		</vbox>
	</window>'

	exec $GTKDIALOG -cp MAIN
fi

exit
