#!/bin/bash

###############################################################################
# PackIt v1.17 by SFR'2013-2016,2019                                          #
# GNU GPL v2 applies                                                          #
###############################################################################

APPNAME="PackIt"
VERSION="v1.17"

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

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

OLDDIR="$(pwd)"
WORKDIR="/tmp/packit.${USER}.${$}"
TMPMNT="${WORKDIR}/mntpt.${$}"

mkdir -p "$WORKDIR" "$TMPMNT"

trap 'cd "$OLDDIR"; umount "$TMPMNT" 2>/dev/null || umount -l -f "$TMPMNT" 2>/dev/null; rm -rf $WORKDIR' EXIT

export TMP_INPUT="${WORKDIR}/input"			; : > "$TMP_INPUT"
export TMP_PASS1="${WORKDIR}/pass1"			; : > "$TMP_PASS1"
export TMP_PASS2="${WORKDIR}/pass2"			; : > "$TMP_PASS2"
export TMP_OUTPUT_DIR="${WORKDIR}/outdir"	; : > "$TMP_OUTPUT_DIR"
export TMP_ARCHNAME="${WORKDIR}/archname"	; : > "$TMP_ARCHNAME"
export TMP_EXT="${WORKDIR}/ext"				; : > "$TMP_EXT"
export TMP_MKSQ_LIST="${WORKDIR}/mksqlist"	; : > "$TMP_MKSQ_LIST"

TMP_EXEC="${WORKDIR}/packit_exec"

APPICON="${MYPATH}/PackIt.png"

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

[ "$(which gtkdialog4 2>/dev/null)" ] && GTKDIALOG=gtkdialog4 || GTKDIALOG=gtkdialog

func_vercmp_gt () {
	[ "${1}" != "$(echo -e "${1}\n${2}" | sort -t '.' -k1,1n -k2,2n -k3,3n -k4,4n -k5,5n | head -n1)" ]
}

GTKDLG_VER="$($GTKDIALOG -v 2>/dev/null | grep -Eo 'version.*\.[0-9] ' | cut -f2 -d ' ')"

if func_vercmp_gt "0.8.0" "${GTKDLG_VER}"; then
	export GUI_REQUIREMENTS='
	<window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
		<vbox>
			<pixmap><input file stock="gtk-dialog-warning"></input></pixmap>
			<text><label>""</label></text>
			<text><label>'$(gettext "Please install Gtkdialog >= 0.8.0.")'</label></text>
			<text><label>""</label></text>

			<hbox homogeneous="true">
				<button ok></button>
			</hbox>
		</vbox>
		<action signal="delete-event">EXIT:abort</action>
	</window>'
    $GTKDIALOG -cp GUI_REQUIREMENTS
    exit 1
fi

func_vercmp_gt "0.8.3" "${GTKDLG_VER}" && GTKDLG_NEW=0 || GTKDLG_NEW=1	# 1 = gtkdialog >= 0.8.3

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

ARCHNAME="$(gettext 'NewArchive')"
OUTPUT_DIR="$HOME"

