#!/bin/sh

set -u

KATEG_FILES="`dirname $0`/kategorien-norm.lst `dirname $0`/kategorien-debian.lst `dirname $0`/kategorien-verwandte.lst"
#READ_DESKTOP_DIR="/var/lib/menu-xdg/applications/menu-xdg"
READ_DESKTOP_DIR="/usr/share/applications"
WRITE_DESKTOP_DIR="`dirname $0`/desktop-files"
#DATA_FILE="`dirname $0`/database.dat"
DATA_FILE="/tmp/database.dat"
EINTRAEGE_PRO_SEITE=10

exec -- 2>/tmp/output
#set -x

############# Menue-Verwaltung ################

filter_empty()
{
	sed -r '/^[[:space:]]*$/d ; s/^[[:space:]]*// ; s/[[:space:]]*$//'
}


hole_app_liste()
{
	find "$READ_DESKTOP_DIR" -type f -name \*.desktop | while read a
		do	basename "${a%.desktop}"
	  done | filter_empty | sort | nl 
}


# zuerst in der Datenbank nachsehen - ansonsten aus dem desktop-Verzeichnis holen
# Parameter: app-name
lade_app_kategs()
{
	DDATEI=`find $READ_DESKTOP_DIR -type f -name $1.desktop`
	if [ -e "$DATA_FILE" ] && grep -q "^$1=" "$DATA_FILE"
		then	grep "^$1=" "$DATA_FILE" | cut -d "=" -f 2 | tr " " "\n"
		else	[ -e "$DDATEI" ] && grep "^Categories=" "$DDATEI" | cut -d "=" -f 2 | tr ";" "\n"
	  fi | filter_empty | sort | uniq
}


hole_kateg_liste()
{
	cat $KATEG_FILES | cut -f 1 | filter_empty | sort | uniq
}


# liefert eine Liste von Kategorien zurueck, die entweder auf die angegebene verweisen oder
# solche, auf die sie selbst verweist
# nicht-standard-konforme Kategorien (X-???-???) werden herausgefiltert
# Parameter: die zu bearbeitende Kategorie
hole_verwandte_kategs()
{
	(
		[ -z "$1" ] && return
		# erstmal die verweisenden:
		cat $KATEG_FILES | sed 's/$/\t/' | grep "[[:space:]]$1[[:space:]]" | cut -f 1
		# dann die, auf die verwiesen wird:
		cat $KATEG_FILES | grep "^$1[[:space:]]" | cut -f 2-30 | tr "\t" "\n" | tr " " "\n"
	) | grep -v "^X-" | filter_empty | sort | uniq
}

# liefert alle Kategorien zurueck, die mit den bisherigen Kategorien der Anwendung verwandt sind,
# ihr jedoch noch nicht zugeordnet wurden
hole_verwandte_kategs_der_app()
{
	#local FILTER=`lade_app_kategs "$1" | sed 's#^#/# ; s#$#/d;#' | tr "\n" " "`
	local FILTER=`lade_app_kategs "$1" | sed 's#^.*$#/&/d; #' | tr "\n" " "`
	lade_app_kategs "$1" | while read a; do hole_verwandte_kategs "$a"; done | sed "$FILTER" | filter_empty | sort | uniq
}


hole_anzahl_apps()
{
	echo "$ALLE_APPS" | wc -l
}


# entfernt alle Apps, die nicht in der angegebenen Kategorie sind
# Parameter: 	- die Kategorie 
#		- die Anwendungen
filter_apps_nach_kateg()
{
	local KATEG="$1"
	shift
	echo -e "$ALLE_APPS" | while read num name
		do	lade_app_kategs "$name" | grep -q "$KATEG" && echo -e "$num\t$name"
	  done
}



speichere_formdaten()
{
	local POST_DATA=`cat - | tr "&" "\n"`
	local EINTRAEGE=`echo "$POST_DATA" | grep "^text_kategs_" | cut -d = -f 1 | sed 's/^text_kategs_//'`
	local NEUE_KATEGS
	local APP_NAME
	for a in $EINTRAEGE
		do	NEUE_KATEGS=`echo "$POST_DATA" | grep "^text_kategs_$a=" | cut -d '=' -f 2 | tr '+' ' ' | tr ' ' '\n'`
			NEUE_KATEGS="$NEUE_KATEGS\n`echo -e \"$POST_DATA\" | grep "^liste_kateg[123]_$a=" | cut -d '=' -f 2`"
			NEUE_KATEGS=`echo -e "$NEUE_KATEGS" | sort | uniq | tr '\n' ' '`
			APP_NAME=`app_num2name $a`
			NEUE_ZEILE=`echo -e "$APP_NAME=$NEUE_KATEGS" | sed -r 's/[[:space:]]+/ /g; s/=[[:space:]]/=/'`
	  		[ ! -e "$DATA_FILE" ] && touch "$DATA_FILE"
			sed -i "s/^$APP_NAME=.*/$NEUE_ZEILE/" "$DATA_FILE"
			grep -q "^$APP_NAME=" "$DATA_FILE" || echo -e "$NEUE_ZEILE" >> "$DATA_FILE"
	  done
}


