#!/bin/ash
# Configuration GUI for Fatdog Event Manager 
# Copyright (C) James Budiono 2012, 2020
#
# License: GNU GPL Version 3 or later
#
# Note: the bits in Global Inits, which is part of GTK-server bash init code
#       is (C) Peter van Eerten. Everything else is (C) James Budiono
#
# internationalization by L18L

# std localisation stanza
export TEXTDOMAIN=fatdog
. gettext.sh
# performance tweak - use "C" if there is no localisation
! [ -e $TEXTDOMAINDIR/${LANG%.*}/LC_MESSAGES/$TEXTDOMAIN.mo ] &&
! [ -e $TEXTDOMAINDIR/${LANG%_*}/LC_MESSAGES/$TEXTDOMAIN.mo ] && LANG=C

### configuration variables
APPTITLE="$(gettext 'Fatdog64 Event Manager')"
EVENTMANAGER_CONFIG=/etc/eventmanager
#EVENTMANAGER_CONFIG=$(readlink -f ./eventmanager)

### runtime variables with default values
RAMSAVEINTERVAL=30
ACCESS_MODE=750
ICON_ALIGNMENT=bottom	
SHOW_VOLUME_LABEL=yes	
MARGIN_TOP=32 MARGIN_BOTTOM=64 MARGIN_LEFT=32 MARGIN_RIGHT=32
ICON_DX=64	
ICON_DY=64	
GRID_X=16	
GRID_Y=16
STARTUP_DELAY=3

[ $(id -u) -ne 0 ] && exec gtksu "$APPTITLE" "$0" # must run as root for the time being

#---------------------------------------------------------- Global Inits
### global variables for proper GTK-server
GTK= NULL="NULL"
PIPE=/tmp/gtk.bash.$$
trap 'stop-gtk-server -fifo $PIPE; exit' HUP TERM INT # stop GTK-server in case of an error

### start GTK-server
gtk-server -fifo=$PIPE &
while [ ! -p $PIPE ]; do sleep 1; continue; done

### GTK-server helper functions
# Assignment function
define() { $2 $3 $4 $5 $6 $7 $8 $9; eval $1=\'"$GTK"\'; }

# Communicate with GTK-server
gtk()
{
/bin/echo "$@" > $PIPE
read GTK < $PIPE
}

#---------------------------------------------------------- GUI realization

init_gtk() {
	# init gtk
	gtk gtk_init
	
	# add GTK+ API not defined in gtk-server.cfg
	gtk gtk_server_define gtk_builder_new NONE WIDGET 0
	gtk gtk_server_define gtk_builder_add_from_file NONE INT 3 WIDGET STRING NULL
	gtk gtk_server_define gtk_builder_add_from_string NONE INT 4 WIDGET STRING INT NULL
	gtk gtk_server_define gtk_builder_get_object NONE WIDGET 2 WIDGET STRING
	gtk gtk_server_define gtk_builder_connect_signals NONE NONE 2 WIDGET NULL		
}

### load config
load_config() {
	# load current settings from file, otherwise use defaults
	[ -e $EVENTMANAGER_CONFIG ] && . $EVENTMANAGER_CONFIG
	

	# make sure text entries are not blank
	for p in RAMSAVEINTERVAL MARGIN_TOP MARGIN_BOTTOM MARGIN_LEFT MARGIN_RIGHT \
	         ICON_DX ICON_DY GRID_X GRID_Y STARTUP_DELAY MAX_VOLABEL; do
		eval pp=\$$p
		[ -z "$pp" ] && eval $p=0
	done

	# prepare dialog
	gtk gtk_entry_set_text $ENTRY_RAM_SAVE $RAMSAVEINTERVAL
	gtk gtk_entry_set_text $ENTRY_MULTI_COMPRESS "\"$MKSQUASHFS_OPTIONS\""
	
	gtk gtk_entry_set_text $ENTRY_MARGIN_TOP $MARGIN_TOP
	gtk gtk_entry_set_text $ENTRY_MARGIN_BOTTOM $MARGIN_BOTTOM
	gtk gtk_entry_set_text $ENTRY_MARGIN_LEFT $MARGIN_LEFT
	gtk gtk_entry_set_text $ENTRY_MARGIN_RIGHT $MARGIN_RIGHT
	
	gtk gtk_entry_set_text $ENTRY_ICON_DX $ICON_DX
	gtk gtk_entry_set_text $ENTRY_ICON_DY $ICON_DY
	gtk gtk_entry_set_text $ENTRY_GRID_X $GRID_X
	gtk gtk_entry_set_text $ENTRY_GRID_Y $GRID_Y
	
	gtk gtk_entry_set_text $ENTRY_STARTUP_DELAY $STARTUP_DELAY
	gtk gtk_entry_set_text $ENTRY_MAX_VOLABEL $MAX_VOLABEL
	gtk gtk_entry_set_text $ENTRY_EXCLUDED_DRIVES "\"$(echo $EXCLUDED_DRIVES | sed 's/|/, /g')\""
	
	case $ACCESS_MODE in
		770) gtk gtk_toggle_button_set_active $RADIO_ACCESS_RW 1 ;;
		*) gtk gtk_toggle_button_set_active $RADIO_ACCESS_RO 1 ;;
	esac
	
	case $ICON_ALIGNMENT in 
		bottom) gtk gtk_toggle_button_set_active $RADIO_ALIGN_BOTTOM 1 ;;
		top)    gtk gtk_toggle_button_set_active $RADIO_ALIGN_TOP 1 ;;
		left)   gtk gtk_toggle_button_set_active $RADIO_ALIGN_LEFT 1 ;;
		right)  gtk gtk_toggle_button_set_active $RADIO_ALIGN_RIGHT 1 ;;
	esac
	
	case $SHOW_VOLUME_LABEL in
		"") gtk gtk_toggle_button_set_active $CKBOX_VOLUME_LABEL 0 ;;
		*)  gtk gtk_toggle_button_set_active $CKBOX_VOLUME_LABEL 1 ;;
	esac

	case $USE_DRIVE_ICON in
		"") gtk gtk_toggle_button_set_active $CKBOX_USE_DRIVE_ICON 0 ;;
		*)  gtk gtk_toggle_button_set_active $CKBOX_USE_DRIVE_ICON 1 ;;
	esac
	
	case $UNLISTED_ACCESS in
		"") gtk gtk_toggle_button_set_active $CKBOX_UNLISTED_ACCESS 0 ;;
		*)  gtk gtk_toggle_button_set_active $CKBOX_UNLISTED_ACCESS 1 ;;
	esac
	
	case $ACCESS_GROUP in
		"") gtk gtk_toggle_button_set_active $CKBOX_ACCESS_GROUP 0 ;;
		*)  gtk gtk_toggle_button_set_active $CKBOX_ACCESS_GROUP 1 ;;
	esac

	case $DEFAULT_CLICK_ACTION in
		""|devmount) gtk gtk_toggle_button_set_active $CKBOX_MOUNT_BY_LABEL 0 ;;
		*)  gtk gtk_toggle_button_set_active $CKBOX_MOUNT_BY_LABEL 1 ;;
	esac
		
	return 0
}