if (($#)); then 
	[ ! -e "$1" ] && { echo "File/dir doesn't exist!"; exit 1; }
	FILEPATH="$(dirname "$1")"
	[ "$FILEPATH" = "." ] && FILEPATH="$(pwd)"
	[ "$FILEPATH" = "" ] && FILEPATH="/"
	OUTPUT_DIR="$FILEPATH"
	[ "$2" = "" ] && ARCHNAME="$(basename "$1")"
fi

echo "$OUTPUT_DIR" > "$TMP_OUTPUT_DIR"
echo "$ARCHNAME" > "$TMP_ARCHNAME"

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

SEVENZ=7z
for i in 7z 7za 7zr; do
	[ "$(which $i 2>/dev/null)" ] && { SEVENZ="$i"; break; }
done

LZ4=lz4
for i in lz4 lz4c; do
	[ "$(which $i 2>/dev/null)" ] && { LZ4="$i"; break; }
done

MKSQUASHFS=mksquashfs
for i in mksquashfs mksquashfs4 mksquashfs3; do
	[ "$(which $i 2>/dev/null)" ] && { MKSQUASHFS="$i";  break; }
done

export SEVENZ LZ4 MKSQUASHFS

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

PASS_1="tar cpio mke2fs mkisofs $MKSQUASHFS"
PASS_2="$SEVENZ bzip2 gzip $LZ4 lzip lzma lzop rar xz zip zstd"

# -----------------------------------------------------------------------------
# Check if mksquashfs supports some additional compression methods
# -----------------------------------------------------------------------------

if [ "$(which $MKSQUASHFS 2>/dev/null)" ]; then
	MKSQ_LIST="$($MKSQUASHFS 2>&1 | grep -Ewo 'gzip|lzma|lzo|lz4|xz' | sort -u)"
	echo -n "$MKSQ_LIST" > "$TMP_MKSQ_LIST"
fi

# -----------------------------------------------------------------------------
# Test 7z(a/r) and rar's .sfx/.exe ability
# -----------------------------------------------------------------------------

IS_7Z_SFX=false
IS_7Z_EXE=false
IS_RAR_SFX=false
IS_RAR_EXE=false

SELFEXTTEST="$WORKDIR/selfexttest.sfx"

if [ "$(which $SEVENZ 2>/dev/null)" ]; then
	echo test | $SEVENZ a -si -sfx7zCon.sfx "$SELFEXTTEST" >/dev/null 2>&1
	[ $? -eq 0 ] && IS_7Z_SFX=true
	rm -f "$SELFEXTTEST"

	echo test | $SEVENZ a -si -sfx7z.sfx "$SELFEXTTEST" >/dev/null 2>&1
	[ $? -eq 0 ] && IS_7Z_EXE=true
	rm -f "$SELFEXTTEST"
fi

if [ "$(which rar 2>/dev/null)" ]; then
	if [ -e "${MYPATH}/resources/default.sfx" ]; then
		echo test | rar a -si -sfx"${MYPATH}/resources/default.sfx" "$SELFEXTTEST" >/dev/null 2>&1
	else
		echo test | rar a -si -sfxdefault.sfx "$SELFEXTTEST" >/dev/null 2>&1
	fi
	[ $? -eq 0 ] && IS_RAR_SFX=true
	rm -f "$SELFEXTTEST"

	if [ -e "${MYPATH}/resources/Default.SFX" ]; then
		echo test | rar a -si -sfx"${MYPATH}/resources/Default.SFX" "$SELFEXTTEST" >/dev/null 2>&1
	else
		echo test | rar a -si -sfxDefault.SFX "$SELFEXTTEST" >/dev/null 2>&1
	fi
	[ $? -eq 0 ] && IS_RAR_EXE=true
	rm -f "$SELFEXTTEST"
fi

export IS_7Z_SFX IS_7Z_EXE IS_RAR_SFX IS_RAR_EXE

# -----------------------------------------------------------------------------
# Flags for PASS_2 tools: COMPRESSION_LEVELS | ENCRYPTION | ENCRYPT_FILENAMES | SOLID | MULTIPLE_FILES
# -----------------------------------------------------------------------------
F_7z=11111
F_7za=11111
F_7zr=10011
F_bzip2=10000
F_gzip=10000
F_lz4=10000
F_lz4c=10000
F_lzip=10000
F_lzma=10000
F_lzop=10000
F_rar=11111
F_xz=10000
F_zip=11001
F_zstd=10000

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

func_escape () {
	local TMP="${1}"
	TMP="${TMP//\\/\\\\}"			# escape backslashes
	TMP="${TMP//\"/\\\"}"			# escape "
	TMP="${TMP//\$/\\\$}"			# escape $
	TMP="${TMP//\`/\\\`}"			# escape `
	echo -n "$TMP"
}

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

func_set_extension () {

	if [ $1 -eq 1 ]; then
		echo -n "$2" > "$TMP_PASS1"
	else
		echo -n "$2" > "$TMP_PASS2"
	fi

	TEMPEXT="$(<$TMP_PASS1)$(<$TMP_PASS2)"

	case "$TEMPEXT" in
		.tar)					TEMPEXT=".tar\n.cbt" ;;
		.cpio)					TEMPEXT=".cpio" ;;
		.mkisofs)				TEMPEXT=".iso" ;;
		.mke2fs)				TEMPEXT=".2fs\n.ext2\n.img" ;;
		.$MKSQUASHFS)			TEMPEXT=".sfs\n.sqfs\n.squashfs" ;;
		# -----------
		.$SEVENZ)				TEMPEXT=".7z\n.cb7"
								[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.sfx"
								[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.exe" ;;
		.bzip2)					TEMPEXT=".bz2" ;;
		.gzip)					TEMPEXT=".gz" ;;
		.$LZ4)					TEMPEXT=".lz4" ;;
		.lzip)                  TEMPEXT=".lz" ;;
		.lzma)					TEMPEXT=".lzma" ;;
		.lzop)					TEMPEXT=".lzo" ;;
		.rar)					TEMPEXT=".rar\n.cbr"
								[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.sfx"
								[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.exe" ;;
		.xz)					TEMPEXT=".xz" ;;
		.zip)					TEMPEXT=".zip\n.cbz"
								[ "$(which unzipsfx 2>/dev/null)" ] && TEMPEXT="${TEMPEXT}\n.sfx" ;;
		.zstd)					TEMPEXT=".zst" ;;
		# -----------
		.tar.$SEVENZ)			TEMPEXT=".tar.7z"
								[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.sfx"
								[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.exe" ;;
		.tar.bzip2)				TEMPEXT=".tar.bz2\n.tb2\n.tbz\n.tbz2" ;;
		.tar.gzip) 				TEMPEXT=".tar.gz\n.tgz" ;;
		.tar.$LZ4)				TEMPEXT=".tar.lz4\n.tzl4"	;;
		.tar.lzip)              TEMPEXT=".tar.lz\n.tlz" ;;
		.tar.lzma)				TEMPEXT=".tar.lzma\n.tlzma\n.tzma" ;;
		.tar.lzop)				TEMPEXT=".tar.lzo\n.tzo" ;;
		.tar.rar)				TEMPEXT=".tar.rar"
								[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.sfx"
								[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.exe" ;;
		.tar.xz)				TEMPEXT=".tar.xz\n.txz" ;;
		.tar.zip)				TEMPEXT=".tar.zip"
								[ "$(which unzipsfx 2>/dev/null)" ] && TEMPEXT="${TEMPEXT}\n.tar.sfx" ;;
		.tar.zstd)				TEMPEXT=".tar.zst\n.tzst" ;;
		# -----------
		.cpio.$SEVENZ)			TEMPEXT=".cpio.7z"
								[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.sfx"
								[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.exe" ;;
		.cpio.bzip2)			TEMPEXT=".cpio.bz2" ;;
		.cpio.gzip)				TEMPEXT=".cpio.gz\n.cpgz\n.cgz" ;;
		.cpio.$LZ4)				TEMPEXT=".cpio.lz4"	;;
		.cpio.lzip)             TEMPEXT=".cpio.lz" ;;
		.cpio.lzma)				TEMPEXT=".cpio.lzma" ;;
		.cpio.lzop)				TEMPEXT=".cpio.lzo" ;;
		.cpio.rar)				TEMPEXT=".cpio.rar"
								[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.sfx"
								[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.exe" ;;
		.cpio.xz)				TEMPEXT=".cpio.xz" ;;
		.cpio.zip)				TEMPEXT=".cpio.zip"
								[ "$(which unzipsfx 2>/dev/null)" ] && TEMPEXT="${TEMPEXT}\n.cpio.sfx" ;;
		.cpio.zstd)				TEMPEXT=".cpio.zst" ;;
		# -----------
		.mke2fs.$SEVENZ)		TEMPEXT=".2fs.7z\n.ext2.7z\n.img.7z"
								[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.sfx\n.ext2.sfx\n.img.sfx"
								[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.exe\n.ext2.exe\n.img.exe" ;;
		.mke2fs.bzip2)			TEMPEXT=".2fs.bz2\n.ext2.bz2\n.img.bz2" ;;
		.mke2fs.gzip)			TEMPEXT=".2fs.gz\n.ext2.gz\n.img.gz" ;;
		.mke2fs.$LZ4)			TEMPEXT=".2fs.lz4\next2.lz4\nimg.lz4" ;;
		.mke2fs.lzip)           TEMPEXT=".2fs.lz\next2.lz\nimg.lz" ;;
		.mke2fs.lzma)			TEMPEXT=".2fs.lzma\n.ext2.lzma\n.img.lzma" ;;
		.mke2fs.lzop)			TEMPEXT=".2fs.lzo\n.ext2.lzo\n.img.lzo" ;;
		.mke2fs.rar)			TEMPEXT=".2fs.rar\n.ext2.rar\n.img.rar"
								[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.sfx\n.ext2.sfx\n.img.sfx"
								[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.exe\n.ext2.exe\n.img.exe" ;;
		.mke2fs.xz)				TEMPEXT=".2fs.xz\n.ext2.xz\n.img.xz" ;;
		.mke2fs.zip)			TEMPEXT=".2fs.zip\n.ext2.zip\n.img.zip"
								[ "$(which unzipsfx 2>/dev/null)" ] && TEMPEXT="${TEMPEXT}\n.2fs.sfx\n.ext2.sfx\n.img.sfx" ;;
		.mke2fs.zstd)			TEMPEXT=".2fs.zst\n.ext2.zst\n.img.zst" ;;
		# -----------
		.mkisofs.$SEVENZ)		TEMPEXT=".iso.7z"
								[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.sfx"
								[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.exe" ;;
		.mkisofs.bzip2)			TEMPEXT=".iso.bz2" ;;
		.mkisofs.gzip)			TEMPEXT=".iso.gz" ;;
		.mkisofs.$LZ4)			TEMPEXT=".iso.lz4" ;;
		.mkisofs.lzip)          TEMPEXT=".iso.lz" ;;
		.mkisofs.lzma)			TEMPEXT=".iso.lzma" ;;
		.mkisofs.lzop)			TEMPEXT=".iso.lzo" ;;
		.mkisofs.rar)			TEMPEXT=".iso.rar"
								[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.sfx"
								[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.exe" ;;
		.mkisofs.xz)			TEMPEXT=".iso.xz" ;;
		.mkisofs.zip)			TEMPEXT=".iso.zip"
								[ "$(which unzipsfx 2>/dev/null)" ] && TEMPEXT="${TEMPEXT}\n.iso.sfx" ;;
		.mkisofs.zstd)			TEMPEXT=".iso.zst" ;;
		# -----------
		.$MKSQUASHFS.*)			TEMPEXT=".sfs\n.sqfs\n.squashfs" ;;
		*)						TEMPEXT="" ;;
	esac
  
	echo -en $TEMPEXT > $TMP_EXT
}

