#! /bin/sh
# vim:sts=2 sw=2 ts=2 et ai foldmethod=marker

# set -x

set_language_stand_alone=0
using_current_default=0
nelm=
[ `basename ${0}` = "language" ] && set_language_stand_alone=1
[ `basename ${0}` = "set_language" ] && set_language_stand_alone=1
if [ -z "${binawk}" ]; then
  if type nawk > /dev/null 2>&1; then
    binawk=nawk
  elif type gawk > /dev/null 2>&1; then
    binawk=gawk
  elif type awk > /dev/null 2>&1; then
    binawk=awk
  fi
fi

LinkDefaultLanguage()
{
  if [ -f "${1}"/default.lng -o -h "${1}"/default.lng ]; then
    changed=1
    if [ -h "${1}"/default.lng ]; then
      base=`ls -l "${1}/default.lng" | ${binawk} -F ' -> ' '{ print $2; }'`
      base=`basename ${base} .lng`
      [ "${2}" = "${base}" ] && changed=0
    fi
    rm -f "${1}"/default.lng
    [ ${changed} -eq 1 ] && LogMessage "Default language was changed to ${2}."
  elif ls -d "${1}"/default.lng >/dev/null 2>&1 ; then
    LogMessage "Default language (default.lng) cannot be safely replaced. Remove it manually."
    return 75
  fi
  ln -s "${2}.lng" "${1}/default.lng"
}


LanguageOf() #{{{
{
  DownCase ${1} | cut -f1 -d-
} #}}}

CountryOf() #{{{
{
  # Print nothing if no country specified.
  DownCase ${1} | cut -s -f2- -d- | cut -f1 -d.
} #}}}

DetermineSystemDefaultLanguage() #{{{
{
  if [ ${set_language_stand_alone} -eq 1 -a -h "${langdir}/default.lng" ]; then #{{{
    link=`ls -l "${langdir}/default.lng" | cut -f2 -d'>' | cut -f2 -d' '`
    default_lang=`basename ${link} .lng`
    using_current_default=1
  else
    if [ -z "${LANG}" ]; then #{{{
      default_lang=en-US
    else
      case ${LANG} in
        C|POSIX*|C.*)   default_lang=en-US ;;
        *)              default_lang=${LANG} ;;
      esac
    fi #}}}
  fi #}}}
} #}}}

ResolveWithLanguageInfo() #{{{
{
  [ ! -r "${language_info}" ] && return
  line=`grep -i ":${*}:" "${language_info}"`
  [ -z "${line}" ] && line=`grep -i "^${*}:" "${language_info}"`
  if [ -z "${line}" ]; then #{{{
    mm=`echo ${*} | tr _ -`
    line=`grep -i "^${mm}:" "${language_info}"`
  fi #}}}
  base=`echo ${line} | cut -f3 -d:`
  [ -z "${base}" ] && base=`echo ${line} | cut -f1 -d:`
  echo ${base}
} #}}}

ResolveLanguage() #{{{
{
  to_resolve="${@}"
  to_resolve=`ResolveWithLanguageInfo ${to_resolve}`
  [ -z "${to_resolve}" ] && to_resolve="${@}"

  selected=
  possible=

  dl=`DownCase ${to_resolve} | tr _ -`
  ln=`LanguageOf ${dl}`
  cn=`CountryOf ${dl}`

  for il in ${InstalledLanguages}; do #{{{
    il_ln=`LanguageOf ${il}`
    il_cn=`CountryOf ${il}`

    if [ "${il_ln}" = "${ln}" ]; then #{{{
      if [ "${il_cn}" = "${cn}" ]; then #{{{
        selected=${il}
        break
      fi #}}}

      # We have a language, but not country, match.
      possible="@${il}"
      continue
    fi #}}}
  done #}}}

  if [ -z "${selected}" ]; then #{{{
    if [ ! -z "${possible}" ]; then #{{{
      selected=${possible}
    fi #}}}
  fi #}}}

  echo ${selected}
} #}}}