### validate and save settings
save_config() {
	# get values
	define RAMSAVEINTERVAL gtk gtk_entry_get_text $ENTRY_RAM_SAVE
	define MKSQUASHFS_OPTIONS gtk gtk_entry_get_text $ENTRY_MULTI_COMPRESS
	
	define MARGIN_TOP gtk gtk_entry_get_text $ENTRY_MARGIN_TOP
	define MARGIN_BOTTOM gtk gtk_entry_get_text $ENTRY_MARGIN_BOTTOM
	define MARGIN_LEFT gtk gtk_entry_get_text $ENTRY_MARGIN_LEFT
	define MARGIN_RIGHT gtk gtk_entry_get_text $ENTRY_MARGIN_RIGHT
	
	define ICON_DX gtk gtk_entry_get_text $ENTRY_ICON_DX
	define ICON_DY gtk gtk_entry_get_text $ENTRY_ICON_DY
	define GRID_X gtk gtk_entry_get_text $ENTRY_GRID_X
	define GRID_Y gtk gtk_entry_get_text $ENTRY_GRID_Y
	
	define STARTUP_DELAY gtk gtk_entry_get_text $ENTRY_STARTUP_DELAY
	define MAX_VOLABEL gtk gtk_entry_get_text $ENTRY_MAX_VOLABEL
	define EXCLUDED_DRIVES gtk gtk_entry_get_text $ENTRY_EXCLUDED_DRIVES
	EXCLUDED_DRIVES=$(echo "$EXCLUDED_DRIVES"|sed 's/[ ]*,[ ]*/|/g;s/^[ ]*//; s/[ ]*$//')
	
	gtk gtk_toggle_button_get_active $RADIO_ACCESS_RW
	case $GTK in
		1) ACCESS_MODE=770 ;;
		0) ACCESS_MODE=750 ;;
	esac
	
	UNLISTED_ACCESS=
	gtk gtk_toggle_button_get_active $CKBOX_UNLISTED_ACCESS
	case $GTK in 1) UNLISTED_ACCESS=yes; ACCESS_MODE=${ACCESS_MODE/0/5} ;; esac
	
	ACCESS_GROUP=
	gtk gtk_toggle_button_get_active $CKBOX_ACCESS_GROUP
	case $GTK in 1) ACCESS_GROUP=users ;; esac
	
	gtk gtk_toggle_button_get_active $RADIO_ALIGN_BOTTOM
	case $GTK in 1) ICON_ALIGNMENT=bottom ;; esac
	gtk gtk_toggle_button_get_active $RADIO_ALIGN_TOP
	case $GTK in 1) ICON_ALIGNMENT=top ;; esac
	gtk gtk_toggle_button_get_active $RADIO_ALIGN_LEFT
	case $GTK in 1) ICON_ALIGNMENT=left ;; esac
	gtk gtk_toggle_button_get_active $RADIO_ALIGN_RIGHT
	case $GTK in 1) ICON_ALIGNMENT=right ;; esac
	
	SHOW_VOLUME_LABEL=
	gtk gtk_toggle_button_get_active $CKBOX_VOLUME_LABEL
	case $GTK in 1) SHOW_VOLUME_LABEL=yes ;; esac

	USE_DRIVE_ICON=
	gtk gtk_toggle_button_get_active $CKBOX_USE_DRIVE_ICON
	case $GTK in 1) USE_DRIVE_ICON=yes ;; esac

	DEFAULT_CLICK_ACTION=devmount
	gtk gtk_toggle_button_get_active $CKBOX_MOUNT_BY_LABEL
	case $GTK in 1) DEFAULT_CLICK_ACTION=labelmount ;; esac

	# save - try to preserve the comments if file exist, otherwise create new one
	[ ! -e $EVENTMANAGER_CONFIG ] && touch $EVENTMANAGER_CONFIG
	sed -i -e "
