#!/bin/bash

Info () {
title="Info"
author="Peter Starfinger"
mail="E-Mail: info@die-starfingers.de"
year="2020 / 2024"
app="$(basename $0)"
msgid="The Starbuntu application
<i>\$app</i>
was written by"
info="$(gettext "$msgid" | (export PATH `envsubst --variables "$msgid"`; envsubst "$msgid"))"

yad --center --fixed --title="$title" --window-icon="info" --image="info" --borders=20 --text="$info"$'\n'$'\n'"$author"$'\n'"$mail"$'\n'$'\n'"$year"$'\n' --text-align=center --selectable-labels --button="OK" &
wunwa "$title" > /dev/null; xdotool key Home key Down
}

tip () {
adv=$"instead of"
alarm=$"Attention while inserting special characters:"
title=$"Special Characters"
conj=$"or"

help1=$'\t'"    $adv \'&#92;\'&#9;&#9;\'&#92;&#92;' $conj \'&amp;#92;\'"
# help2=$'\t'"    $adv \'&amp; \'&#9;\'&amp;amp; \' $conj \'&amp;#38; \'"
help3=$'\t'"    $adv \'&#60;\'&#9;\'&amp;lt;\' $conj \'&amp;#60;\'"
help4=$'\t'"    $adv \'&#62;\'&#9;\'&amp;gt;\' $conj \'&amp;#62;\'"
help5=$'\t'"    $adv nbsp&#9;\' \' $conj \'&amp;#160;\'"
help6=$'\t'"    $adv Tab&#9;\'&#92;t\' $conj \'&amp;#9;\'"
help7=$'\t'"    $adv \'↵\'&#9;\'&#92;n\' $conj \'&amp;#10;\'"
#help="    $alarm    &#10;&#10;$help1&#10;$help2&#10;$help3&#10;$help4&#10;$help5&#10;$help6&#10;$help7&#10;"
help="    $alarm    &#10;&#10;$help1&#10;$help3&#10;$help4&#10;$help5&#10;$help6&#10;$help7&#10;"
yad --center --fixed --title="$title" --window-icon="/usr/share/icons/gnome/48x48/status/dialog-warning.png" --image="/usr/share/icons/gnome/48x48/status/dialog-warning.png" --image-on-top --borders=20 --text="$help" --selectable-labels --button="OK" &
wunwa "$title" > /dev/null; xdotool key Home key Down
}

param="$1"
[ "$param" = "info" ] && Info && exit 0
[ "$param" = "tip" ] && tip && exit 0

keyword="$@"
user=$(whoami)
while for did in $(xinput --list --id-only); do xinput query-state $did 2>/dev/null | grep -s down; done | grep -s -Eq .; do sleep 0.1; done