DisplayLanguage() #{{{
{
  [ ! -r "${language_info}" ] && return

  ln=`echo ${1} | cut -f1 -d. | tr _ -`
  ln=`grep -i "^${ln}:" "${language_info}" | cut -f2 -d:`

  [ -z "${ln}" ] && return

  if [ -z "${2}" ]; then #{{{
    echo ${ln}
  else
    case ${2} in #{{{
      -bracket*)  echo "[${ln}]" ;;
      -brace*)    echo "{${ln}}" ;;
      -paren*)    echo "(${ln})" ;;
    esac #}}}
  fi #}}}
} #}}}

DL() { DisplayLanguage "${@}"; }
DLbk() { DisplayLanguage "${1}" -bracket; }
DLbr() { DisplayLanguage "${1}" -brace; }
DLp() { DisplayLanguage "${1}" -paren; }

DisplayLanguageList() #{{{
{
  if [ ! -r "${language_info}" ]; then #{{{
    plang=`echo ${InstalledLanguages} | sed -e 's/ /, /g' -e 's/, $//'`

    LogMessage <<EOS
    ${plang}
EOS
  else
    for pl in ${InstalledLanguages}; do #{{{
      LogMessage "    ${pl}   `DL ${pl}`"
    done #}}}
  fi #}}}

  LogMessage <<EOS

EOS
} #}}}

FindInstalledLanguages() #{{{
{
  InstalledLanguages=""
  lng_flist=`ls -md "${langdir}"/*.lng`

  numfiles=`echo ${lng_flist} | ${binawk} -F, '{print NF}'`
  i=0
  while [ ${i} -lt ${numfiles} ]; do #{{{
    i=`expr $i + 1`
    lp=`echo ${lng_flist} | ${binawk} -F, -v num=$i '{print $num}'`
    lp=`echo ${lp}`
    lf=`basename "${lp}" .lng`
    ll=`DownCase "${lf}"`

    [ "${lf}" = "default" ] && continue
    [ -h "${lp}" ] && continue
    InstalledLanguages="${InstalledLanguages} ${lf}"
  done #}}}
} #}}}

InitLanguageFunctions() #{{{
{
  basedir="${1}"

  if [ -z "${basedir}" ]; then #{{{
    LogMessage "Calling script must provide a base directory."
    return 75
  fi #}}}

  langdir="${basedir}/Languages"

  if [ ! -d "${langdir}" ]; then #{{{
    LogMessage "Languages directory cannot be found in ${basedir}."
    return 75
  fi #}}}

  language_info="${langdir}/language.info"
} #}}}

SetDefaultLanguage() #{{{
{
  InitLanguageFunctions "${1}"
  DetermineSystemDefaultLanguage
  FindInstalledLanguages

  # Ask for the default language because it's not been provided or we're not
  # using the defaults.
  if [ ${use_defaults} -eq 0 -o -z "${default_lang}" ]; then #{{{
    [ -z "${default_lang}" ] && default_lang=en-US

    LogMessage <<EOS

Specify the language that should be used by default for e-mail
notifications. The Agent knows the following languages:

EOS

    DisplayLanguageList

    if [ ${using_current_default} -eq 0 ]; then #{{{
      [ -z "${default_lang}" ] && syslang=en-US || syslang=${default_lang}
      language=`ResolveLanguage ${default_lang}`

      near_match=0
      charset=0

      case ${language} in #{{{
        @*) language=`echo ${language} | sed -e 's/@//'`
            near_match=1
            ;;
      esac #}}}

      case ${language} in #{{{
        *.*) charset=1 ;;
      esac #}}}

      default_lang=${language}

      if [ -z ${language} ]; then #{{{
        LogMessage <<EOS
Your default language has been detected as ${syslang} `DLbk ${syslang}`.
This is not a supported language.

Type in a supported language from the list above.

EOS
        default_lang=
      elif [ ${near_match} -eq 1 ]; then
        LogMessage <<EOS
Your default language has been detected as ${syslang} `DLbk ${syslang}`,
which is a supported language with an unsupported language region.
The Agent will use ${language} `DLbk ${language}` as the closest supported
match.

Type in a supported language from the list above or press ENTER to use this
language.

EOS
      elif [ ${charset} -eq 1 ]; then
        LogMessage <<EOS
Your default language has been detected as ${syslang} `DLbk ${syslang}`;
the Agent will see this language as ${language} `DLbk ${language}`, ignoring
character set specifiers.

Type in a supported language from the list above or press ENTER to use this
language.

EOS
      else
        LogMessage <<EOS
Your default language has been detected as ${syslang} `DLbk ${syslang}`.

