#!/bin/bash

### mxfb-menu-generator: a tiny script to Create a (non dynamic) fluxbox menu using information on .desktop files, released by PPC, 7/10/2020, under GPLv3
### Modified by MX Linux Devs for use in MX-Fluxbox August 2021

### How to use this script:
### 1. Copy the script below and paste it into your text editor, saving it in your Home as MXFB_menu_generator.sh
### 2. Navigate to that file, right click it > Proprieties > "Permissions" tab > Check the last field, to allow this script to run as a program
### 3. Add the following entry to your menu to access "All Categories" anywhere you want
#######################################################################################
#[submenu] (All Apps)
#       [include] (~/.fluxbox/submenus/full_menu)
#       [separator]
#       [include] (~/.fluxbox/full_menu)
#   [end]
#######################################################################################
### 4.- Now click Menu > All apps > Update menu. Wait for some seconds while the menu is generated

#ensure subfolder menu exists
if [ ! -d "$HOME/.fluxbox/submenus" ]; then
	mkdir -p "$HOME/.fluxbox/submenus"
fi

#use a temp file for unsorted list
TEMPLIST="$(mktemp /tmp/mxfb-menu-generator.XXXXX)"

#preglobal file (can be removed)
PREGLOBAL="$HOME/.fluxbox/pre-global-menu.txt"

#target menu file
FILE="$HOME/.fluxbox/submenus/full_menu"

#exit if in chroot
if [ "$UID" = "0" ]; then
  echo "mxfb-menu-generator:  in a chroot, exiting..."
  exit 0
fi

#exit if menu generation toggled off
if [ "$1" = "auto" ]; then
    if [ -e "$HOME/.fluxbox/mxfb-menu-generator-disabled.chk" ]; then
    exit 0
    fi
fi

#check time since last build
time=0
now=$(date +"%s")
if [ -e "FILE" ]; then
   time=$(stat --format %Y "$FILE")
fi

if [ $(($now-$time)) -lt 5 ]; then
	exit 0
fi

Encoding=UTF-8
#
# use session locale
SESSION_LANG=$(sed -n '/^Language=/{s///; s/[.].*/.UTF-8/;p;q}' ~/.dmrc 2>/dev/null) ;
LANG=${SESSION_LANG:=$LANG}

# i18n - Internationalization
#export TEXTDOMAIN=mxfb-accessories
export TEXTDOMAIN=mx-desktop-menu-l10n
export TEXTDOMAINDIR="/usr/share/locale"

CATEGORIES="Accessories Development Games Graphics Internet Multimedia MX-Tools MX-Live MX-Maintenance MX-Setup MX-Software MX-Utilities MXFB-Tools Office System Settings"
ALLAPPS=$(gettext "All Applications")
[ "$ALLAPPS" = "All Applications"  ] && ALLAPPS="All Apps"

echo "Please wait, creating menu file - stored in $FILE ..."

#echo
#echo If you want to insert this 'All categories'  sub-menu into your MXFB menu:
#echo 'rootMenu > Settings > Configure > Menu'
#echo and insert, anywhere you want, this code:
#echo  ' [submenu] (All apps)'
#echo  '  [include] (~/.fluxbox/submenus/full_menu)'
#echo  '  [separator] '
#echo  '  [exec] (Update Menu) {mxfb-menu-generator} '
#echo  ' [end]'
#echo


#Get system language (to allow localization):
lang=${LANG%%_*}

#Loop through all .desktop files in the applications folder
#lang=fr

LIST="/usr/share/applications/*.desktop"

if [ -n "$(find /var/lib/flatpak/exports/share/applications/ -name *.desktop 2>/dev/null)" ]; then
	LIST="$LIST /var/lib/flatpak/exports/share/applications/*.desktop"
fi

if [ -n "$(find $HOME/.local/share/applications/ -name *.desktop 2>/dev/null)" ]; then
    LIST="$LIST $HOME/.local/share/applications/*.desktop"
fi

if [ -n "$(find $HOME/.local/share/flatpak/exports/share/applications/ -name *.desktop 2>/dev/null)" ]; then
    LIST="$LIST $HOME/.local/share/flatpak/exports/share/applications/*.desktop"
