#!/bin/ash
# choose locale for user
# Copyright (C) James Budiono 2012, 2014
# License: GNU GPL Version 3 or later
#
# 2014-01 L18L - localisation
#141202 omit territory in dialog, ex: German Germany. Now just: German de_DE.UTF - German locale for Germany
#141212 launch script $0.i18n for localizing desktop without need to RestartX
#141231 --no-cancel and move actual language to top of list

export TEXTDOMAIN=fatdog

### configuration
APPTITLE="$(gettext 'Fatdog64 Locale Selector')"
SUPPORTED_GLIBC_LOCALES=/usr/share/i18n/SUPPORTED
LOCALE_DEF_DIR=/usr/share/i18n/locales
LOCALE_DIR=/usr/lib64/locale
LANG_CONFIG=$FATDOG_STATE_DIR/language	# read by /etc/profile and xwin
CACHE_DIR=/tmp/${0##*/}
CACHE_FILE=$CACHE_DIR/cache
COUNT_FILE=$CACHE_DIR/count
FIXED_LOCALES_DIR=$CACHE_DIR/locales
WORKDIR=/tmp/${0##*/}.$$

# helper - create Xdialog treeview strings for all supported locales.
# this is an extra long pipeline - so cache this result for later
supported_locales() {
	# use the simplified locale list, if exists
	[ -e ${SUPPORTED_GLIBC_LOCALES}_simple ] && SUPPORTED_GLIBC_LOCALES=${SUPPORTED_GLIBC_LOCALES}_simple
	index=0
	while read -r p; do
		case $p in 
			\#*|SUPPORTED*) ;;	# ignore these
			*)	# read the locale / charmap combination
				index=$(( index + 1))
				p=${p% \\}	# remove training space and backslash
				src=${p%%/*}; src=${src%%.*}
				
				# only process if we have the source file
				if [ -e $FIXED_LOCALES_DIR/$src ]; then
					# locale and charmaps
					echo -n "${p%%/*}|${p##*/}|"
					
					# read the source for title (description), language, and territory (country)
					LN='' CN=''
					while read -r q ; do
					case $q in
							%*) ;; # comment, ignore
							title*)        TI="\"${q#*\"}" ;;
							lang_name*)    LN="${q#*\"}"; LN="${LN%\"*} " ;;
							language*)     LA="${q#*\"}"; LA="${LA%\"*}" ;;
							country_name*) CN="${q#*\"}"; CN="${CN%\"*} " ;; 
							territory*)    TE="${q#*\"}"; TE="${TE%\"*}" ;;
						esac
					done < $FIXED_LOCALES_DIR/$src
					[ "$LA" = "${LN% }" ] && LN='' #avoid "Afrikaans Afrikaans"
					[ "$TE" = "${CN% }" ] && CN='' #avoid "Bulgaria Bulgaria"
					echo "${TI}|\"${LN}${LA}\"|\"${CN}${TE}\"" 
				fi
				;;
		esac
	done < $SUPPORTED_GLIBC_LOCALES | tr -d '"' | 
	awk -F"|" '
	# transliterate columns
	# input:  locale|charmap|title|language|territory
	#         $1     $2      $3    $4       $5
	# output: language|country|locale|charmap|description
	{ print   $4     "|" $5  "|" $1 "|" $2  "|" $3}' | 
	sort -f | 
	awk -F"|" '
	# format for Xdialog tree output
	# input: language|country|locale|charmap|description
	#        $1       $2      $3     $4      $5
	{
		if ( $1 != language ) {
			print "\"" $1 "\"", "\"" $1 "\"", "off", 0
			language=$1
			country=""
		}				
		if ( $2 != country ) {
			print "\"" $2 "\"", "\"" $2 "\"", "off", 1
			country=$2
		}
		print "\"" $3 "+" $4 "\"", "\"" $3 " - " $5 "\"", "off", 2
	}
	'
}