if [ "$user" != "root" ]; then
    if [ ! -e "$keyword" ] || [ "$(stat "$keyword" | tail -1 | cut -d\  -f2-3 | cut -d: -f1-2)" != "$(date +%Y-%m-%d\ %H:%M)" ]; then
	wunwa "Event Tester" && wmctrl -r 'Event Tester' -N "Root: $(gettext "Super_L key")" &
	kp=$(timeout 2s xev -geometry 260x50 | grep -s -A2 --line-buffered '^KeyRelease' | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p')
	if [[ "${kp}" =~ "Super_L" ]]; then
	    cd /usr/share/applications
	    gsu $0 "$keyword" & exit 0
	fi
    fi
fi

leave=false
IFS=$'\n'

text1=$"Application keyword:&#10;(If empty, file select box)"
text2=$"Which file do you want to edit?"
text3=$"File: "
text4=$"File with this keyword not found!"
text5=$"<b>             Path and name of the launcher:</b>"
text6=$"Input of special characters"
title1=$"Desktop File Keyword"
title2=$"Desktop File List"
title3=$"Change Desktop File Entries"
title4=$"Warning"
title5=$"New Launcher"
button0=$"Cancel"
button1=$"Hints"
button2=$"Help"
field1=$"Comment"
field2=$"Command&#58; "
field3=$"Icon: "
field4=$"Categories+: "
field5="→ AppMenu&#58; "
field6=$"Other&#58; "

if [ ! -f "$keyword" ]; then

  if [ -z "$keyword" ]; then
    keyword=`yad --center --fixed --title="$title1" --image="edit-desktop" --image-on-top --window-icon="$HOME/.icons/edit-desktop.png" --borders=10 --text="<b>$text1</b>" --entry --button=$button0:1 --button="OK":0`
    knopf=$?
  fi

  if [ -f "$keyword" ]; then
    $0 "$keyword" & exit 0
  fi

  if [ -n "$keyword" ]; then
    glob_apps=($(find /usr/share/applications -type f -name "*.desktop" | sort))
    if [ "$USER" != "root" ]; then
	loc_apps=($(find $HOME/.local/share/applications -type f -name "*.desktop" | sort))
	for f in ${loc_apps[@]}; do glob_apps=(${glob_apps[@]/\/usr\/share\/applications\/$(basename "$f")}); done
	desk_apps=($(find $XDG_DESKTOP_DIR -type f -name "*.desktop" | sort))
	auto_apps=($(find $HOME/.config/autostart -type f -name "*.desktop" | sort))
    fi
    apps=(${glob_apps[@]} ${loc_apps[@]} ${desk_apps[@]} ${auto_apps[@]})

    desk_list=($(echo "${apps[*]}" | grep "$keyword"))
    desk_list+=($(grep -s -ilE "$keyword" ${apps[@]}))
    desk_list=($(echo "${desk_list[*]}" | sort -u))

    if [ ${#desk_list[@]} -gt 0 ]; then
	n_desk=${#desk_list[@]}
	v_dim=$(xdpyinfo | grep -s dimensions)
	v_dim=${v_dim#*x}
	v_dim=${v_dim%% *}
	h=$((n_desk*24+85))
	[ $h -gt $((v_dim-110)) ] && h=$((v_dim-110))
	desk_file=`yad --center --title=$title2 --height=$h --width=700 --window-icon="$HOME/.icons/edit-desktop.png" --borders=10 --text="<b>$text2</b>" --list --separator="¦" --no-headers --column="Desktop Files" ${desk_list[@]} --button=$button0:1 --button="OK":0`
	if [ $? -eq 0 ]; then desk_file="${desk_file::-1}"; fi
    else
	yad --center --fixed --title="$title4" --borders=50 --window-icon="$HOME/.icons/edit-desktop.png" --image=dialog-warning --text=$'\n'"<b>    $text4</b>" --button="OK"
    fi
  elif [ $knopf -eq 0 ]; then
    desk_file="$(yad --title="$title5" --center --window-icon=/usr/share/icons/HighContrast/48x48/status/airplane-mode.png --text="$text5" --file --filename=$HOME/.local/share/applications/ --mime-filter=application/x-desktop --save)"
    [ $? -gt 0 ] && exit 0
    [ "${desk_file: -8}" != ".desktop" ] && desk_file="$desk_file.desktop"
  fi
else
  [ "$(xdg-mime query filetype "$keyword")" = "application/x-desktop" ] && desk_file="$keyword"
fi

base_file="$(basename "$desk_file")"
d_f=${desk_file%/*}
d_f=${d_f##*/}
if [ "$d_f" = "applications" ]; then
    [ "$USER" != "root" ] && destination="$HOME/.local/share/applications/$base_file" || destination="/usr/share/applications/$base_file"
else
    destination="$desk_file"
fi

until $leave; do

  if [ -n "$desk_file" ]; then

    cont=($(cat "$desk_file"))
    n_act=$(grep -n -s "\[Desktop Action" <<< "${cont[*]}" | cut -d: -f1)
    if [[ $n_act -gt 1 ]]; then
	n_noact=$((n_act-2))
	cont=($(echo "${cont[*]::$n_noact}"))
	cont=($(sed '/Actions=/d' <<< "${cont[*]}"))
    fi
    n=${#cont[@]}; icon_loc_deleted=false
    for v in name n_name name_loc n_name_loc comment n_comment comment_loc n_comment_loc command n_command icon n_icon categories n_categories; do unset $v; done
    for ((k=0; k<n; k++)); do
	cont[$k]="$(echo ${cont[$k]} | sed 's/\&$/\&amp;/g; s/ \&\& / \&amp;\&amp; /g; s/\& /\&amp; /g; s/</\&lt;/g; s/>/\&gt;/g')"
	if [[ ${cont[$k]} =~ ^"Name=" ]] && [ -z "$name" ]; then n_name=$k; name="${cont[$k]#*=}"; fi
	if [[ ${cont[$k]} =~ ^"Name[$LANGUAGE" ]] && [ -z "$name_loc" ]; then n_name_loc=$k; name_loc="${cont[$k]#*=}"; fi
	if [[ ${cont[$k]} =~ "Comment=" ]] && [ -z "$comment" ]; then n_comment=$k; comment="${cont[$k]#*=}"; fi
	if [[ ${cont[$k]} =~ "Comment[$LANGUAGE" ]] && [ -z "$comment_loc" ]; then n_comment_loc=$k; comment_loc="${cont[$k]#*=}"; fi
	if [[ ${cont[$k]} =~ ^"Exec=" ]] && [ -z "$command" ]; then n_command=$k; command="${cont[$k]#*=}"; fi
	if [[ ${cont[$k]} =~ "Icon=" ]] && [ -z "$icon" ]; then n_icon=$k; icon="${cont[$k]#*=}"; fi
	if [[ ${cont[$k]} =~ "Icon[$LANGUAGE" ]]; then cont[$k]=""; icon_loc_deleted=true; fi
	if [[ ${cont[$k]} =~ "Categories=" ]] && [ -z "$categories" ]; then n_categories=$k; categories="${cont[$k]#*=};"; categories=${categories//;;/;}; fi
	if [[ ${cont[$k]} =~ "NoDisplay=" ]]; then n_noshow=$k; noshow="${cont[$k]#*=}"; fi
    done
    [ -z "$n_name" ] && n_name=$n && ((n++))
    [ -z "$n_name_loc" ] && n_name_loc=$n && ((n++))
    [ -z "$n_comment" ] && n_comment=$n && ((n++))
    [ -z "$n_comment_loc" ] && n_comment_loc=$n && ((n++))
    [ -z "$n_command" ] && n_command=$n && ((n++))
    [ -z "$n_icon" ] && n_icon=$n && ((n++))
    [ -z "$n_categories" ] && n_categories=$n && ((n++))
    [ -z "$n_noshow" ] && n_noshow=$n && noshow=false

    IFS=\;
    if [ -n "$categories" ]; then
	ctg=(${categories::-1})
    else
	ctg=(); ctg_loc=""
    fi
    $noshow && alt=$"Yes""!^"$"No" || alt=$"Yes""!"$"No"
    [ "$LANGUAGE" != "en" ] && brackets=".$LANGUAGE" || brackets="="
    for c in ${ctg[@]}; do
	c_loc=$(grep -s "Name$brackets" $HOME/.local/share/desktop-directories/$c.directory)
	[ -z "$c_loc" ] && c_loc=$(grep -s "Name" $HOME/.local/share/desktop-directories/$c.directory)
	[ -z "$c_loc" ] && c_loc=$(grep -s "Name$brackets" /usr/share/desktop-directories/$c.directory)
	[ -z "$c_loc" ] && c_loc=$(grep -s "Name" /usr/share/desktop-directories/$c.directory)
	c_loc="${c_loc#*=}"
	[ -n "$c_loc" ] && ctg_loc="$ctg_loc$c_loc;"
    done
    IFS=$'\n'; ctgs=()
    apps=($(cat $HOME/.config/menus/Apps.lst))
    for a in ${apps[*]}; do
	b="$a"; pre=""
	while [ -n "$b" ]; do
	    IFS=$'‖'
	    c=($b)
	    c_loc=$(grep -s "Name$brackets" $HOME/.local/share/desktop-directories/${c[1]}.directory)
	    [ -z "$c_loc" ] && c_loc=$(grep -s "Name" $HOME/.local/share/desktop-directories/${c[1]}.directory)
	    [ -z "$c_loc" ] && c_loc=$(grep -s "Name$brackets" /usr/share/desktop-directories/${c[1]}.directory)
	    [ -z "$c_loc" ] && c_loc=$(grep -s "Name" /usr/share/desktop-directories/${c[1]}.directory)
	    c_loc="${c_loc#*=}"
	    ctgs=(${ctgs[@]} "$pre$c_loc")
	    IFS=$'\n'
	    b=$(cat $HOME/.config/menus/${c[1]}.lst | grep -s "▶ ")
	    pre="$pre    "
	done
    done
    clear=$"Clear"
    IFS=$'!'
    ctgs="$(echo "${ctgs[*]}")!$clear"
    ctgs="${ctgs//▶ /}"
    if [ "$LANGUAGE" != "en" ]; then
	field_name1="--field=Name[en]&#58; "
	field_name2="--field=Name[$LANGUAGE]&#58; "
	[ -z "$name_loc" ] && content_name2=\"\" || content_name2="$name_loc"
	field_comment1="--field=$field1[en]&#58; "
	field_comment2="--field=$field1[$LANGUAGE]&#58; "
	[ -z "$comment_loc" ] && content_comment2=\"\" || content_comment2="$comment_loc"
    else
	field_name1="--field=Name&#58; "
	field_name2=""
	content_name2=""
	field_comment1="--field=$field1&#58; "
	field_comment2=""
	content_comment2=""
    fi
    lang_dir=$"C"
    pwd="$(pwd)"; cd $HOME/.icons
    entries=`yad --center --title="$title3" --width=600 --height=200 --window-icon="$HOME/.icons/edit-desktop.png" --borders=10 --text="<b>$text3$base_file</b>" --text-align=center --form --separator="¦" $field_name1 "$name" $field_name2 $content_name2 $field_comment1 "$comment" $field_comment2 $content_comment2 --field="$field2" "$command" --field="$field3":SFL "$icon" --file-filter $"Graphic Files "" | *.svg *.png *.SVG *.PNG" --add-preview --field="$field4":CBE "$ctg_loc!$ctgs" --field="$field5":CB "$alt" --field="$field6" --button="$button0":1 --button="$button2":"yelp /usr/share/help/$lang_dir/Starbuntu/starbuntu-apps-details.page#edit-app-launcher" --button="$button1!!$text6":"$0 tip"  --button="Info":"$0 info" --button="OK":0`
    exitstatus=$?

    if [ $exitstatus -eq 0 ]; then
	cd "$pwd"
	name_new="${entries%%¦*}"; entries="${entries#*¦}"
	if [[ $LANGUAGE != "en" ]]; then name_loc_new="${entries%%¦*}"; entries="${entries#*¦}"; fi
	comment_new="${entries%%¦*}"; entries="${entries#*¦}"
	if [[ $LANGUAGE != "en" ]]; then comment_loc_new="${entries%%¦*}"; entries="${entries#*¦}"; fi
	command_new="${entries%%¦*}"; entries="${entries#*¦}"
	icon_new="${entries%%¦*}"; entries="${entries#*¦}"
	categories_new=$(echo ${entries%%¦*} | sed 's/^ *//'); entries="${entries#*¦}"
	noshow_new="${entries%%¦*}"; entries="${entries#*¦}"
	other="${entries%%¦*}"
	leave=true

	[ "$noshow_new" = $"No" ] && noshow_new=true || noshow_new=false
	
	if [[ ${categories_new: -1} = ';' ]]; then categories_new=${categories_new::-1}; fi
	IFS=$';'
	ctg=($categories_new)
	if [ ${#ctg[@]} -gt 1 ]; then chain=true; else chain=false; fi
	
	ctg_en=""
	for c in ${ctg[@]}; do
	    if [[ "$c" =~ $"Clear" ]]; then
		[ $(whoami) != "root" ] && [ "$(dirname $desk_file)" = "/usr/share/applications" ] && cp "$desk_file" "$HOME/.local/share/applications/$base_file" && desk_file="$HOME/.local/share/applications/$base_file"
		sed -i '/Categories=/d' "$desk_file"
		$0 "$desk_file" &		
		exit 0
	    else
		f_c=$(grep -s -lE "=$c$" $HOME/.local/share/desktop-directories/*)
		[ -z "$f_c" ] && f_c=$(grep -s -lE "=$c$" /usr/share/desktop-directories/*)
		c_en=$(basename "$f_c")
		c_en="${c_en%.*}"
		ctg_en="$ctg_en$c_en;"
	    fi
	done

	IFS=$'\n'
	if [[ "$name_new$name_loc_new$comment_new$comment_loc_new$command_new$icon_new$ctg_en$noshow_new" != "$name$name_loc$comment$comment_loc$command$icon$categories$noshow" ]] || [ -n "$other" ] || $icon_loc_deleted || ([ "$USER" = "root" ] && [ -f "$HOME/.local/share/applications/$base_file" ]); then
	    [ -n "$name_new" ] && cont[$n_name]="Name=$name_new" || cont[$n_name]=""
	    [ -n "$name_loc_new" ] && cont[$n_name_loc]="Name[$LANGUAGE]=$name_loc_new" || cont[$n_name_loc]=""
	    [ -n "$comment_new" ] && cont[$n_comment]="Comment=$comment_new" || cont[$n_comment]=""
	    [ -n "$comment_loc_new" ] && cont[$n_comment_loc]="Comment[$LANGUAGE]=$comment_loc_new" || cont[$n_comment_loc]=""
	    [ -n "$command_new" ] && cont[$n_command]="Exec=$command_new" || cont[$n_command]=""
	    [ -n "$icon_new" ] && cont[$n_icon]="Icon=$icon_new" || cont[$n_icon]=""
	    if [ -n "$categories_new" ]; then
	        if $chain; then
		    cont[$n_categories]="Categories=$ctg_en"
		elif [ -z "$(grep -E "^Categories.*[=;]${ctg_en/;}[;]?" $desk_file)" ]; then
		    cont[$n_categories]="Categories=$categories$ctg_en"
		fi
	    else
		cont[$n_categories]=""
	    fi
	    $noshow_new && cont[$n_noshow]="NoDisplay=true" || cont[$n_noshow]="NoDisplay=\"\""
	    if [ -n "$other" ]; then
		var_other="${other%%=*}"; value_other="${other#*=}"
		k=$(grep -n -s ^"$var_other=" <<< "${cont[*]}" | cut -d: -f1); ((k--))
		if [ $k -gt 0 ]; then
		    [ -n "$value_other" ] && cont[$k]="$other" || cont[$k]=""
		fi
		[ $k -eq -1 ] && [ -n "$value_other" ] && cont[$n]="$other"
	    fi
	    cont=(${cont[@]})

	    if [ -f "$destination" ]; then
		rm "$destination"
	    fi
	    [[ ! "${cont[@]}" =~ '#!/usr/bin/env exec-desktop' ]] && echo '#!/usr/bin/env exec-desktop' > "$destination"
	    [[ ! "${cont[@]}" =~ '[Desktop Entry]' ]] && echo "[Desktop Entry]" >> "$destination"
	    [[ ! "${cont[@]}" =~ 'Type=Application' ]] && echo "Type=Application" >> "$destination"
	    for ((k=0; k<${#cont[@]}; k++)); do
		cont[$k]="$(echo "${cont[$k]}" | sed 's/\&amp;/\&/g; s/\&#38;/\&/g; s/\&lt;/</g; s/\&#60;/</g; s/\&gt;/>/g; s/\&#62;/>/g')"
		[[ ! "${cont[$k]}" =~ ^[^=]*=\"\" ]] && echo "${cont[$k]}" >> "$destination"
	    done
	    chmod a+x "$destination"
	    if [ "$USER" = "root" ]; then
		for user in $(ls /home); do
		    [ -f "/home/$user/.local/share/applications/$(basename "$destination")" ] && mv "/home/$user/.local/share/applications/$(basename "$destination")" "/home/$user/.local/share/applications/$(basename "$destination").bak"
		done
	    fi
	    [[ "$destination" =~ "applications" ]] && appmenu-refresh && obamenu-refresh
	    leave=true
	fi
    else
	leave=true
    fi
  else
    leave=true
  fi

done