app_num2name()
{
	echo "$ALLE_APPS" | grep "^[[:space:]]*$1[[:space:]]" | cut -f 2
}


app_name2num()
{
	echo "$ALLE_APPS" | grep "[[:space:]]$1$" | cut -f 1
}

################# debug & test #################
debug_zeige_alle_apps()
{
	for a in `hole_app_liste`
		do	echo -en "$a\t-\t"
			lade_app_kategs "$a" | tr "\n" " "
			echo
	  done
}


############## html-encoding ################
html_header()
{
	echo "Content-type: text/html"
	echo
	echo "<HTML>"
	echo "<HEAD>"
	echo "	<TITLE>Debian-Menue-Designer</TITLE>"
	echo '	<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">'
	echo "</HEAD>"
	echo "<BODY>"
}


html_footer()
{
	echo "</BODY>"
	echo "</HTML>"
}


html_nav()
{
	echo '<DIV ALIGN="CENTER"><TABLE BORDER="0" CELLPADDING="20"><TR>'

	echo "<FORM ACTION=\"`basename $0`\" METHOD=\"GET\">"
	
	echo '	<TD>Kategorie: <BR><SELECT NAME="kateg_filter">'
	echo '		<OPTION VALUE="">alle</OPTION>'
	for a in $ALLE_KATEGS
		do 	if [ "$a" = "$KATEG_FILTER" ]
				then	echo "		<OPTION SELECTED>$a</OPTION>"
				else	echo "		<OPTION>$a</OPTION>"
			  fi
	  done
	echo '	</SELECT></TD>'
	
	echo '	<TD>Eintr&auml;ge je Seite:<BR><SELECT NAME="eintraege_pro_seite">'
	for a in 10 25 50 100 500 1000
		do 	if [ "$a" = "$EINTRAEGE_PRO_SEITE" ]
				then	echo "		<OPTION SELECTED>$a</OPTION>"
				else	echo "		<OPTION>$a</OPTION>"
			  fi
	  done
	echo '		</SELECT>'
	echo '	</TD>'

	echo '	<TD>Beginne bei Eintrag:<BR><SELECT NAME="app_start_nr">'
	for a in 1 10 25 100 500
		do 	if [ "$a" = "$APP_START_NR" ]
				then	echo "		<OPTION SELECTED>$a</OPTION>"
				else	echo "		<OPTION>$a</OPTION>"
			  fi
	  done
	echo '		</SELECT>'
	echo '	</TD>'

	echo '	<TD><INPUT TYPE="SUBMIT" VALUE="Anzeigen"></TD>'
	echo '</FORM></TR></TABLE></DIV>'
	echo '<HR>'
}

# zwei Paramater:
# (1) _all_ ODER Name der Anwendung, zu der nur die noch nicht verwendeten Verwandten eingetragen werden sollen
# (2) der Name der HTML-Auswahlliste (entspricht dem spaeteren Variablennamen des Inhalts)
html_kateg_liste()
{
	echo "<SELECT NAME=\"$2\" SIZE=\"1\">"
	echo "	<OPTION></OPTION>"
	if [ $1 = "_all_" ]
		then	echo -e "$ALLE_KATEGS"
		else	hole_verwandte_kategs_der_app "$1"
	  fi | while read a; do echo "	<OPTION>$a</OPTION>"; done
	echo "</SELECT>"
	echo
}


# Parameter: app-nummer
html_apps_config()
{
	local APP_NAME=`app_num2name $1`
	echo "	<TR>"
	echo "		<TD>$APP_NAME</TD>"
	echo "		<TD><INPUT NAME=\"text_kategs_$1\" SIZE=\"50\" VALUE=\"`lade_app_kategs $APP_NAME | tr '\n' ' '`\"></TD>"
	echo "		<TD>`html_kateg_liste $APP_NAME liste_kateg1_$1`</TD>"
	echo "		<TD>`html_kateg_liste $APP_NAME liste_kateg2_$1`</TD>"
	echo "		<TD>`html_kateg_liste _all_ liste_kateg3_$1`</TD>"
	echo "	</TR>"
}