export -f func_set_extension

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

func_show_warning () {

	export GUI_WARNING='
	<window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
		<vbox>
			<pixmap><input file stock="gtk-dialog-warning"></input></pixmap>
			<text><label>""</label></text>
			<text><label>'${1}'</label></text>
			<text><label>""</label></text>
			<hseparator></hseparator>
			<hbox homogeneous="true">
				<button space-fill="true" space-expand="true">
					<input file stock="gtk-refresh"></input>
					<label>'$(gettext "Restart")'</label>
					<action>EXIT:OK</action>
				</button>
				<button space-fill="true" space-expand="true">
					<input file stock="gtk-quit"></input>
					<label>'$(gettext "Exit")'</label>
					<action>EXIT:abort</action>
				</button>
			</hbox>
		</vbox>
		<action signal="delete-event">EXIT:abort</action>
	</window>'
    
	eval $($GTKDIALOG -cp GUI_WARNING)
	[ "$EXIT" = "OK" ] || exit 1

}

export func_show_warning

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

func_show_success () {

	export GUI_SUCCESS='
	<window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
		<vbox>
			<pixmap>
				'$( if [ -f /usr/local/lib/X11/pixmaps/ok.xpm ]; then 
					echo '<input file>/usr/local/lib/X11/pixmaps/ok.xpm</input>'
				else
					echo '<input file stock="gtk-apply"></input>'
				fi )'
			</pixmap>
			<text><label>""</label></text>
			<text><label>'$(gettext "The archive")'</label></text>
			<text use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
			<text><label>'$(gettext "has been successfully created!")'</label></text>
			<text><label>""</label></text>
			<hseparator></hseparator>
			<hbox homogeneous="true"><button ok></button></hbox>
		</vbox>
		<action signal="delete-event">EXIT:abort</action>
	</window>'
  
	eval $($GTKDIALOG -cp GUI_SUCCESS)

}

export -f func_show_success

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

func_show_fail () {

	export GUI_FAIL='
	<window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
		<vbox>
			<pixmap>
				'$( if [ -f /usr/local/lib/X11/pixmaps/error.xpm ]; then 
					echo '<input file>/usr/local/lib/X11/pixmaps/error.xpm</input>'
				else
					echo '<input file stock="gtk-dialog-error"></input>'
				fi )'
			</pixmap>

			<text><label>""</label></text>
			<text><label>'$(gettext "The archive")'</label></text>
			<text use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
			<text><label>'$(gettext "has not been successfully created!")'</label></text>
			<text><label>""</label></text>

			<hseparator></hseparator>

			<hbox homogeneous="true">
				<button space-fill="true" space-expand="true">
					<input file stock="gtk-file"></input>
					<label>'$(gettext "View log")'</label>
					<action>EXIT:log</action>
				</button>
				<button space-fill="true" space-expand="true">
					<input file stock="gtk-refresh"></input>
					<label>'$(gettext "Restart")'</label>
					<action>EXIT:restart</action>
				</button>
				<button space-fill="true" space-expand="true">
					<input file stock="gtk-quit"></input>
					<label>'$(gettext "Exit")'</label>
					<action>EXIT:exit</action>
				</button>
			</hbox>
		</vbox>
		<action signal="delete-event">EXIT:abort</action>
	</window>'
  
	eval $($GTKDIALOG -cp GUI_FAIL)
  
	case "$EXIT" in
		log)		return 2 ;;
		restart)	return 1 ;;
		*)			return 0 ;;
	esac

}

export -f func_show_success

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

func_show_log () {

	export GUI_LOG='
	<window title="'${APPNAME}' - '$(gettext "Log")'" width-request="600" height-request="400" image-name="'${APPICON}'">
		<vbox>
			<edit editable="false">
				<input file>'${WORKDIR}/packit.log'</input>
			</edit>
			<hbox homogeneous="true">
				<button ok></button>
			</hbox>
		</vbox>
		<action signal="delete-event">EXIT:abort</action>
	</window>'
  
	$GTKDIALOG -cp GUI_LOG

}

export -f func_show_log

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

RANGE=7

export GUI_WAIT='
	<window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
		<vbox>
			<pixmap>
				<input file stock="gtk-dialog-info"></input>
			</pixmap>
    
			<text><label>""</label></text>
			<text><label>'$(gettext "The archive")'</label></text>
			<text use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
			<text><label>'$(gettext "is being created, please wait...")'</label></text>

			<text>
				<variable>varOUTPUT_SIZE</variable>
				<input>echo -n "["; [ -f "$DESTARCH" ] && du -bh "$DESTARCH" 2>/dev/null | cut -f1 | tr -d "\n" || echo -n "?"; echo -n "]"</input>
			</text>

			<notebook show-border="false" show-tabs="false" tab-base-index="0">
				'$(for i in $(seq 1 ${RANGE}); do
				echo '
					<hscale sensitive="false" draw-value="false" range-min="1" range-max="'${RANGE}'" range-step="1" range-value="'${i}'">
					</hscale>'
				done)'

				'$(for i in $(seq $((${RANGE}-1)) -1 1); do
				echo '
					<hscale sensitive="false" draw-value="false" range-min="1" range-max="'${RANGE}'" range-step="1" range-value="'${i}'">
					</hscale>'
				done)'
      
				<variable>varINDEX</variable>
				<input>echo $(( ($varINDEX+1) % (('${RANGE}'-1) * 2) ))</input>
			</notebook>

			<timer visible="false" milliseconds="true" interval="200">
				<action>refresh:varINDEX</action>
			</timer>
			<timer visible="false" milliseconds="false" interval="1">
				<action>refresh:varOUTPUT_SIZE</action>
			</timer>

			<hbox homogeneous="true">
				<button>
					<input file stock="gtk-cancel"></input>
					<label>Abort</label>
					<action>PID=$(cat "'${WORKDIR}/PID'"); while true; do TMP=$(pgrep -P $PID); [ "$TMP" ] && PID="$TMP" || break; done; kill $PID</action>
					<action>#pkill -TERM -P $(cat "'${WORKDIR}/PID'")</action>
					<action>EXIT:exit</action>
				</button>
			</hbox>
		</vbox>

		<action signal="delete-event">PID=$(cat "'${WORKDIR}/PID'"); while true; do TMP=$(pgrep -P $PID); [ "$TMP" ] && PID="$TMP" || break; done; kill $PID</action>
		<action signal="delete-event">EXIT:abort</action>
	</window>'

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