fi

if [ -n "$(find /usr/share/applications/antix/ -name *.desktop 2>/dev/null)" ]; then
    LIST="$LIST /usr/share/applications/antix/*.desktop"
fi

for file in $LIST
do

if [ -f "$file" ]; then
name1=$(grep -o -m 1 '^Name=.*' "$file")
 ### localized menu entries generator (slows the script down, but produces nearly perfect localized menus):
    name2="$name1"
	translated_name1=$(grep -o -m 1 "^Name\[$lang\]=.*" "$file")
	[ -z "$translated_name1" ] && note="No localized name found, using the original one" || name2="$translated_name1"
	#if the desktop file has the string "Desktop Action" simple use the original untranslated name, to avoid using a translation that's not the name of the app, but the action it does
	grep -q "Desktop Action" "$file" && name2="$name1"
    name1="$name2"
### end of localized menu entries generator

name=$(echo "$name1"|sed 's/.*\=//')
command1="$(grep -o -m 1 '^Exec=.*' "$file")"
command=$(echo "$command1" |sed -E 's/Exec\=//g')
name=$(echo "$name" |sed 's/[()]//g')
terminal=$(grep -o -m 1 'Terminal=.*' "$file")
  if [[ $terminal == *"true"* ]]; then
   command=$(echo x-terminal-emulator -e "$command")
  fi
 categories=$(grep -o -m 1 'Categories=.*' "$file")

 #process NoDisplay, OnlyShowIn, NotShowIn
 nodisplay=$(grep -o -m 1 'NoDisplay=.*' "$file")
 onlyshowin=$(grep -o -m 1 'OnlyShowIn=.*' "$file")
 notshowin=$(grep -o -m 1 'NotShowIn=.*' "$file")
 if [ -n "$onlyshowin" ]; then
	if [[ ! "$onlyshowin" =~ "fluxbox" ]]; then
		nodisplay=true
	fi
 fi
 if [ -n "$notshowin" ]; then
	if [[ "$notshowin" =~ "fluxbox" ]]; then
		nodisplay=true
	fi
 fi
 if [[ $nodisplay != *"rue"* ]]; then
    echo "[exec] ("$name ")" "{" $command "}" "$categories"
 fi
fi
done > "$TEMPLIST"

#process MX-Tools categories in temp list
sed -i "s/MX-Live/MX-Tools/" "$TEMPLIST"
sed -i "s/MX-Maintenance/MX-Tools/" "$TEMPLIST"
sed -i "s/MX-Setup/MX-Tools/" "$TEMPLIST"
sed -i "s/MX-Software/MX-Tools/" "$TEMPLIST"
sed -i "s/MX-Utilities/MX-Tools/" "$TEMPLIST"
sort "$TEMPLIST" > "$PREGLOBAL"
rm "$TEMPLIST"
#remove existing menu file, if it exists
if [ -e "$FILE" ]; then
	rm "$FILE"
fi

#fix for repeated synaptic menu entry- first instance does not run, so, delete it:
sed -i '/{ synaptic }/d' "$PREGLOBAL"

#### Now divide applications into categories:
#This array has all the available .desktop file categories we want to have on the menu (note: the "." is a quick and dirty workaround, so the script ignores entry nr 0):
array1=( . Utility Development Game Graphics Network AudioVideo MX-Tools MX-Live MX-Maintenance MX-Setup MX-Software MX-Utilities X-MXFB-Tools Office System Settings)
#This array corresponds to the previous one, but it's the "user friendly name" that shows on the menu- NOTE: this can be translated to any language!
array2=( . $CATEGORIES)

#Begin LOCALIZATION OF Category sub-menus to a language - pt, add equivalent section for other languages:
#    if [[ $lang == *"pt"* ]];
#    then
#		array2=( . Acessórios Desenvolvimento Jogos Graficos Internet Multimédia Escritório Sistema 'Definições globais')
#		echo A criar submenus em Português
#    fi
#End LOCALIZATION OF Category sub-menus

#Create the header of the file
echo "[begin] ($ALLAPPS)" >> "$FILE"
#Loop through the array- the last number below has to match the number of entries on $array1
for i in {1..16};
do
 #Create a submenu entry for the current item on $array2
 MAKESUBMENU=true