### 
build_cache() {
	local count=0 files=0
	
	# cache validity check
	[ -e $COUNT_FILE ] && read count < $COUNT_FILE 
	files=$(ls -l $LOCALE_DEF_DIR | wc -l)
	[  $files -eq $count ] && return
	echo $files > $COUNT_FILE
	rm -f $FIXED_LOCALES_DIR/* 
	
	# it will be long, tell user to wait
	Xdialog --no-buttons --title "$APPTITLE" \
	--infobox "$(gettext 'Please wait, computing available locales.')" 0 0 1000000 &
	XPID=$!

	# fix locale files - add missing lang_name
	mkdir -p $WORKDIR/bad $WORKDIR/good $WORKDIR/locales
	
	# copy files & separate those who have langnames and not
	find $LOCALE_DEF_DIR -type f -print0 | xargs -0 grep -l ^lang_name | xargs cp -t $WORKDIR/good
	find $LOCALE_DEF_DIR -type f -print0 | xargs -0 grep -L ^lang_name | xargs cp -t $WORKDIR/bad
	find $WORKDIR \( -name 'iso*' -o -name 'translit*' -o -name 'i18n' -o -name 'POSIX' \) -delete
	#find $WORKDIR -type f
	
	# for every locale file that don't have langnames, try to find a sensible one
	ls $WORKDIR/bad | while read -r p; do
		lang_name=$(grep -m1 ^lang_name $WORKDIR/good/${p%%_*}_* 2> /dev/null)
		case "$lang_name" in
			*FIXME*|"") cp $WORKDIR/bad/"$p" $WORKDIR/locales ;; # can't do anything, too bad
			*) { cat $WORKDIR/bad/"$p"; echo "$lang_name"; } > $WORKDIR/locales/"$p" ;;
		esac
	done
	
	# copy the rest of the good files
	cp $WORKDIR/good/* $WORKDIR/locales
	#ls $WORKDIR/locales
	
	# special treatment
	sed -i -e 's#language   "U006Breyol"#language   "Kreyol"#' $WORKDIR/locales/ht_HT
	sed -i -e 's#lang_name "<U0064><U0075><U0074><U0063><U0068>"#lang_name "Nederlands"#' $WORKDIR/locales/nl_*

	# convert UCS to UTF, join lines split by /
	sed -i -e ':x; /\/$/ { N; s/\/\n//; tx }' $WORKDIR/locales/*
	ls $WORKDIR/locales | while read -r p; do
		show-ucs-data $WORKDIR/locales/"$p" > $FIXED_LOCALES_DIR/"$p"
	done
	rm -rf $WORKDIR	
	
	# generate Xdialog strings
#	supported_locales > $CACHE_FILE                                 #141202
	supported_locales | grep -v '1$' | sed 's/2$/1/'  > $CACHE_FILE #141202
	kill $XPID
}

# L18L: $1-locale to move to top
locale_to_top()
{
    local pp=$1 LINE1
    grep -B 1 "^\"${pp}_" $CACHE_FILE > ${CACHE_FILE}_1
    grep -v   "^\"${pp}_" $CACHE_FILE > ${CACHE_FILE}_2
    read LINE1 < ${CACHE_FILE}_1
    grep -v   "$LINE1" ${CACHE_FILE}_2 >> ${CACHE_FILE}_3
    cat ${CACHE_FILE}_1 ${CACHE_FILE}_3 > ${CACHE_FILE}
    rm ${CACHE_FILE}_*
}

# L18L: move current locale to top
actual_locale_to_top()
{
    local pp p=$LANG
    read p < $LANG_CONFIG
    pp=${p%_*}
    echo move LANGUAGE $pp to top of list 
    locale_to_top $pp
}


### main ###

mkdir -p $FIXED_LOCALES_DIR; build_cache

locale_to_top en     # English pre-installed
actual_locale_to_top # a bit more user friendly

CURR_LOCALE_TEXT="\
$(eval echo $(gettext 'Current locale is ${LANG}')) \n
$(awk -F\" '/^title/ {print $2}' $FIXED_LOCALES_DIR/${LANG%.*})" 

# --treeview <text> <height> <width> <list height> <tag1> <item1> <status1> <item_depth1> {<help1>}... 
if selection=$(eval Xdialog --stdout --title \"$APPTITLE\" \
             --backtitle \" $CURR_LOCALE_TEXT \" \
             --treeview \"$(gettext 'Select your locale')\" 30 80 0 $(cat $CACHE_FILE) ); then
	locale=${selection%+*}; source=${locale%.*}
	charmap=${selection#*+}
	#echo $locale $source $charmap
	case $selection in *+*) ;; *)
		Xdialog --title "$APPTITLE" --infobox "$(gettext 'You need to choose the specific locale; not only the language or the country.')" 0 0 10000
		exec "$0" 
	esac
	
	locale_dir=$(echo $locale | sed 's/UTF-8/utf8/')
	if [ ! -e $LOCALE_DIR/$locale_dir ]; then
		# locale not yet compiled, need to generate it
		if [ $(id -u) -ne 0 ]; then gtksu "$(gettext 'Create new locale definition')" localedef -f $charmap -i $source --no-archive $locale
		else localedef -f $charmap -i $source --no-archive $locale 
		fi
		
		# check that it is actually created now, only if it is we set the locale
		if [ $? -eq 0 ]; then
			echo $locale > $LANG_CONFIG; ok=ok
		fi
	else
		echo $locale > $LANG_CONFIG; ok=ok
	fi
fi

if [ $ok ]; then 
    [ -r ${0}.i18n ] && . ${0}.i18n # 141212 - run this file if it exists.
    [ -z $FIRST_RUN ] && # first-run, don't ask and don't restart
	Xdialog --title "$APPTITLE" --yesno "$(eval echo $(gettext 'Your new locale will be set to $locale after you restart X server.'))
$(eval echo $(gettext 'Locale configuration is stored in $LANG_CONFIG.'))\n\n
$(gettext 'Do you want to restart X server now?')" 0 0 && wmexit restart
else Xdialog --title "$APPTITLE" --infobox "$(gettext 'Cancelled, nothing is changed.')" 0 0 10000
fi