export GUI_CHOOSER='
	<window title="'${APPNAME}'" modal="true" resizable="false" image-name="'${APPICON}'">
		<vbox>
  
			<chooser>
				<variable>INPUT</variable>
				<default>'${HOME}'</default>
				<width>600</width>
				<height>400</height>
			</chooser>
		
			<hbox>
				<button>
					<label>'$(gettext 'OK')'</label>
					<input file stock="gtk-ok"></input>
					<variable>CLOSE_CHOOSER</variable>
					<action>echo "$INPUT" > '${TMP_INPUT}'</action>
					<action>refresh:varINPUT</action>
					<action>closewindow:CLOSE_CHOOSER</action>
				</button>
				<button>
					<label>'$(gettext 'Cancel')'</label>
					<input file stock="gtk-cancel"></input>
					<action>closewindow:CLOSE_CHOOSER</action>
				</button>
			</hbox>
	
		</vbox>

		<variable>GUI_CHOOSER</variable>
	</window>'

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

export GUI_MAIN='
	<window title="'${APPNAME}' '${VERSION}'" resizable="false" image-name="'${APPICON}'">
		<vbox>
			'$(if ! (($#)); then
				echo '
				<frame '$(gettext 'Select input folder or file:')'>
					<hbox>
						<entry editable="true" activates_default="true">
							<variable>varINPUT</variable>
							<input file>"'${TMP_INPUT}'"</input>
							<action>echo -e "${varINPUT// \//\\n/}" > "'${TMP_INPUT}'"</action>
						</entry>
						<button>
							<input file stock="gtk-file"></input>
							<action>launch:GUI_CHOOSER</action>
						</button>
					</hbox>
				</frame>'
			fi)'
			<hbox>
				<frame '$(gettext 'Pass_1:')'>
					<vbox>
						'$(echo '
							<radiobutton>
								<variable>varPASS1</variable>
								<label>'$(gettext '(none)')'</label>
								<action>if true func_set_extension 1 ''</action>
								<action>if true enable:varPASS2_STATE</action>
								'$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="active_is_true(varPASS2)">disable:varPACKIT</action>')'
								<action>refresh:varEXTENSION</action>
								'$([ "$MKSQ_LIST" != "" ] && echo '<action>disable:varMKSQ_LIST</action>')'
							</radiobutton>
						'
					
						for i in ${PASS_1}; do
					
							if [ "$(which $i 2>/dev/null)" ]; then
					
								if [ "$i" = "$MKSQUASHFS" ]; then
									echo '<hseparator></hseparator>'
								fi
					
								echo '
									<radiobutton>
										<label>'${i}'</label>
										<action>if true func_set_extension 1 '.${i}'</action>
										<action>refresh:varEXTENSION</action>
										<action>enable:varPACKIT</action>
								'
					
								if [ "$i" = "$MKSQUASHFS" ]; then
									echo '
										<action>if true activate:varPASS2</action>
										<action>disable:varPASS2_STATE</action>
									'
								fi
					
								if [ "$i" != "$MKSQUASHFS" ]; then
									echo '<action>if true enable:varPASS2_STATE</action>'
								fi
					
								if [ "$i" = "$MKSQUASHFS" ] && [ "$MKSQ_LIST" != "" ]; then
									echo '<action>if true enable:varMKSQ_LIST</action>'
								fi
					
								if [ "$i" = "$MKSQUASHFS" ]; then
									echo '<action>if true enable:varMKSQ_BLOCK</action>'
								fi
					
								if [ "$i" != "$MKSQUASHFS" ] && [ "$MKSQ_LIST" != "" ]; then
									echo '<action>disable:varMKSQ_LIST</action>'
								fi
					
								if [ "$i" != "$MKSQUASHFS" ]; then
									echo '<action>disable:varMKSQ_BLOCK</action>'
								fi

								echo '</radiobutton>'

								if [ "$i" = "$MKSQUASHFS" ] && [ "$MKSQ_LIST" != "" ]; then
									echo '
										<hbox>
										<comboboxtext tooltip-text="'"$(gettext "Compression")"'">
										<variable>varMKSQ_LIST</variable>
										<sensitive>false</sensitive>
										<input file>'${TMP_MKSQ_LIST}'</input>
										</comboboxtext>
										<comboboxtext tooltip-text="'"$(gettext "Block size")"'">
										<variable>varMKSQ_BLOCK</variable>
										<sensitive>false</sensitive>
										<default>128K</default>
										<item>4K</item>
										<item>16K</item>
										<item>32K</item>
										<item>64K</item>
										<item>128K</item>
										<item>256K</item>
										<item>512K</item>
										<item>1M</item>
										</comboboxtext>
										</hbox>
									'
								fi
					
							fi
					
						done)'
					</vbox>
				</frame>

				<frame '$(gettext 'Pass_2:')'>
					<vbox>
					'$(echo '
						<radiobutton>
						<variable>varPASS2</variable>
						<label>'$(gettext '(none)')'</label>
						<action>if true func_set_extension 2 ''</action>
					'
				
					if [ ${GTKDLG_NEW} -eq 1 ]; then
						echo '<action condition="active_is_true(varPASS1)">disable:varPACKIT</action>'
					fi
					
					echo '
						<action>refresh:varEXTENSION</action>
						<action>disable:varLEVEL</action>
						<action>disable:varLEVEL_INFO</action>
						<action>disable:varSOLID</action>
						<action>disable:varPASSWORD</action>
						<action>disable:varPASSWORD_PLAIN</action>
						<action>disable:varPASSWORD_INFO</action>
						<action>disable:varENCHEAD</action>
						</radiobutton>
					'
				
					for i in $PASS_2; do
				
						if [ "$(which $i 2>/dev/null)" ]; then
				
							FLAGS=F_$i
				
							echo '
								<radiobutton>
								<label>'${i}'</label>
								<action>if true func_set_extension 2 '.${i}'</action>
								<action>refresh:varEXTENSION</action>
								<action>enable:varLEVEL</action>
								<action>enable:varLEVEL_INFO</action>
								<action>enable:varPACKIT</action>
							'
							if [ ${!FLAGS:0:1} -eq 0 ]; then
								echo '
									<action>disable:varLEVEL</action>
									<action>disable:varLEVEL_INFO</action>
								'
							fi
					
							if [ ${!FLAGS:1:1} -eq 0 ]; then
								echo '
									<action>disable:varPASSWORD</action>
									<action>disable:varPASSWORD_PLAIN</action>
									<action>disable:varPASSWORD_INFO</action>
								'
							else
								echo '
									<action>enable:varPASSWORD</action>
									<action>enable:varPASSWORD_PLAIN</action>
									<action>enable:varPASSWORD_INFO</action>
								'
							fi
					
							if [ ${!FLAGS:2:1} -eq 0 ]; then
								echo '<action>disable:varENCHEAD</action>'
							else
								echo '<action>enable:varENCHEAD</action>'
							fi
					
							if [ ${!FLAGS:3:1} -eq 0 ]; then
								echo '<action>disable:varSOLID</action>'
							else
								echo '<action>enable:varSOLID</action>'
							fi
					
							echo '</radiobutton>'
				
						fi
					done
					
					if [ $GTKDLG_NEW -eq 1 ]; then
						echo '<variable>varPASS2_STATE</variable>'
					fi)'
					</vbox>
				</frame>
		
				<frame '$(gettext 'Pass_2 extra options:')'>
					<vbox>
						<text>
							<variable>varLEVEL_INFO</variable>
							<sensitive>false</sensitive>
							<label>'$(gettext 'Compression preset:')' </label>
						</text>
						<hscale range-min="1" range-max="5" range-step="1" range-value="3" value-pos="2">
							<variable>varLEVEL</variable>
							<sensitive>false</sensitive>
							<item>1|0|'$(gettext 'Fast')'</item>
							<item>3|0|'$(gettext 'Average')'</item>
							<item>5|0|'$(gettext 'Best')'</item>
						</hscale>
			
						<hseparator></hseparator>
			
						<hbox homogeneous="true">
							<checkbox>
								<variable>varSOLID</variable>
								<label>'$(gettext 'Solid archive')'</label>
								<default>false</default>
								<sensitive>false</sensitive>
							</checkbox>
						</hbox>
			
						<hseparator></hseparator>
			
						<text>
							<variable>varPASSWORD_INFO</variable>
							<sensitive>false</sensitive>
							<label>'$(gettext 'Password:')' </label>
						</text>
			
						<notebook show-tabs="false" show-border="false">
							<entry max-length="256" caps-lock-warning="true" visibility="false" primary-icon-stock="gtk-strikethrough" primary-icon-tooltip-text="'$(gettext "Show password")'">
								<variable>varPASSWORD</variable>
								<input>echo "$varPASSWORD_PLAIN"</input>
								<action>refresh:varPASSWORD_PLAIN</action>
								<action signal="primary-icon-release">refresh:varPASS_MODE</action>
								'$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="command_is_true( [ \"$varPASSWORD\" ] && echo true )">enable:varENCHEAD_PASS</action>')'
								'$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="command_is_true( [ \"$varPASSWORD\" ] || echo true )">disable:varENCHEAD_PASS</action>')'
							</entry>
							<entry block-function-signals="true" max-length="256" caps-lock-warning="true" visibility="true" primary-icon-stock="gtk-underline" primary-icon-tooltip-text="'$(gettext "Hide password")'">
								<variable>varPASSWORD_PLAIN</variable>
								<input>echo "$varPASSWORD"</input>
								<action>refresh:varPASSWORD</action>
								<action signal="primary-icon-release">refresh:varPASS_MODE</action>
							</entry>
							<variable>varPASS_MODE</variable>
							<input>echo $(( (varPASS_MODE+1) &1 ))</input>
						</notebook>
	
						<hbox homogeneous="true">
							<checkbox>
								<variable>varENCHEAD</variable>
								<default>false</default>
								<sensitive>false</sensitive>
								<label>'$(gettext 'Encrypt filenames')'</label>
							</checkbox>
							'$( [ $GTKDLG_NEW -eq 1 ] && echo '<sensitive>false</sensitive>')'
							'$( [ $GTKDLG_NEW -eq 1 ] && echo '<variable>varENCHEAD_PASS</variable>')'
						</hbox>
					</vbox>
				</frame>
			</hbox>
		
			<hbox>
				<text xalign="0"><label>'$(gettext 'Output folder:')' </label></text>
				<entry activates_default="true" fs-title="'$(gettext 'Select an output folder')'" fs-folder="'${HOME}'" fs-action="folder">
					<variable>varOUTPUT_DIR</variable>
					<input file>'${TMP_OUTPUT_DIR}'</input>
				</entry>
				<button>
					<input file stock="gtk-directory"></input>
					<action>fileselect:varOUTPUT_DIR</action>
				</button>
			</hbox>
		
			<hbox>
				<text xalign="0"><label>'$(gettext 'Archive name:')' </label></text>
				<entry activates_default="true">
					<variable>varARCHNAME</variable>
					<input file>'${TMP_ARCHNAME}'</input>
				</entry>
		
				<comboboxtext width-request="96">
					<variable>varEXTENSION</variable>
					<input file>'${TMP_EXT}'</input>
				</comboboxtext>
		
			</hbox>
	
			<hseparator></hseparator>
		
			<hbox>
				<checkbox>
					<variable>varVERBOSE</variable>
					<default>false</default>
					<label>'$(gettext 'Verbose mode')'</label>
				</checkbox>
				<checkbox>
					<variable>varCHKSUM</variable>
					<default>false</default>
					<label>'$(gettext "Checksums")'</label>
				</checkbox>
		
				<vseparator></vseparator>
		
				<text space-fill="true" space-expand="true"><label>" "</label></text>
				<button can-default="true" has-default="true">
					<variable>varPACKIT</variable>
					<sensitive>false</sensitive>
					<label>'$(gettext 'Pack it!')'</label>
					<input file stock="gtk-ok"></input>
					<action>EXIT:packit</action>
				</button>
				<button>
					<label>'$(gettext 'Cancel')'</label>
					<input file stock="gtk-cancel"></input>
					<action>EXIT:cancel</action>
				</button>
			</hbox>
    
		</vbox>

		<action signal="show">disable:varPASSWORD</action>
		<action signal="show">disable:varPASSWORD_PLAIN</action>
		<action signal="delete-event">EXIT:abort</action>
	</window>'

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