s/RAMSAVEINTERVAL=[^ \t]*/RAMSAVEINTERVAL='$RAMSAVEINTERVAL'/
s/MKSQUASHFS_OPTIONS=[^ \t]*.*/MKSQUASHFS_OPTIONS='$MKSQUASHFS_OPTIONS'/

s/MARGIN_TOP=[^ \t]*/MARGIN_TOP='$MARGIN_TOP'/
s/MARGIN_BOTTOM=[^ \t]*/MARGIN_BOTTOM='$MARGIN_BOTTOM'/
s/MARGIN_LEFT=[^ \t]*/MARGIN_LEFT='$MARGIN_LEFT'/
s/MARGIN_RIGHT=[^ \t]*/MARGIN_RIGHT='$MARGIN_RIGHT'/

s/ICON_DX=[^ \t]*/ICON_DX='$ICON_DX'/
s/ICON_DY=[^ \t]*/ICON_DY='$ICON_DY'/
s/GRID_X=[^ \t]*/GRID_X='$GRID_X'/
s/GRID_Y=[^ \t]*/GRID_Y='$GRID_Y'/

s/STARTUP_DELAY=[^ \t]*/STARTUP_DELAY='$STARTUP_DELAY'/
s/MAX_VOLABEL=[^ \t]*/MAX_VOLABEL='$MAX_VOLABEL'/
s/EXCLUDED_DRIVES=.*$/EXCLUDED_DRIVES='$EXCLUDED_DRIVES'/
s/USE_DRIVE_ICON=[^ \t]*/USE_DRIVE_ICON='$USE_DRIVE_ICON'/

s/ACCESS_MODE=[^ \t]*/ACCESS_MODE='$ACCESS_MODE'/
s/UNLISTED_ACCESS=[^ \t]*/UNLISTED_ACCESS='$UNLISTED_ACCESS'/
s/ACCESS_GROUP=[^ \t]*/ACCESS_GROUP='$ACCESS_GROUP'/
s/ICON_ALIGNMENT=[^ \t]*/ICON_ALIGNMENT='$ICON_ALIGNMENT'/
s/SHOW_VOLUME_LABEL=[^ \t]*/SHOW_VOLUME_LABEL='$SHOW_VOLUME_LABEL'/
s/DEFAULT_CLICK_ACTION=[^ \t]*/DEFAULT_CLICK_ACTION='$DEFAULT_CLICK_ACTION'/
" $EVENTMANAGER_CONFIG
	
	# fill in missing values
	append_config RAMSAVEINTERVAL
	append_config MKSQUASHFS_OPTIONS
	append_config ACCESS_MODE
	append_config UNLISTED_ACCESS
	append_config ACCESS_GROUP
	append_config ICON_ALIGNMENT
	append_config SHOW_VOLUME_LABEL	
	append_config MARGIN_TOP
	append_config MARGIN_BOTTOM
	append_config MARGIN_LEFT
	append_config MARGIN_RIGHT
	append_config ICON_DX
	append_config ICON_DY
	append_config GRID_X
	append_config GRID_Y
	append_config STARTUP_DELAY
	append_config USE_DRIVE_ICON
	append_config MAX_VOLABEL
	append_config EXCLUDED_DRIVES
	append_config DEFAULT_CLICK_ACTION
	
	Xdialog --title "$(gettext 'Success!')" --infobox "$(gettext 'Configuration is updated.')" 0 0 10000
}
# $1 config item
append_config() {
	! grep -Fqm 1 $1 $EVENTMANAGER_CONFIG && eval echo $1=\\\'\$$1\\\' >> $EVENTMANAGER_CONFIG
	return 0
}