Type in a supported language from the list above or press ENTER to use this
language.

EOS
      fi #}}}
    else
      LogMessage <<EOS
The Agent is currently set to use ${default_lang} `DLbk ${default_lang}`.

Type in a supported language from the list above or press ENTER to keep the
current language.

EOS
    fi #}}}

    language=
    while [ -z "${language}" ]; do #{{{
      printf "Select language: "
      [ ! -z "${default_lang}" ] && printf "[${default_lang}] "
      read input

      [ -z "${input}" ] && input=${default_lang}
      language=`ResolveLanguage ${input}`

      if [ -z "${language}" ]; then #{{{
        if [ -z "${input}" ]; then #{{{
          LogMessage <<EOS

Language must be specified. Please choose one of the following languages:

EOS
        else
          err_lang=`ResolveWithLanguageInfo ${input}`
          [ -z "${err_lang}" ] && err_lang="${input}"

          LogMessage <<EOS

Unsupported language ${err_lang} `DLbk ${err_lang}`.
Please choose one of the following languages:

EOS
        fi #}}}

        DisplayLanguageList
      fi #}}}
    done #}}}

    case ${language} in #{{{
      @*) language=`echo ${language} | sed -e 's/@//'`
          nelm=`ResolveWithLanguageInfo ${input}`
          ;;
    esac #}}}

    default_lang=${language}
  else
    language=`ResolveLanguage "${default_lang}"`

    if [ -z "${language}" ]; then #{{{
      LogMessage "Language ${default_lang} cannot be resolved."
      LogMessage "Setting to en-US."
      default_lang=en-US
    else
      default_lang=${language}
    fi #}}}
  fi #}}}

  [ -z "${default_lang}" ] && default_lang=en-US

  if [ ! -f "${langdir}"/${default_lang}.lng ]; then #{{{
    LogMessage "A critical error occurred: the language file cannot be found."
    return 75
  fi #}}}

  LogMessage <<EOS

EOS

  if [ ! -z "${nelm}" ]; then #{{{
    LogMessage <<EOS
Language ${nelm} `DLbk ${nelm}` resulted in a non-exact match.
EOS
  fi #}}}

  LogMessage "Using ${default_lang} `DLbk ${default_lang}` as the default language."

  LinkDefaultLanguage "${langdir}" "${default_lang}"

  return 0
} #}}}

if [ ${set_language_stand_alone} -eq 1 ]; then #{{{
  bn0=`basename ${0}`
  dn0=`dirname ${0}`
  use_defaults=0

  [ "${dn0}" = "." ] && dn0=`pwd`

  LogMessage() #{{{
  {
    [ ${#} -gt 0 ] && echo "${@}" || cat -
  } #}}}

  ParamName() #{{{
  {
    echo "${1}" | cut -f1 -d=
  } #}}}

  ParamValue() #{{{
  {
    echo "${1}" | cut -f2 -d=
  } #}}}

  DownCase() #{{{
  {
    echo "${1}" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
  } #}}}

  SetDefaultLanguage "${dn0}"
  exit ${?}
fi #}}}

SetCmdLineLanguageOption() #{{{
{
  InitLanguageFunctions "${1}"
  provided_language="${2}"

  DetermineSystemDefaultLanguage
  FindInstalledLanguages

  # Ask for the default language because it's not been provided or we're not
  # using the defaults.
  default_lang=${provided_language}
  if [ ${use_defaults} -eq 0 -o -z "${default_lang}" ]; then #{{{
    [ -z "${default_lang}" ] && default_lang=en-US

    if [ ${using_current_default} -eq 0 ]; then #{{{
      [ -z "${default_lang}" ] && syslang=default_lang || syslang=${default_lang}
      language=`ResolveLanguage ${default_lang}`

      near_match=0
      charset=0

      case ${language} in #{{{
        @*) language=`echo ${language} | sed -e 's/@//'`
            near_match=1
            ;;
      esac #}}}

      case ${language} in #{{{
        *.*) charset=1 ;;
      esac #}}}

      LogMessage <<EOS
Your selected language has been detected as ${syslang} `DLbk ${syslang}`.
EOS

      LinkDefaultLanguage "${langdir}" "${language}"
    fi #}}}
  fi #}}}	

  return 0
} #}}}