I=$IFS; IFS='
'

for STATEMENTS in $($GTKDIALOG -cp GUI_MAIN); do
	if [[ "$STATEMENTS" == "varARCHNAME="* ]]; then
		varARCHNAME="$(echo $STATEMENTS | cut -f2- -d '"' | rev | cut -f2- -d '"' | rev)"
	elif [[ "$STATEMENTS" == "varOUTPUT_DIR="* ]]; then
		varOUTPUT_DIR="$(echo $STATEMENTS | cut -f2- -d '"' | rev | cut -f2- -d '"' | rev)"
	elif [[ "$STATEMENTS" == "varPASSWORD="* ]]; then
		varPASSWORD="$(echo $STATEMENTS | cut -f2- -d '"' | rev | cut -f2- -d '"' | rev)"
		varPASSWORD="$(func_escape "$varPASSWORD")"
	else
		eval $STATEMENTS
	fi
done

IFS=$I

[ "$EXIT" != "packit" ] && exit 0

if [ "$(<$TMP_INPUT)" = "" ]; then
	IFILES=( "$@" )
else
	I="$IFS"
	IFS=$'\n'
	IFILES=( $(<$TMP_INPUT) )
	IFS="$I"
fi

# -----------------------------------------------------------------------------
# Precautions and stuff
# -----------------------------------------------------------------------------

