#!/bin/bash

. /usr/local/lib/desktop-session/lib-desktop-session.sh
. /usr/local/lib/desktop-session/desktop-session-file-locations.sh

      ICON_TITLE="Icon Manager"
        WM_TITLE="Window Manager"
 WM_SELECT_TITLE="Window Manager"
WM_DEFAULT_TITLE="Set Default WM"

       ROOT_FILE="$share_dir/wm-menus/%s-wm-menu"
       USER_FILE="$HOME/.%s/wm-menu"

   ICON_PROG="$desktop_session_restart"
 SELECT_PROG="$desktop_session_restart"
SET_DEF_PROG="desktop-session-set-default"
 LOGOUT_PROG="$desktop_session_logout"

   ICON_LIST="Cycle-IM Rox SpaceFM None-IM"
       ISTEP=2
         WMs="fluxbox icewm jwm RAW"

   icon_managers="Rox Space min"
     min_enabled=fluxbox,icewm,jwm
     Rox_enabled=fluxbox,icewm,jwm
   Space_enabled=fluxbox,icewm,jwm

ME=${0##*/}

usage() {
    local ret=${1:-0}
    cat <<Usage
Usage: $ME: [options] [window-managers]

Create menus for several window managers: $WMs
that allow users to change to the window manager without
exiting X using desktop-session.

The list of window managers we can change to can be
much larger that the list of window managers we make
menus for.

Normally we only make menus if the are older than the
$xs_dir directory.  Use the --force option to force
their creation.

Options:

    -d --debug   Print contents of the files to the screen
                 Don't write any files
    -f --force   Force creation of the menus even if
                 they are not out of date
    -h --help    Show this help
    -v --verbose Print last modified times

Usage

    exit $ret
}

main() {

    while [ $# -gt 0 -a -z "${1##-*}" ]; do
        arg=${1#-}; shift

        case $arg in
            -debug|d)  DEBUG=true   ;;
            -force|f)  FORCE=true   ;;
             -help|h)  usage        ;;
          -verbose|v)  VERBOSE=true ;;

                   *)  error "Unkown argument: -$arg" ;;
        esac
    done

    check_user
    [ "$*" ] && WMs="$*"

    XS_MOD_TIME=$(mod_time $xs_dir)
    show_mod_time $xs_dir

    for wm in $WMs; do
        write_menu $wm
    done

}

write_menu() {
    local file wm=$1

    case $UID in
        0) file=$(pf "$ROOT_FILE" "$wm") ;;
        *) file=$(pf "$USER_FILE" "$wm") ;;
    esac

    local mod_time=$(mod_time $file)
    show_mod_time $file

    if [ $mod_time -gt $XS_MOD_TIME -a -z "$FORCE" ]; then
        echo "Not updating: $file"
        return
    fi

    [ -z "$WM_LIST" ] && WM_LIST=$(wm_list)

    local start_menu end_menu entry start_file end_file
    local outer_menu

    local istep=$ISTEP
    case $wm in
    fluxbox)
        start_menu="[submenu] (%s)"
        end_menu="[end]"
        entry_text="[exec] (%s) {%%s}"
        ;;

    icewm)
        start_menu="menu \"%s\" - {"
        end_menu="}"
        entry_text="prog \"%s\" - %%s"
        ;;

    jwm)
        start_menu="<Menu label=\"%s\">"
        end_menu="</Menu>"
        entry_text="<Program label=\"%s\">%%s</Program>"
        start_file="<JWM>"
        end_file="</JWM>"
        ;;
    RAW)
        start_menu=""
        end_menu=""
        entry_text=" |%s|%%s|"
        ;;

    *)  error "Unknown window manager: $wm"
        ;;

    esac

    if [ "$DEBUG" ]; then
        echo
        echo "Would write file: $file"
        echo
        _write_menu
    else
        echo "Writing file: $file"
        mkdir -p $(dirname $file)
        _write_menu > $file
    fi
}

_write_menu() {
    local indent=0
    if  [ $start_file ]; then
        pf $start_file
        indent_plus
    fi

   [ "$outer_menu" ] && start_menu "$WM_TITLE"

    for entry in $WM_LIST; do
        entry "$entry" "$SELECT_PROG $entry"
    done

    [ "$outer_menu" ] && end_menu 

    if [ $end_file ]; then
        indent_minus
        pf $end_file
    fi
}

start_menu()   { pf "$start_menu" "$@" ; indent_plus  ;}
end_menu()     { indent_minus ; pf "$end_menu"   "$@" ;}

entry()        { pf "$entry_text" "$@"                ;}
indent_plus()  { indent=$((indent + istep))           ;}
indent_minus() { indent=$((indent - istep))           ;}

pf() {
    local text=$1; shift;
    while [ $# -gt 0 ]; do
        text=$(printf "$text" "$1")
        shift
    done
    printf "%${indent}s" ""
    echo "$text"
}

wm_list() {
    rawWMarray=($(grep -h ^Name= $xs_dir/*.desktop |sed -r -e 's/^Name=//' -e 's/ (desktop|session)$//i' -e 's/ +/_/g' |tr "[A-Z]" "[a-z]" |sort -fu |tr '\n' '\ ' ))
    for wm in ${rawWMarray[@]}; do
        for icon in $icon_managers; do
            eval valid=\$${icon}_enabled
            case ,$valid, in
                *,$wm,*)
                    if [[ ! " ${rawWMarray[@]} " =~ " $icon-$wm " ]]; then
                        echo "$icon-$wm";
	            fi
                ;;
            esac
        done
        echo $wm
    done
}

check_user() {
    [ $UID -ne 0 -a -z "$DEBUG" ] \
        && error "The \"$ME\" script must be run as root"
}

error() {
    echo "$ME Error:" >&2
    echo "$*"         >&2
    exit 2
}
mod_time() {
    file=$1
    if [ -z "$file" ] || [ !  -r $file ]; then
        echo 0
        return
    fi
    stat -c "%Y" $file
}

show_mod_time() {
    file=$1
    [ "$VERBOSE" ] || return

    echo "$file last modified:"
    if [ -z "$file" ] || [ !  -r $file ]; then
        echo unknown
        return
    fi

    stat -c "%y" $file
}

main "$@"