################### main ###################
### gtk-server localisation stanza
gtk gtk_server_define setlocale NONE STRING 2 INT STRING
gtk gtk_server_define bindtextdomain NONE STRING 2 STRING STRING
gtk gtk_server_define textdomain NONE STRING 1 STRING
gtk setlocale 6 \"\" # 6 corresponds to LC_ALL
gtk bindtextdomain $TEXTDOMAIN $TEXTDOMAINDIR
gtk textdomain $TEXTDOMAIN

### init gui
init_gtk
define BUILDER gtk gtk_builder_new
define RESULT gtk gtk_builder_add_from_file $BUILDER "${0}.xml"
gtk gtk_builder_connect_signals $BUILDER

define MAIN_WINDOW gtk gtk_builder_get_object $BUILDER main_window
define BUTTON_QUIT gtk gtk_builder_get_object $BUILDER button-quit
define BUTTON_SAVE gtk gtk_builder_get_object $BUILDER button-save

define ENTRY_RAM_SAVE gtk gtk_builder_get_object $BUILDER ram-save
define ENTRY_MULTI_COMPRESS gtk gtk_builder_get_object $BUILDER multi-compress

define ENTRY_MARGIN_TOP gtk gtk_builder_get_object $BUILDER margin-top
define ENTRY_MARGIN_BOTTOM gtk gtk_builder_get_object $BUILDER margin-bottom
define ENTRY_MARGIN_LEFT gtk gtk_builder_get_object $BUILDER margin-left
define ENTRY_MARGIN_RIGHT gtk gtk_builder_get_object $BUILDER margin-right

define LABEL_ICON_DX gtk gtk_builder_get_object $BUILDER icon-dx-label
define LABEL_ICON_DY gtk gtk_builder_get_object $BUILDER icon-dy-label
define ENTRY_ICON_DX gtk gtk_builder_get_object $BUILDER icon-dx
define ENTRY_ICON_DY gtk gtk_builder_get_object $BUILDER icon-dy
define ENTRY_GRID_X gtk gtk_builder_get_object $BUILDER grid-x
define ENTRY_GRID_Y gtk gtk_builder_get_object $BUILDER grid-y

define RADIO_ACCESS_RW gtk gtk_builder_get_object $BUILDER access-rw
define RADIO_ACCESS_RO gtk gtk_builder_get_object $BUILDER access-ro
define CKBOX_UNLISTED_ACCESS gtk gtk_builder_get_object $BUILDER access-unlisted
define CKBOX_ACCESS_GROUP gtk gtk_builder_get_object $BUILDER access-group

define RADIO_ALIGN_BOTTOM gtk gtk_builder_get_object $BUILDER align-bottom
define RADIO_ALIGN_LEFT gtk gtk_builder_get_object $BUILDER align-left
define RADIO_ALIGN_TOP gtk gtk_builder_get_object $BUILDER align-top
define RADIO_ALIGN_RIGHT gtk gtk_builder_get_object $BUILDER align-right

define CKBOX_VOLUME_LABEL gtk gtk_builder_get_object $BUILDER volume-label
define ENTRY_STARTUP_DELAY gtk gtk_builder_get_object $BUILDER startup-delay
define CKBOX_USE_DRIVE_ICON gtk gtk_builder_get_object $BUILDER use-drive-icon
define ENTRY_MAX_VOLABEL gtk gtk_builder_get_object $BUILDER max-volabel
define CKBOX_MOUNT_BY_LABEL gtk gtk_builder_get_object $BUILDER mount-by-label
define ENTRY_EXCLUDED_DRIVES gtk gtk_builder_get_object $BUILDER excluded-drives

gtk g_object_unref $BUILDER

### connect signals
gtk gtk_server_connect $MAIN_WINDOW delete-event quit-clicked
gtk gtk_server_connect $BUTTON_QUIT clicked quit-clicked
gtk gtk_server_connect $BUTTON_SAVE clicked save-clicked

### init app
load_config
if [ -z "$UNPATCHED_ROX" ]; then
	gtk gtk_widget_hide $ENTRY_ICON_DX
	gtk gtk_widget_hide $ENTRY_ICON_DY
	gtk gtk_widget_hide $LABEL_ICON_DX
	gtk gtk_widget_hide $LABEL_ICON_DY
fi

### gtk main loop
gtk gtk_widget_show $MAIN_WINDOW
while true; do 
	define EVENT gtk gtk_server_callback wait
	case $EVENT in
		quit*)	break ;;
		save*)  save_config ;;
	esac
done
gtk gtk_server_exit 