#Nested loop to check if the item on the current line of the "pre-global-menu.txt" file matches the current item on $array1, if it matches, add it to the "$FILE" file
 while read p; 	do
		if [[ "$p" =~ "${array1[$i]}" ]]
			then
				if [ "$MAKESUBMENU" = "true" ]; then
					echo "[submenu] ($(gettext "${array2[$i]}"))"  >> "$FILE"
					MAKESUBMENU=false
				fi
				echo "$p" >> "$FILE"
		fi
	done <"$PREGLOBAL" ;
	if [ "$MAKESUBMENU" = "false" ]; then
			echo '[end]' >> "$FILE" ;
	fi
	 MAKESUBMENU=true
done

#Process only entries that don't fit anywhere else:
sed -i '/Utility/d' "$PREGLOBAL"
sed -i '/Development/d' "$PREGLOBAL"
sed -i '/Game/d' "$PREGLOBAL"
sed -i '/Graphics/d' "$PREGLOBAL"
sed -i '/AudioVideo/d' "$PREGLOBAL"
sed -i '/Office/d' "$PREGLOBAL"
sed -i '/System/d' "$PREGLOBAL"
sed -i '/Settings/d' "$PREGLOBAL"
sed -i '/Network/d' "$PREGLOBAL"
sed -i '/MX-Tools/d' "$PREGLOBAL"
sed -i '/MX-Live/d' "$PREGLOBAL"
sed -i '/MX-Maintenance/d' "$PREGLOBAL"
sed -i '/MX-Setup/d' "$PREGLOBAL"
sed -i '/MX-Software/d' "$PREGLOBAL"
sed -i '/MX-Utilities/d' "$PREGLOBAL"
sed -i '/MXFB-Tools/d' "$PREGLOBAL"


#check if the file is not empty, create last submenu and populate it
if [ -n "$(grep exec "$PREGLOBAL")" ]; then
  echo "[submenu] ($(gettext "Other"))"  >> "$FILE"
  while read p; 	do
		echo "$p" >> "$FILE"
  done <"$PREGLOBAL" ;
echo '[end]' >> "$FILE"
fi

###Fix menu errors, so Libreoffice, etc, work without errors
delete="%U"
sed -e s/$delete//g -i "$FILE"
delete="%u"
sed -e s/$delete//g -i "$FILE"
delete="%F"
sed -e s/$delete//g -i "$FILE"
delete="%f"
sed -e s/$delete//g -i "$FILE"

##add [end] to the end, to match the very first [begin]
echo "[end]" >> "$FILE"

#modify menu to remove empty mx-tools entries
sed -i '0,/\[submenu\] (MX-Live)/{//!b; :a; n; /\[end\]/d; ba;}' "$FILE"
sed -i "/\[submenu\] (MX-Live)/d" "$FILE"
sed -i '0,/\[submenu\] (MX-Maintenance)/{//!b; :a; n; /\[end\]/d; ba;}' "$FILE"
sed -i "/\[submenu\] (MX-Maintenance)/d" "$FILE"
sed -i '0,/\[submenu\] (MX-Setup)/{//!b; :a; n; /\[end\]/d; ba;}' "$FILE"
sed -i "/\[submenu\] (MX-Setup)/d" "$FILE"
sed -i '0,/\[submenu\] (MX-Software)/{//!b; :a; n; /\[end\]/d; ba;}' "$FILE"
sed -i "/\[submenu\] (MX-Software)/d" "$FILE"
sed -i '0,/\[submenu\] (MX-Utilities)/{//!b; :a; n; /\[end\]/d; ba;}' "$FILE"
sed -i "/\[submenu\] (MX-Utilities)/d" "$FILE"

echo Menu file created and ready to be used

#cleanup preglobal
#rm "$PREGLOBAL"

#if fluxbox running, reload menu
test=$(ps -aux)
if [[ "$test" == *"startfluxbox" ]]; then
	pkill -SIGUSR1 fluxbox
  killall -SIGUSR1 conky 2>/dev/null
fi
exit 0