# als Parameter ist die Nummer der ersten Anwendung der Liste erforderlich
html_edit_liste()
{
	echo -n '<FORM NAME="Kategorien-Zuordnung" METHOD="POST"'
	echo " ACTION=\"`basename $0`?action=speichern&app_start_nr=$APP_START_NR&eintraege_pro_seite=$EINTRAEGE_PRO_SEITE&kateg_filter=$KATEG_FILTER\">"
	echo "<TABLE BORDER=\"0\">"
	echo "	<TR>"
	echo "		<TH>Programm</TH>"
	echo "		<TH>bisherige Kategorien</TH>"
	echo "		<TH>verwandte Kategorie I</TH>"
	echo "		<TH>verwandte Kategorie II</TH>"
	echo "		<TH>weitere Kategorie</TH>"
	echo "	</TR>"
	
	local uebrig=$EINTRAEGE_PRO_SEITE
	echo -e "$ALLE_APPS\n" | sed -n "$((APP_START_NR)),$((APP_START_NR+EINTRAEGE_PRO_SEITE-1))p" | while read num name
		do	[ -n "$num" ] && html_apps_config $num
			uebrig=$((uebrig-1))
	  done

	echo "</TABLE>"
	echo '<DIV ALIGN="CENTER"><INPUT TYPE="SUBMIT" VALUE=" Speichern "></DIV>'
	echo "</FORM>"

	if [ $APP_START_NR -gt 1 -o $((APP_START_NR+EINTRAEGE_PRO_SEITE-1)) -lt `hole_anzahl_apps` ]
		then	echo '<P><BR><DIV ALIGN="CENTER">'
		if [ $APP_START_NR -gt 1 ]
			then	local PREV_START_NR=$((APP_START_NR-EINTRAEGE_PRO_SEITE))
				[ "$PREV_START_NR" -lt 1 ] && PREV_START_NR=1
				echo "<A HREF=\"`basename $0`?app_start_nr=$PREV_START_NR&eintraege_pro_seite=$EINTRAEGE_PRO_SEITE&kateg_filter=$KATEG_FILTER\">vorherige Seite</A>"
		  fi
		if [ $((APP_START_NR+EINTRAEGE_PRO_SEITE-1)) -lt `hole_anzahl_apps` ]
			then	local NEXT_START_NR=$((APP_START_NR+EINTRAEGE_PRO_SEITE))
				echo "<A HREF=\"`basename $0`?app_start_nr=$NEXT_START_NR&eintraege_pro_seite=$EINTRAEGE_PRO_SEITE&kateg_filter=$KATEG_FILTER\">n&auml;chste Seite</A>"
		  fi
		echo "</DIV></P>"
	  fi
}

############# cgi-Zeug #############

# liest einen cgi-Parameter ein und liefert notfalls einen angegebenen Default-Wert zurueck
# Parameter: der Name des Parameters und der default-Wert
hole_parameter()
{
	local ERG=$2
	if set | grep -q "^QUERY_STRING"
		then	ERG=`echo "$QUERY_STRING" | tr "&" "\n" | grep "^$1" | cut -d "=" -f 2`
		else	ERG="$2"
	  fi
	[ -z "$ERG" ] && ERG="$2"
	echo -e "$ERG"
}

############# los geht es! ############

ALLE_KATEGS=`hole_kateg_liste`
ALLE_APPS=`hole_app_liste`

KATEG_FILTER=`hole_parameter kateg_filter ""`
[ -n "$KATEG_FILTER" ] && ALLE_APPS=`filter_apps_nach_kateg "$KATEG_FILTER"`

APP_START_NR=`hole_parameter app_start_nr 1`
EINTRAEGE_PRO_SEITE=`hole_parameter eintraege_pro_seite $EINTRAEGE_PRO_SEITE`

html_header
html_nav

ACTION=`hole_parameter action formular`

case "$ACTION" in
	speichern|formular)
		[ "$ACTION" = "speichern" ] && speichere_formdaten

		html_edit_liste
		;;
	*)
		echo '<H1><DIV ALIGN="CENTER">Fehlerhafte Aktion ('
		echo "$ACTION"
		echo ') angefordert!</DIV></H1>'
		;;
  esac

html_footer