if [ ${#IFILES[@]} -eq 0 ]; then
	func_show_warning "$(gettext 'You must specify an existing input file/folder!')"
	exec "$MYNAME" "$@"
fi

if [ "$varOUTPUT_DIR" = "" ] || [ "$(readlink -f "$varOUTPUT_DIR")" = "" ]; then
	func_show_warning "$(gettext 'You must specify an existing output folder!')"
	exec "$MYNAME" "$@"
fi

if [ "$(<$TMP_PASS1)$(<$TMP_PASS2)" = "" ]; then
	func_show_warning "$(gettext 'You must select a tool in "Pass_1" and/or "Pass_2"!')"
	exec "$MYNAME" "$@"
fi

if [ "$(<$TMP_PASS1)" = "" ] && ([ ${#IFILES[@]} -gt 1 ] || [ -d "$(readlink -f "${IFILES[0]}" 2>/dev/null)" ]); then
	TEMPEXT=$(<$TMP_PASS2)
	FLAGS=F_${TEMPEXT:1}
	if [ ${!FLAGS:4:1} -eq 0 ]; then
		func_show_warning "$(gettext 'The chosen tool can process only single files.')"
		exec "$MYNAME" "$@"
	fi
fi

if [ "$(<$TMP_PASS2)" = ".zip" ] && [[ "$varEXTENSION" == *".sfx" ]] && [ "$varPASSWORD" != "" ]; then
	func_show_warning "$(gettext 'Encrypted, self-extracting ZIP archives are not supported.')"
	exec "$MYNAME" "$@"
fi

# -----------------------------------------------------------------------------
# Separate dirname & basename(s)
# -----------------------------------------------------------------------------

INDIR="$(dirname "${IFILES[0]}")"

for i in $(seq 0 $((${#IFILES[@]}-1))); do
	IFILES[$i]="$(basename "${IFILES[$i]}")"
done

# Don't overwrite existing dir/file
varARCHNAME="${varARCHNAME//\//_}"		# precaution: replace / with _
CNT=1
DESTARCH="${varOUTPUT_DIR}/${varARCHNAME}"
TEMP="$DESTARCH"

while [ -e "${TEMP}${varEXTENSION}" ]; do
	TEMP="$DESTARCH($CNT)"
	((CNT++))
done

echo -n "<b>$(basename "${TEMP}${varEXTENSION}" | sed -e 's~&~\&amp;~g' -e 's~<~\&lt;~g' -e 's~>~\&gt;~g')</b>" > "$WORKDIR/msg"

TEMP="$(func_escape "$TEMP")"
DESTARCH="${TEMP}${varEXTENSION}"

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

cd "$INDIR"		# important - must be here, before options!!!

# -----------------------------------------------------------------------------
# Prepare options for tools in PASS2
# -----------------------------------------------------------------------------

case "$(<$TMP_PASS2)" in
	.$SEVENZ)
		OPTS="-mx=$(( $varLEVEL + ($varLEVEL-1) ))"

		if [ $($SEVENZ | sed -n 's/p7zip Version \([0-9]\+\).*/\1/p') -ge 15 ]; then
			OPTS="${OPTS} -mqs=on"	# old sorting, better compression
		fi

		if [ "$varENCHEAD" = "true" ]; then
			OPTS="${OPTS} -mhe=on"
		else
			OPTS="${OPTS} -mhe=off"
		fi

		if [ "$varSOLID" = "true" ]; then
			OPTS="${OPTS} -ms=on"
		else
			OPTS="${OPTS} -ms=off"
		fi

		if [ "$varPASSWORD" != "" ];then
			PASSWORD="-p${varPASSWORD}"
		else
			PASSWORD=
		fi

		if [[ "$varEXTENSION" == *".sfx" ]]; then
			OPTS="${OPTS} -sfx7zCon.sfx"
		elif [[ "$varEXTENSION" == *".exe" ]]; then
			OPTS="${OPTS} -sfx7z.sfx"
		fi
		;;
	# -----------
	.bzip2|.gzip|.$LZ4|.lzip|.lzma)
		OPTS="-$(( $varLEVEL + ($varLEVEL-1) ))"
		;;
	# -----------
	.lzop)
		OPTS="-${varLEVEL}"
		;;
	# -----------
	.rar)
		OPTS="-m${varLEVEL}"

		if [ "$varSOLID" = "true" ]; then
			OPTS="${OPTS} -se"
		else
			OPTS="${OPTS} -s-"
		fi

		if [ "$varPASSWORD" != "" ] && [ "$varENCHEAD" = "false" ]; then
			PASSWORD="-p${varPASSWORD}"
		fi

		if [ "$varPASSWORD" != "" ] && [ "$varENCHEAD" = "true" ]; then
			PASSWORD="-hp${varPASSWORD}"
		fi

		if [[ "$varEXTENSION" == *".sfx" ]]; then
			if [ -e "${MYPATH}/resources/default.sfx" ]; then
				OPTS="${OPTS} -sfx${MYPATH}/resources/default.sfx"
			else
				OPTS="${OPTS} -sfxdefault.sfx"
			fi
		fi

		if [[ "$varEXTENSION" == *".exe" ]]; then
			if [ -e "${MYPATH}/resources/Default.SFX" ]; then
				OPTS="${OPTS} -sfx${MYPATH}/resources/Default.SFX"
			else
				OPTS="${OPTS} -sfxDefault.SFX"
			fi
		fi
		;;
	# -----------
	.xz)
		OPTS="-$(( $varLEVEL + ($varLEVEL-1) ))"
		# Enable multithreading. Not yet - it consumes a lot of RAM!
		#if echo | xz -T0 >/dev/null 2>&1; then
		#	OPTS="${OPTS} -T0"
		#fi
		;;
	# -----------
	.zip)
		OPTS="-$(( $varLEVEL + ($varLEVEL-1) ))"
		PASSWORD="$varPASSWORD"
		
		if [[ "$varEXTENSION" == *".sfx" ]]; then
			ZIPSFX=true
		else
			ZIPSFX=false
		fi
		;;
	# -----------
	.zstd)
		OPTS="-$(( $varLEVEL + ( ($varLEVEL-1) * (19/5) + $varLEVEL-($varLEVEL/2+1) ) ))"
		;;
esac

if [ "$varMKSQ_LIST" != "" ]; then
	MKOPTS=" -comp ${varMKSQ_LIST}"
else
	MKOPTS=''
fi

MKOPTS="${MKOPTS} -b ${varMKSQ_BLOCK}"

# -----------------------------------------------------------------------------
# Prepare PASS1
# -----------------------------------------------------------------------------

case "$(<$TMP_PASS1)" in
	.tar)
		if [ "$(readlink -f "$(which tar 2>/dev/null)" | grep "busybox")" ]; then
			TAR_OPT=''
		else
			TAR_OPT='--no-unquote'
		fi

		if [ ! "$(<$TMP_PASS2)" ]; then
			PASS1='tar '${TAR_OPT}' -cvf "$DESTARCH" -- "${IFILES[@]}"'
		else
			PASS1='tar '${TAR_OPT}' -cvf - -- "${IFILES[@]}" | '
		fi
		;;
	# -----------
	.cpio)
		if [ ! "$(<$TMP_PASS2)" ]; then
			PASS1='find "./${IFILES[@]}" | cpio -ov -H newc > "$DESTARCH"'
		else
			PASS1='find "./${IFILES[@]}" | cpio -ov -H newc | '
		fi
		;;
	# -----------
	.mke2fs)
		PASS1='DEST_TMP="${DESTARCH}_${$}.tmp"
			DATASIZE=$( du -c -s -B 1 -- "${IFILES[@]}" | tail -n 1 | cut -f1); RET=$?;
			[ $RET -eq 0 ] && [ $DATASIZE -lt $((256*1024)) ] && DATASIZE=$((256*1024))
			[ $RET -eq 0 ] && dd if=/dev/zero of="${DEST_TMP}" bs=$(( ($DATASIZE+($DATASIZE/10)+(10*1024*1024))/10 )) count=10; RET=$?;
			[ $RET -eq 0 ] && mke2fs -F -m 0 -- "${DEST_TMP}"; RET=$?;
			[ $RET -eq 0 ] && mount -t ext2 -o rw,sync,loop -- "${DEST_TMP}" $TMPMNT; RET=$?;
			[ $RET -eq 0 ] && cp -ravi -t $TMPMNT -- "${IFILES[@]}"; RET=$?;
			umount $TMPMNT 2>/dev/null || umount -l -f $TMPMNT 2>/dev/null
			# bug (?) in resize2fs - if filename contains ? it will be truncated
			[ $RET -eq 0 ] && resize2fs -M -- "${DEST_TMP}"; RET=$?
			[ $RET -eq 0 ] || { rm -f -- "${DEST_TMP}"; NoNeXiStEnTcOmMaNd 2>/dev/null; }' # make error
			[ "$(<$TMP_PASS2)" ] && PASS1=''${PASS1}' && cat "${DEST_TMP}" | '
		;;
	# -----------
	.mkisofs)
		VOLID="$(func_escape "${ARCHNAME:0:31}")"	# max 32 chars!

		# If only one dir selected, search for bootloader
		if [ ${#IFILES[@]} -eq 1 ] && [ -d "${IFILES[0]}" ]; then
			BOOTLOADER=''
			BOOTPARM=''
			JOLIET_OPT='-J'

			# Bootloader search "borrowed" from shinobar's "dir2iso"
			for B in grldr isolinux.bin; do
				[ -s "${IFILES[0]}/${B}" ] && BOOTLOADER="${B}" && break
			done

			# EFI (Fatdog64)
			EFI="$(find "${IFILES[0]}" -type f -name "efiboot.img" -printf '%P\n' 2>/dev/null)"

			if [ "$BOOTLOADER" ]; then
				BOOTPARM="-b "${BOOTLOADER}" -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
			fi

			if [ "$EFI" ]; then
				BOOTPARM="${BOOTPARM} -eltorito-alt-boot -eltorito-platform efi -b "${EFI}" -no-emul-boot"
			fi

			# Disable Joliet when creating Puppy ISO
			if [ "$BOOTLOADER" ] && [ -e "${IFILES[0]}/vmlinuz" -a -e "${IFILES[0]}/initrd"* ]; then
				JOLIET_OPT=''
			fi

			# TO_DO: isohybrid!!! But isohybrid doesn't use stdin & stdout...
			#if [ "$BOOTLOADER" ]; then
			#	if [ "$EFI" ]; then
			#		ISOHYBRID='isohybrid -u <boot.iso>'
			#	else
			#		ISOHYBRID='isohybrid -o 64 <boot.iso>'
			#	fi
			#fi

			if [ ! "$(<$TMP_PASS2)" ]; then
				PASS1='mkisofs -iso-level 4 $JOLIET_OPT -D -R -V "$VOLID" -o "$DESTARCH" $BOOTPARM -- "${IFILES[@]}"'
			else
				PASS1='mkisofs -iso-level 4 $JOLIET_OPT -D -R -V "$VOLID" $BOOTPARM -- "${IFILES[@]}" | '
			fi

		else

			# Create graft-points, in order to have all dirs separately
			# (bug? filename can't end with '\' backslash)
			for i in $(seq 0 $((${#IFILES[@]}-1)) ); do
				#IFILES[$i]="$(basename "${IFILES[$i]}")=${IFILES[$i]}"
				IFILES[$i]="${IFILES[$i]//=/\\=}=${IFILES[$i]//=/\\=}"	# also, escape =
			done

			if [ ! "$(<$TMP_PASS2)" ]; then
				PASS1='mkisofs -graft-points -J -D -R -V "$VOLID" -o "$DESTARCH" -- "${IFILES[@]}"'
			else
				PASS1='mkisofs -graft-points -J -D -R -V "$VOLID" -- "${IFILES[@]}" | '
			fi

		fi
		;;
	# -----------
	.$MKSQUASHFS)
		PASS1='$MKSQUASHFS "${IFILES[@]}" "$DESTARCH" -info $MKOPTS'
		: > $TMP_PASS2	# disable Pass 2
		;;
	# -----------
	*) PASS1= ;;
esac

# -----------------------------------------------------------------------------
# Prepare PASS2
# -----------------------------------------------------------------------------

case "$(<$TMP_PASS2)" in
	.$SEVENZ)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='$SEVENZ a $OPTS "$PASSWORD" -- "$DESTARCH" "${IFILES[@]}"'
		else
			PASS2='$SEVENZ a -si $OPTS "$PASSWORD" -- "$DESTARCH"'
		fi
		;;
	# -----------
	.bzip2)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='bzip2 -vv -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='bzip2 -vv -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.gzip)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='gzip -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='gzip -v -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.$LZ4)	# can't use -- yet (v1.8.2)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='$LZ4 -v $OPTS "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='$LZ4 -v $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.lzip)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='lzip -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='lzip -v -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.lzma)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='lzma -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='lzma -v -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.lzop)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='lzop -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='lzop -v -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.rar)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='rar a -ol $OPTS "$PASSWORD" -- "$DESTARCH" "${IFILES[@]}"'
		else
			PASS2='rar a -si"$(basename "${DESTARCH%.*}")" -ol $OPTS "$PASSWORD" -- "$DESTARCH" "${IFILES[@]}"'
		fi
		;;
	# -----------
	.xz)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='xz -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='xz -v -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	.zip)
		if [ ! "$(<$TMP_PASS1)" ]; then

			if [ "$PASSWORD" != "" ]; then
				PASS2='zip -v -r -y $OPTS -P"${PASSWORD}" - "${IFILES[@]}" > "$DESTARCH"'
			else
				PASS2='zip -v -r -y $OPTS - "${IFILES[@]}" > "$DESTARCH"'
			fi

		else

			mkdir -p "${WORKDIR}/FIFO_tmp"
			FIFO="${WORKDIR}/FIFO_tmp/$(basename "${DESTARCH%.*}")"
			PASS1='mkfifo "$FIFO"; '${PASS1}' cat - > "$FIFO" | '

			if [ "$PASSWORD" != "" ]; then
				PASS2='zip -j -v -y $OPTS -P"${PASSWORD}" - -FI "$FIFO" > "$DESTARCH"'
			else
				PASS2='zip -j -v -y $OPTS - -FI "$FIFO" > "$DESTARCH"'
			fi

		fi

		# Some gymnastics needed for .sfx
		PASS2=''${PASS2}'; RET=$?
			if [ $RET -eq 0 ] && [ "$ZIPSFX" = "true" ]; then
				cat "$(which unzipsfx)" "${DESTARCH}" > "${DESTARCH}_${$}.tmp"
				mv -f -- "${DESTARCH}_${$}.tmp" "${DESTARCH}"
				chmod +x "${DESTARCH}"
				zip -A "${DESTARCH}"
			elif [ $RET -ne 0 ]; then
				NoNeXiStEnTcOmMaNd 2>/dev/null	# make error
			fi'
		;;
	# -----------
	.zstd)
		if [ ! "$(<$TMP_PASS1)" ]; then
			PASS2='zstd -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"'
		else
			PASS2='zstd -v -c $OPTS > "$DESTARCH"'
		fi
		;;
	# -----------
	*) PASS2= ;;
