#!/bin/bash
#based on defaults-chooser by sc0ttman
#GPL 2015 - Sigmund Berglund (zigbert)

set -a #export all functions and variables
export TEXTDOMAIN=puppyapps
export OUTPUT_CHARSET=UTF-8
DEFAULTAPPS=""
default_apps='archiver audioeditor audiomixer audioplayer barehtmlviewer browser calendar cdplayer cdrecorder chat chmviewer connect contact draw email filemanager htmleditor htmlviewer imageeditor imageviewer mediaplayer musicplayer paint pdfviewer processmanager screenshot run search spreadsheet terminal texteditor textviewer torrent wordprocessor'
IGNORE_ALREADY_SET=""
APPS_DEFAULT_EXEC="$(gettext 'Autodetect')"

export TMPDIR=/tmp/apps/puppyapps
! [ -d $TMPDIR ] && mkdir -p ${TMPDIR}

GUI_SORT=2
GUI_MAXROWS=10
GUI_COUNT=0 #count available default* - for columns in gui
   #for this to work, we must avoid creating a subshell or pipe | (*)


    ############################
    #                          #
    #        Functions         #
    #                          #
    ############################

desktop_output () {
	LANG=C grep -E '^Name=|^GenericName=|^Comment=|^MimeType=|^Icon=' /usr/share/applications/*.desktop | \
	grep -v "/usr/share/applications/default.*" > ${TMPDIR}/puppyapps_desktop_output #we do this one time, instead of in search_desktop
}

get_default () {
	LANG=C
	APP="$1"
	if [ "$DEFAULTAPPS" ]; then
		if ! ( echo "$DEFAULTAPPS" | grep -qw "default$1"); then
			echo '###'
			return 1
		fi
	fi
	F="/usr/local/bin/default$1"
	if [ ! -f "$F" ]; then
		echo '###'
		return 1
	fi
	if [ "$IGNORE_ALREADY_SET" ] ; then
		read -r P < ${TMPDIR}/puppyapps_items_$APP ; echo $P ; return 5
	fi
	#strip out 'exec ', ' "$@"', and all whitespace from the end of the last line of the file
	while read line ; do
		case $line in '#'*) continue ;;
		*'exec '*)
			P="${line#*exec }" #remove '*exec '
			P="${P%% \$*}" #remove ' $*'
			P="${P%% \"*}" #remove ' "*'
			break ;;
		esac
	done < $F
	#special treatment of defaultapps
	case $P in #if default* is the target (default value), we look into the array
		puppyapps*|default*)
			read -r P < ${TMPDIR}/puppyapps_items_$APP
			echo $P
			return 5
			;;
	esac
	echo $P
	return 0
}

remove_desktop() {
	grep -viE "$1" ${TMPDIR}/puppyapps_desktop_output
}
search_desktop() {
	grep -iE "$1" ${TMPDIR}/puppyapps_desktop_output | cut -f1 -d':' | uniq 
}
search_desktop2() { grep -iE "$1" | cut -f1 -d':' | uniq ; }

apps_array() {
	#if no target is set in /usr/local/bin/default*, we gbrab the first existing executable in the list echoed from here.
	#therefor, be sure to included the most valuable apps first in the static part of the list.
	#executables not installed on system will NOT be in the echoed list.
	LANG=C
	case $1 in
	archiver)
		APPLIST="`echo -e "file-roller\nengrampa\npeazip\npupzip\nxarchiver\nxarchive\n"`
		$(search_desktop 'archive')"
		;;
	audioeditor)
		APPLIST="`echo -e "audacity\nmhwaveedit\nsweep\n"`
		$(search_desktop '(audio|sound).*editor')"
		;;
	audiomixer)
		APPLIST="`echo -e "gnome-alsamixer\nretrovol\nrxvt -e alsamixer\n"`
		$(search_desktop 'mixer')"
		;;
	audioplayer)
		APPLIST="`echo -e "deadbeef\naudacious\naqualung\npmusic\n"`
		$(search_desktop '(audio|media).*player')"
		;;
	barehtmlviewer)
		APPLIST="`echo -e "dillo\nPuppyBrowser\nhv3\nmini-web\nskipstone\nmidori\noperamini\nelinks\nicecat\nxlynx\nw3m\nw3m-term"`"
		;;
	browser)
		APPLIST="`echo -e "opera\npalemoon\nfirefox\nchromium\nchrome\nicecat\nmidori\nseamonkey\nqtweb\ndillo\n"`
		$(search_desktop 'web.*browser')"
		;;
	calendar)
		APPLIST="`echo -e "osmo\nnotecase\nXdialog --calendar '' 350x270\nyad --calendar"`"
		;;
	cdplayer)
		APPLIST="`echo -e "\ndeadbeef all.cda\npmusic_CD\npmusic -c\npcd\n"`
		$(search_desktop 'cd.*player')"
		;;
	cdrecorder)
		APPLIST="`echo -e "k3b\npburn\ngraveman\ngrafburn\nburniso2cd\npeasydisc"`
		$(search_desktop 'burn')"
		;;
	chat)
		APPLIST="`echo -e "hexchat-wrapper\nhexchat\n"`
		$(search_desktop 'chat')"
		;;
	chmviewer)
		APPLIST="`echo -e "pzchmview\nchmsee\nkchmviewer\ngnochm\nxchm\nkchm\n"`"
		;;
	connect)
		APPLIST="`echo -e "connectwizard\\nsns\nfrisbee\nnet-setup.sh\npupdial\npppoe_gui\npgprs-shell\ngnome-ppp\n"`"
		;;
	contact)
		APPLIST="`echo -e "osmo\nmozaddressbook\nsylpheed\nthunderbird\n"`"
		;;
	draw)
		APPLIST="`echo -e "inkscape\nlibreoffice5.0 --draw\ninscapelite\n"`
		$(search_desktop '(draw|(vector|graphics|image).*editor)')"
		;;
	email)
		APPLIST="`echo -e "thunderbird\nsylpheed\n"`
		$(remove_desktop 'libfm' | search_desktop2 'mail')"
		;;
	filemanager)
		APPLIST="`echo -e "spacefm\npcmanfm\nroxfiler\n"`
		$(search_desktop 'file.*manager')"
		;;
	htmleditor)
		APPLIST="`echo -e "libreoffice5.0 --web\nbluefish\ngeany\n"`
		$(search_desktop '(html|web|text).*editor')"
		;;
	htmlviewer)
		APPLIST="`echo -e "opera\nqtweb\ndillo\nmozstart\nmidori\noperamini"`
		$(search_desktop '(html|web)')"
		;;
	imageeditor)
		APPLIST="`echo -e "gimp\nmtpaint\n"`
		$(search_desktop '(graphics|image).*editor')"
		;;
	imageviewer)
		APPLIST="`echo -e "viewnior\ngpicview\n"`
		$(search_desktop '(graphics|image|picture).*(editor|viewer)')"
		;;
	mediaplayer)
		APPLIST="`echo -e "smplayer\nvlc1\ngnomemplayershell\nvlc\ngxine\nxine\ngnome-mplayer\nmpv\nmplayer"`
		$(search_desktop 'media.*player')"
		;;
	musicplayer)
		APPLIST="`echo -e "deadbeef\naudacious\npmusic\n"`
		$(search_desktop '(audio|media).*player')"
		;;
	paint)
		APPLIST="`echo -e "mtpaint\ngimp\n"`
		$(search_desktop '(graphics|image).*editor')"
		;;
	pdfviewer)
		APPLIST="`echo -e "evince\nepdfview\n"`
		$(search_desktop 'pdf.*(viewer|reader)')"
		;;
	processmanager)
		APPLIST="`echo -e "lxtask\npprocess\nhtop\n"`
		$(search_desktop 'process')"
		;;
	run)
		APPLIST="`echo -e "gmrun\nkrunner\nxfce4-appfinder\nlxpanelctl run\nprun\n"`"
		;;
	screenshot)
		APPLIST="`echo -e "tas\nscreeny\nscrot\nmtpaint -s"`
		$(search_desktop 'screenshot')"
		;;
	search)
		APPLIST="`echo -e "pfind\nfind2list\n"`
		$(search_desktop '(search|find)')"
		;;
	spreadsheet)
		APPLIST="`echo -e "libreoffice5.0 --calc\net\ngnumeric\nmtcelledit\n"`
		$(search_desktop 'spreadsheet')"
		;;
	terminal)
		APPLIST="`echo -e "lxterminal\nurxvt\nrxvt\nxterm\n"`
		$(search_desktop 'terminalemulator')"
		;;
	texteditor)
		APPLIST="`echo -e "geany\nleafpad\nrxvt -e mp\nrxvt -e nano\nrxvt -e vi"`
		$(search_desktop 'text.*editor')"
		;;
	textviewer)
		APPLIST="`echo -e "leafpad\ngeany\nrxvt -e mp\nrxvt -e nano\n"`
		$(search_desktop 'text')"
		;;
	torrent)
		APPLIST="$(search_desktop 'torrent')"
		;;
	wordprocessor)
		APPLIST="`echo -e "libreoffice5.0 --writer\nwps\nabiword\n"`
		$(search_desktop 'wordp')"
		;;
	esac
	(
	while read J; do
		[ ! "$J" ] && continue
		#grep exec from *.desktop file
		P="$J"
		if [ -f "$J" ] ; then
			P="`grep -iFm 1 'exec=' "$J"`"
			P="${P#*=}" # | cut -f2 -d'='
			P="${P%% \%*}" # remove %* [pcmanfm %U -> pcmanfm]
		fi
		#check if installed and ready to execute (made for static arrays)
		E="$P"
		case $P in rxvt*|*term*) E="${P#* -e }" ;; esac #E="$(awk -F ' -e ' '{print $2}' <<< "$P")";;
		#echo $P ; continue ## skip installed
		which "${E%% *}" >/dev/null 2>&1 && echo "$P" ## echo
	done <<< "$APPLIST"
	) | awk '!a[$0]++' #awk removes duplicate lines without sorting
}

update_defaults () {
	LANG=C
	# change the default*** files, using the 'change_default' util
	for I in $appz ; do
	  case ${I#default} in
		archiver)      change_default 'archiver' "$ARCHIVER" ;;
		audioeditor)   change_default 'audioeditor' "$AUDIOEDITOR" ;;
		audiomixer)    change_default 'audiomixer' "$AUDIOMIXER" ;;
		audioplayer)   change_default 'audioplayer' "$AUDIOPLAYER" ;;
		barehtmlviewer)change_default 'barehtmlviewer' "$BAREHTMLVIEWER" ;;
		browser)       change_default 'browser' "$BROWSER" ;;
		calendar)      change_default 'calendar' "$CALENDAR" ;;
		cdplayer)      change_default 'cdplayer' "$CDPLAYER" ;;
		cdrecorder)    change_default 'cdrecorder' "$CDRECORDER" ;;
		chat)          change_default 'chat' "$CHAT" ;;
		chmviewer)     change_default 'chmviewer' "$CHMVIEWER" ;;
		connect)       change_default 'connect' "$CONNECT" ;;
		contact)       change_default 'contact' "$CONTACT" ;;
		draw)          change_default 'draw' "$DRAW" ;;
		email)         change_default 'email' "$EMAIL" ;;
		filemanager)   change_default 'filemanager' "$FILEMANAGER" ;;
		htmleditor)    change_default 'htmleditor' "$HTMLEDITOR" ;;
		htmlviewer)    change_default 'htmlviewer' "$HTMLVIEWER" ;;
		imageeditor)   change_default 'imageeditor' "$IMAGEEDITOR" ;;
		imageviewer)   change_default 'imageviewer' "$IMAGEVIEWER" ;;
		mediaplayer)   change_default 'mediaplayer' "$MEDIAPLAYER" ;;
		musicplayer)   change_default 'musicplayer' "$MUSICPLAYER" ;;
		paint)         change_default 'paint' "$PAINT" ;;
		pdfviewer)     change_default 'pdfviewer' "$PDFVIEWER" ;;
		processmanager)change_default 'processmanager' "$PROCESSMANAGER" ;;
		run)           change_default 'run' "$RUN" ;;
		screenshot)    change_default 'screenshot' "$SCREENSHOT" ;;
		search)        change_default 'search' "$SEARCH" ;;
		spreadsheet)   change_default 'spreadsheet' "$SPREADSHEET" ;;
		terminal)      change_default 'terminal' "$TERMINAL" ;;
		texteditor)    change_default 'texteditor' "$TEXTEDITOR" ;;
		textviewer)    change_default 'textviewer' "$TEXTVIEWER" ;;
		torrent)       change_default 'torrent' "$TORRENT" ;;
		wordprocessor) change_default 'wordprocessor' "$WORDPROCESSOR" ;;
	  esac
	done
	xdg-mime default defaultbrowser-mime.desktop x-scheme-handler/http
	xdg-mime default defaultbrowser-mime.desktop x-scheme-handler/https
	xdg-mime default defaultbrowser-mime.desktop x-scheme-handler/ftp
	xdg-mime default defaultbrowser-mime.desktop x-scheme-handler/chrome
	xdg-mime default defaultbrowser-mime.desktop text/html
	xdg-mime default defaultbrowser-mime.desktop application/x-extension-htm
	xdg-mime default defaultbrowser-mime.desktop application/x-extension-html
	xdg-mime default defaultbrowser-mime.desktop application/x-extension-shtml
	xdg-mime default defaultbrowser-mime.desktop application/xhtml+xml
	xdg-mime default defaultbrowser-mime.desktop application/x-extension-xhtml
	xdg-mime default defaultbrowser-mime.desktop application/x-extension-xht
	. /usr/lib/gtkdialog/box_ok "$(gettext 'Default apps')" complete "$(gettext 'Your default apps have been updated.')"
}

change_default () {
	TYPE="$1"
	FILE="$2"
	if [ "$TYPE" = "filemanager" ] ; then
		case $FILE in rox|*"/rox")
			FILE=roxfiler
		esac
	fi
	#check if the default* file exists
	if [ "$FILE" = '###' ] || [ ! "$FILE" ]; then
		echo
	elif echo "$FILE" | grep -iE "puppyapps|autodetect"; then
		echo -e "#!/bin/sh\nexec puppyapps default$TYPE"' "$@"' > "/usr/local/bin/default$TYPE"
		echo "Default $TYPE will be autodetected by Puppy"
	elif echo "$FILE" | grep -qw "default$TYPE"; then
		echo "'default$TYPE' cannot set to itself."
	elif [ -f "/usr/local/bin/default$TYPE" ];then
		#replace the old program with the new one
		if [ "$FILE" ]; then
			echo -e "#!/bin/sh\nexec $FILE \"\$@\"" > "/usr/local/bin/default$TYPE" #add new comand
		fi
	else #the default* file given was not found
		echo "The file '/usr/local/bin/default$TYPE' not found."
	fi
}

    ############################
    #                          #
    #         Program          #
    #                          #
    ############################

#parameters
for arg in $@ ; do
	case $1 in
		default*)
			desktop_output
			RUNAPP=${1#default} #RUNAPP="`sed 's%default%%' <<< "$1"`"
			shift
			apps_array $RUNAPP > ${TMPDIR}/puppyapps_items_$RUNAPP
			RUNAPP_EXEC="`get_default "$RUNAPP"`"
			if [ "$RUNAPP_EXEC" ]; then
				exec $RUNAPP_EXEC "$@"
			else
				. /usr/lib/gtkdialog/box_ok "$(gettext 'Default apps')" error "$(gettext 'Generic app not found on your system'): <b>default$RUNAPP</b>"
			fi
			exit 0
			;;
		-c|set)
			change_default "$2" "$3"
			exit
			;;
		-l)
			shift
			desktop_output
			TMP=${default_apps}
			[ "$1" ] && TMP="$@"
			for I in $TMP; do
				echo -n "$I: "
				apps_array $I > ${TMPDIR}/puppyapps_items_$I 2> /dev/null
				get_default $I
			done
			exit
			;;
		-ll)
			shift
			desktop_output
			TMP=${default_apps}
			[ "$1" ] && TMP="$@"
			for I in $TMP; do
				echo -e "\n-----------------------\n$I\n-----------------------"
				apps_array $I 2>/dev/null
			done
			exit
			;;
		-m) ###gui###
			shift
			DEFAULTAPPS=$(
				while [ "$1" ]; do
					app=$1
					[[ "$app" != default* ]] && app="default${app}"
					echo -n "$app "
					shift
				done
			)
			;;
		-takeover)
			shift
			appz=${default_apps}
			[ "$1" ] && appz="$@"
			for app in ${appz} ; do
				case "${default_apps}" in *"${app}"*)
					file=/usr/local/bin/default${app}
					echo -e "#!/bin/sh\nexec puppyapps default${app} \"\$@\"" > $file
					chmod +x $file
					echo "default${app} > $file"
				esac
			done
			exit
			;;
		-setdefs)
			desktop_output
			IGNORE_ALREADY_SET=1
			shift
			appz=${default_apps}
			[ "$1" ] && appz="$@"
			for app in ${appz} ; do
				case "${default_apps}" in *"${app}"*)
					file=/usr/local/bin/default${app}
					apps_array $app > ${TMPDIR}/puppyapps_items_$app
					RUNAPP_EXEC=$(get_default "$app")
					if [ $? -eq 1 -o ! "$RUNAPP_EXEC" ] ; then
						echo -e "#!/bin/sh\nexec puppyapps default${app} \"\$@\"" > $file
						echo "[autodetect] > $file"
					else
						echo -e "#!/bin/sh\nexec $RUNAPP_EXEC \"\$@\"" > $file
						echo "$RUNAPP_EXEC > $file"
					fi
					chmod +x $file
				esac
			done
			exit
			;;
		-sort) ###gui###
			shift
			case $1 in
				0|1|2) GUI_SORT=$1 ;;
				*) echo "ERROR: -sort only accepts 0,1,2" >&2 ; exit 1;;
			esac
			;;
		-rows) ###gui###
			shift
			if [[ "$1" -gt 0 && "$1" -lt 101 ]] ; then
				GUI_MAXROWS=$1
			else
				echo "ERROR: -rows only accepts 1-100" >&2 ; exit 1
			fi
			;;

		-h|--help)
			echo 'Usage: '$0' [OPTION(S)]

 Options
  default*       Starts the app based on the array in defaultapps
  
  set TYPE EXEC
  -c TYPE EXEC   Change defaultapp without gui
                 EXEC is the new default target application
                 TYPE is one of the following
                 For supported TYPEs, see below
                 Example:
                 puppyapps -c brower firefox
                 puppyapps -c imageeditor /path/to/gimp
  -l [TYPE]      List default executable for TYPE(s)
                 If no TYPE is specified, show all TYPEs
                 For supported TYPEs, see below
  -ll [TYPE]     List installed executables in array
                 Sorted by priority
                 If no TYPE is specified, show all TYPEs
                 For supported TYPEs, see below
  -m default*    Manage only spesified defaultapp(s)
                 seperate apps with a space
  -prefix PATH   Using alternative root. for Woof-CE
  -takeover      Make puppyapps itself manage all the defaultapps
                 Puppyapps will decide what to run first, and will look
                 in the system for alternatives making the system
                 work in different scenarios
  -setdefs       Set defaults for all default apps.
                 Puppyapps will determine what programs are present
                 and choose one of them and will write it to the defaultapp.
                 If no program is found for a specific default app,
                 then puppyapps will manage it.
  -sort 0..2     For the GUI
                 0) Dont sort
                 1) Sort by internal category name
                 2) Sort by category label [default]
  -rows N        (gui) max number of rows per column [default: '${GUI_MAXROWS}']

  -h, --help     Show this help message
  
  
supported TYPEs:
----------------'
echo ${default_apps} | tr ' ' '\n'

			exit
			;;
	esac
	shift
done

    ############################
    #           GUI            #
    ############################

DC_ICON=/usr/share/pixmaps/puppy/execute.svg

if [ ! "$DEFAULTAPPS" ]; then
	export PuppyappsWizard='
<window title="'$(gettext 'Default Applications Chooser')'" icon-name="gtk-preferences" resizable="false">
<vbox space-expand="true" space-fill="true">
  <vbox spacing="10" space-expand="true" space-fill="true">
  <frame '$(gettext 'Categories')'>
    <hbox spacing="10" homogeneous="true" space-expand="true" space-fill="true">
      <button image-position="2">
        <label>'$(gettext 'Multimedia')'</label>
        '"`/usr/lib/gtkdialog/xml_button-icon multimedia.svg huge`"'
        <action>EXIT:Multimedia</action>
      </button>
      <button image-position="2">
        <label>'$(gettext 'Document')'</label>
        '"`/usr/lib/gtkdialog/xml_button-icon document.svg huge`"'
        <action>EXIT:Document</action>
      </button>
      <button image-position="2">
        <label>'$(gettext 'System')'</label>
         '"`/usr/lib/gtkdialog/xml_button-icon execute.svg huge`"'
        <action>EXIT:System</action>
      </button>
      <button image-position="2">
        <label>'$(gettext 'All')'</label>
         '"`/usr/lib/gtkdialog/xml_button-icon add.svg huge`"'
        <action>EXIT:All</action>
      </button>
    </hbox>
  </frame>
  </vbox>
  <hbox space-expand="false" space-fill="false">
    <button>'"`/usr/lib/gtkdialog/xml_button-icon quit`"'<label>'$(gettext 'Quit')'</label></button>
  </hbox>
 </vbox>
</window>'
	. /usr/lib/gtkdialog/xml_info gtk #build bg_pixmap for gtk-theme
	eval "`gtkdialog --center -p PuppyappsWizard`"
	unset PuppyappsWizard

	case $EXIT in
	Multimedia)
		GUI_MAXROWS=5
		DEFAULTAPPS='defaultmediaplayer defaultmusicplayer defaultaudioplayer defaultaudioeditor defaultaudiomixer defaultcdplayer defaultcdrecorder defaultpaint defaultdraw defaultimageeditor defaultimageviewer'
		DC_ICON=/usr/share/pixmaps/puppy/multimedia.svg
		;;
	Document)
		GUI_MAXROWS=4
		DEFAULTAPPS='defaultwordprocessor defaulttexteditor defaulttextviewer defaultpdfviewer defaultchmviewer defaultspreadsheet defaulthtmleditor defaulthtmlviewer defaultbarehtmlviewer'
		DC_ICON=/usr/share/pixmaps/puppy/document.svg
		;;
	System)
		GUI_MAXROWS=7
		DEFAULTAPPS='defaultcalendar defaultcontact defaultscreenshot defaultfilemanager defaultarchiver defaultsearch defaultterminal defaultprocessmanager defaultrun defaultbrowser defaultemail defaultconnect defaultchat defaulttorrent'
		;;
	All)
		GUI_MAXROWS=16
		DC_ICON=/usr/share/pixmaps/puppy/puppy_config.svg
		;;
	*) exit ;;
	esac
fi

#check if -m switch has been used
if [ -z "$DEFAULTAPPS" -a -z "$1" ]; then
	PSRESULT=$(busybox ps)
	P=$(echo "$PSRESULT" | grep -w "^[ ]*$PPID" | grep -o '/usr/local/bin/default[^ ]*')
	[ "$P" ] && DEFAULTAPPS=$(basename $P)
fi

desktop_output

#splash
if [ ! "$DEFAULTAPPS" -o "$SHOW_SPLASH" != "" ]; then
	/usr/lib/gtkdialog/box_splash -close never -fontsize large -text " $(gettext 'Default Applications Chooser...')" &
	XPID=$!
fi

for I in ${default_apps} ; do
	if [ ! -f ${TMPDIR}/puppyapps_items_$I ] ; then
		( echo "$APPS_DEFAULT_EXEC" ; apps_array $I ) > ${TMPDIR}/puppyapps_items_$I
	fi
done

#for comboboxes - to make startup faster
appz=${default_apps}
[ "$DEFAULTAPPS" ] && appz=$DEFAULTAPPS
for I in $appz ; do
	( echo "$APPS_DEFAULT_EXEC" ; apps_array $I ) > ${TMPDIR}/puppyapps_items_$I
done

make_item() {
	TOP=$@
	[ "$TOP" ] || TOP='@'
	#avoid the default is set to itself
	(echo "$TOP"; grep -vw "$TOP") | grep -vw "default$APP" | sed -e 's|\(..*\)|<item>\1</item>|' | sed -e 's/>@</></'
}

make_box() {
	VARIABLE=$1
	ICON=$2
	shift 2
	LABEL="$@"
	APP="${VARIABLE,,}" ##lowercase #APP="`echo $2 | tr [A-Z] [a-z]`"
	#find default executable
	DEFAULT_EXEC=$(get_default $APP)
	retval=$?
	#echo $DEFAULT_EXEC $retval >&2 ## DEBUG
	case $retval in
		1) return ;; #[ "$DEFAULT_EXEC" = '###' ] && return #skip if no default* is available
		5) DEFAULT_EXEC="$APPS_DEFAULT_EXEC" ;;
	esac
	[ ! "$DEFAULT_EXEC" ] && return #do not allow empty $DEFAULT_EXEC
	#new frame
	if [ ${GUI_COUNT} -ge ${GUI_MAXROWS} ]; then #ge = greater or equal
		GUI_COUNT=0
		echo '</frame><frame>'
	fi
	GUI_COUNT=$(($GUI_COUNT + 1))
	#---
	echo '
	<vbox space-expand="false" space-fill="false">
	  <hbox space-expand="true" space-fill="true">
	    '$(/usr/lib/gtkdialog/xml_pixmap $ICON icon)'
	    <vbox space-expand="true" space-fill="true">
	      <text xalign="0" space-expand="true" space-fill="true"><label>"'$LABEL'"</label></text>
	      <comboboxentry space-expand="false" space-fill="false" tooltip-text="'$(gettext 'Choose your preferred default program, or type command.')'">
	        <variable>'$VARIABLE'</variable>
	        <default>'$DEFAULT_EXEC'</default>
	        <input file>'${TMPDIR}'/puppyapps_items_'$APP'</input>
	      </comboboxentry>
	    </vbox>
	  </hbox>
	</vbox>'
}

list_active (){
	/usr/lib/gtkdialog/box_splash -close never -fontsize large -icon_width 60 -icon /usr/share/pixmaps/puppy/puppy_config.svg -text "$(gettext 'Default Applications Chooser...')" &
	XPID=$!
	puppyapps -l > ${TMPDIR}/puppyapps_tmp
	kill "$XPID"
	defaulttextviewer ${TMPDIR}/puppyapps_tmp &
}

APPDATA="WORDPROCESSOR document.svg $(gettext 'Word processor')
TEXTEDITOR edit.svg $(gettext 'Text editor')
TEXTVIEWER document_viewer.svg $(gettext 'Text viewer')
PDFVIEWER pdf.svg $(gettext 'PDF viewer')
CHMVIEWER document_viewer.svg $(gettext 'CHM viewer')
SPREADSHEET spreadsheet.svg $(gettext 'Spreadsheet')
CALENDAR calendar.svg $(gettext 'Calendar')
CONTACT user.svg $(gettext 'Contact')
MEDIAPLAYER multimedia.svg $(gettext 'Media player')
MUSICPLAYER audio.svg $(gettext 'Music player')
AUDIOPLAYER audio.svg $(gettext 'Audio Player')
AUDIOEDITOR edit_sound.svg $(gettext 'Audio Editor')
AUDIOMIXER sound_mixer.svg $(gettext 'Audio Mixer')
CDPLAYER cd_audio.svg $(gettext 'CD player')
CDRECORDER cd_burn.svg $(gettext 'CD recorder')
PAINT draw.svg $(gettext 'Paint')
DRAW draw_vector.svg $(gettext 'Draw')
IMAGEEDITOR edit_image.svg $(gettext 'Image editor')
IMAGEVIEWER image_viewer.svg $(gettext 'Image viewer')
SCREENSHOT photocamera.svg $(gettext 'Screenshot')
FILEMANAGER directory.svg $(gettext 'File manager')
ARCHIVER package_compressed.svg $(gettext 'Archiver')
SEARCH find.svg $(gettext 'Search')
TERMINAL terminal.svg $(gettext 'Terminal')
PROCESSMANAGER execute.svg $(gettext 'Process manager')
RUN execute.svg $(gettext 'App runner')
BROWSER internet.svg $(gettext 'Web browser')
EMAIL mail.svg $(gettext 'Mail')
HTMLEDITOR edit_html.svg $(gettext 'HTML editor')
HTMLVIEWER document_viewer.svg $(gettext 'HTML viewer')
CONNECT internet_connect.svg $(gettext 'Connect')
CHAT chat.svg $(gettext 'Chat')
BAREHTMLVIEWER internet.svg $(gettext 'Bare HTML Viewer')
TORRENT install.svg $(gettext 'BitTorrent Client')"

case $GUI_SORT in
	0) APPDATA2="$APPDATA" ;; 						#dont sort
	1) APPDATA2="$(echo "$APPDATA" | sort)" ;;		#sort by category name
	2) APPDATA2="$(echo "$APPDATA" | sort -k3)" ;;	#sort by label
	*) echo "ERROR: invalid value for \$GUI_SORT" >&2 ; exit 1;;
esac

DHEIGHT=0
TOTALITEMS=0
while read adata ; do
	TOTALITEMS=$(($TOTALITEMS + 1))
	DHEIGHT=$(($DHEIGHT + 35))
	make_box $adata
done <<< "$APPDATA2" > ${TMPDIR}/gui_boxes #(*)
[ $(($TOTALITEMS%2)) -eq 1 ] && DHEIGHT=$(($DHEIGHT+35))
[ $DHEIGHT -gt 480 ] && DHEIGHT=480

#build help GUI
gettext "<b>Helpful Tips</b>
You can add custom commands, parameters and options by typing the desired command in the chosen field and clicking the apply button. To load apps through the terminal, simply add 'rxvt -e ' before the command you wish to execute in the terminal.

Example: 'rxvt -e mp' will load the terminal based editor, called MP." > /tmp/box_help

export GUI='
<window title="'$(gettext 'Default Applications Chooser')'" default-height="'${DHEIGHT}'" image-name="'${DC_ICON}'">
<vbox space-expand="true" space-fill="true">
  <vbox space-expand="true" space-fill="true">
    <hbox shadow-type="0" scrollable="true" space-expand="true" space-fill="true">
      <frame>
        '$(< ${TMPDIR}/gui_boxes)'
        <vbox space-expand="true" space-fill="true">
          <text space-expand="true" space-fill="true"><label>""</label></text>
        </vbox>
      </frame>
    </hbox>
  </vbox>

  <hbox space-expand="false" space-fill="false">
    <button space-expand="false" space-fill="false">
      '"`/usr/lib/gtkdialog/xml_button-icon help`"'
      <label>"'$(gettext 'Help')'"</label>
      <action>/usr/lib/gtkdialog/box_help "'$(gettext 'Default apps')'" &</action>
    </button>
    <button space-expand="false" space-fill="false">
      '"`/usr/lib/gtkdialog/xml_button-icon info`"'
      <label>"'$(gettext 'List active apps')'"</label>
      <action>list_active</action>
    </button>
    <text width-request="200" space-expand="true" space-fill="true"><label>""</label></text>
    <button>
      '"`/usr/lib/gtkdialog/xml_button-icon cancel`"'
      <label>"'$(gettext 'Cancel')'"</label>
      <action type="exit">EXIT_NOW</action>
    </button>
    <button>
      '"`/usr/lib/gtkdialog/xml_button-icon apply`"'
      <label>"'$(gettext 'Apply')'"</label>
      <action>update_defaults &</action>
      <action type="exit">OK</action>
    </button>
    '"`/usr/lib/gtkdialog/xml_scalegrip`"'
  </hbox>
</vbox>
</window>'

# load the app
. /usr/lib/gtkdialog/xml_info gtk #build bg_pixmap for gtk-theme
[ "$XPID" ] && kill "$XPID" && XPID=""	#splash stop
gtkdialog -p GUI
unset GUI

exit 0