esac

if [ "$(<$TMP_PASS1)" = ".mke2fs" ]; then
	if [ ! "$PASS2" ]; then
		PASS1=''${PASS1}' && mv -n -- "${DEST_TMP}" "${DESTARCH}"'
	else
		PASS2=''${PASS2}' && rm -f -- "${DEST_TMP}"'
	fi
fi

# -----------------------------------------------------------------------------
# Escape \ " and ` also in input filenames
# -----------------------------------------------------------------------------

for i in $(seq 0 $((${#IFILES[@]}-1))); do
	IFILES[$i]="$(func_escape "${IFILES[$i]}")"
done

# -----------------------------------------------------------------------------
# Prepare exec script
# -----------------------------------------------------------------------------

#OFFCOL="\e[30;107m"
#REDCOL="\e[31;107m"
#BLUECOL="\e[34;107m"
#GREENCOL="\e[32;107m"

OFFCOL="\e[00m"
REDCOL="\e[0;31m"
BLUECOL="\e[0;34m"
GREENCOL="\e[0;32m"

echo '#! /bin/bash
set -o pipefail' > "$TMP_EXEC"

for i in $(seq 0 $((${#IFILES[@]}-1))); do
	echo "IFILES[$i]=\"${IFILES[$i]}\"" >> "$TMP_EXEC"				
done

cat << EOF >> "$TMP_EXEC"

trap '[ -f "$WORKDIR/retval" ] || rm -f "\$DESTARCH"' EXIT
trap '[ -f "\$DEST_TMP" ] && rm -f -- "\$DEST_TMP"' EXIT

echo \${$} > '${WORKDIR}/PID'

TMPMNT="$TMPMNT"	
DESTARCH="$DESTARCH"
MKSQUASHFS="$MKSQUASHFS"
SEVENZ="$SEVENZ"
LZ4="$LZ4"
OPTS="$OPTS"	
MKOPTS="$MKOPTS"	
VOLID="$VOLID"
BOOTPARM="$BOOTPARM"
JOLIET_OPT="$JOLIET_OPT"
PASSWORD="$PASSWORD"
ZIPSFX="$ZIPSFX"
FIFO="$FIFO"
varCHKSUM="$varCHKSUM"
PASS1='${PASS1}'
PASS2='${PASS2}'

echo -e "${OFFCOL}"
clear
printf -- "${BLUECOL}=%.0s${OFFCOL}" {0..77}; echo
echo -ne "${BLUECOL}$(gettext "Creating:")${OFFCOL} "; echo "\${DESTARCH}"
printf -- "${BLUECOL}=%.0s${OFFCOL}" {0..77}; echo

eval "\${PASS1}\${PASS2}"; RET=\$?

if [ \$RET -eq 0 ] && [ "\$varCHKSUM" = "true" ]; then
	CURDIR="\$(pwd)"
	cd "\$(dirname "\${DESTARCH}")"
	md5sum -- "\$(basename "\${DESTARCH}")" > "\$(basename "\${DESTARCH}").md5"
	sha1sum -- "\$(basename "\${DESTARCH}")" > "\$(basename "\${DESTARCH}").sha1"
	sha256sum -- "\$(basename "\${DESTARCH}")" > "\$(basename "\${DESTARCH}").sha256"
	cd "\${CURDIR}"
fi

echo; printf -- "${BLUECOL}*%.0s${OFFCOL}" {0..77}; echo
echo -e "${OFFCOL}"
#sync

if [ \$RET -ne 0 ]; then
	echo -ne "${REDCOL}$(gettext "Creation of") ${BLUECOL}"
	echo -n "\$(basename "\${DESTARCH}") "
	echo -e "${REDCOL}$(gettext "has failed!")"
	rm -f "\$DESTARCH"
else
	echo -ne "${BLUECOL}"
	echo -n "\$(basename "\${DESTARCH}") "
	echo -e "${GREENCOL}$(gettext "has been successfully created!")"
fi

echo -e "${OFFCOL}"
echo \$RET > '$WORKDIR/retval'

EOF

chmod +x "$TMP_EXEC"

# -----------------------------------------------------------------------------
# Ok, pack it!
# -----------------------------------------------------------------------------

#INPUT_SIZE=$(du -hcs "${IFILES[@]}" | tail -n -1 | cut -f1)
#export INPUT_SIZE
export DESTARCH

if [ "$varVERBOSE" = "false" ]; then
  
	#echo 'gtk-theme-name="default"' > $WORKDIR/gtkrc_custom
	#export GTK2_RC_FILES="${HOME}/.gtkrc-2.0:$WORKDIR/gtkrc_custom"

	$GTKDIALOG -cp GUI_WAIT & GTKPID=$!
  
	$TMP_EXEC 2>&1 | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K|H|J]//g" | tr -s '\b' '\n' > "$WORKDIR/packit.log"
	RET="$(<$WORKDIR/retval)"
	cd "$OLDDIR"

	kill -s 0 $GTKPID 2>/dev/null && [ "$(ps $GTKPID | grep "$GTKDIALOG")" ] && kill $GTKPID

	if [ $RET -eq 0 ]; then
		func_show_success
		exit 0
	else
		func_show_fail
		case "$?" in
			2) func_show_log; exit 1 ;;
			1) exec "$MYNAME" "$@" ;;
			*) exit 1 ;;
		esac
	fi

else

	if [ ! "$($GTKDIALOG --version | grep -w 'VTE')" ]; then
		echo '/bin/sh' >> "$TMP_EXEC"

		for i in $TERM defaultterm urxvt xterm rxvt lxterminal sakura; do
			which "$i" >/dev/null 2>&1 && { EXEC_TERMINAL="$i"; break; }
		done

		$EXEC_TERMINAL -T "$APPNAME" -e "$TMP_EXEC"
    
	else
  
		export GUI_VTE='
		<window title="'$APPNAME'" image-name="'${APPICON}'">
			<vbox>
				<terminal argv0="/bin/sh"
					xscrollback-lines="100000"
					has-focus="true"
					text-background-color="#fff"
					text-foreground-color="#000">
					<variable>vte0</variable>
					<width>82</width>
					<input>echo "HISTFILE=; '${TMP_EXEC}'"</input>
					<action signal="child-exited">exit:EXIT</action>
				</terminal>
			</vbox>
			<action signal="delete-event">EXIT:abort</action>
		</window>'
      
		$GTKDIALOG -cp GUI_VTE
    
	fi
fi

############################### |* @ ( |< 1 7  ################################
