**************************************************************************
** title:      Localization
** author:     Brian Frank
** created:    5 Nov 07
** copyright:  Copyright (c) 2007, Brian Frank and Andy Frank
** license:    Licensed under the Academic Free License version 3.0
**************************************************************************

Locale [#locale]
****************
The `sys::Locale` class is the hub API for Fantom's localization
infrastructure.  Locales are used to represent a language via
an ISO 639 two letter code.  A locale may also optionally represent
a specific country or region via a ISO 3166 two letter code.  Common
locales include:

    Language Only:
      en     English
      es     Spanish
      fr     French
      de     German
      it     Italian
      ja     Japanese
      ko     Korean
      zh     Chinese
    Language and Country:
      en-US  United States
      en-GB  United Kingdom
      es-ES  Spain
      es-MX  Mexico
      fr-FR  France
      de-DE  Germany
      en-CA  Canada (English)
      fr-CA  Canada (French)
      zh-CN  China (Simplified)
      zh-TW  Taiwan

When the Fantom VM is started it will create a default locale based on the
underlying platform.  For example on a Java VM, the default Fantom locale
will be initialized from 'java.util.Locale' (which in turn is
initialized from the operating system's default locale).

Locales are configured as an actor local variable.  Use `sys::Locale.cur`
and `sys::Locale.setCur` to get and set the current thread's locale.

By convention 'Locale' is never passed as a parameter to Fantom APIs.  Rather
the locale is implied by the current actor.  As a general rule APIs which
are locale sensitive will include the term 'locale' in their method name.

Use [Locale.use]`sys::Locale.use` to execute a body of code using a
different locale:

  echo(Locale.cur)
  Locale("zh-CN").use {  echo(Locale.cur) }
  echo(Locale.cur)

Localized Properties [#props]
*****************************
All the strings displayed to users should typically be pulled out into
*localized props files* to enable easy language translation.  Each pod may
define one localized property map with as many keys are desired.
Localized properties are defined in [props files]`sys::InStream.readProps` as
pod resource files under the 'locale' directory.  An example set of localized
props files:

   locale/en.props
   locale/en-US.props
   locale/en-CA.props
   locale/fr.props
   locale/fr-CA.props

The `sys::Env.locale` API is used to lookup a localized property.
Typically you will use the [Pod.locale]`sys::Pod.locale` convenience
method:

  Button(pod.locale("ok"))
  Button(pod.locale("cancel"))

Looking up localization is delegated to the current [Env]`sys::Env`.
But the standard resolution rules are:

  1. 'Env.props(pod, `locale/{locale}.props`)'
  2. 'Env.props(pod, `locale/{lang}.props`)'
  3. 'Env.props(pod, `locale/en.props`)'
  4. Fallback to 'pod::key' unless 'def' specified

[Env.props]`sys::Env.props` first looks in the pod's etc directory for
overrides, then checks if the pod contains a resource file.

Best practice is to ensure that all properties are mapped in 'en.props' file
as your fallback defaults.  Then store localized translations in language
files such as 'fr.props', 'de.props', etc.  Typically you will only use
country specific files such as 'en-US' or 'en-GB' for regional terms.

Locale Literals [#localeLiterals]
*********************************
String interpolation supports a special mode used to make working
with localized props easy.  The following interpolation formats are
supported:

  - '$<key>' unqualified key
  - '$<pod::key>' qualified key
  - '$<key=def>' unqualified key with default value

The simplest locale literal is an unqualified key which is just
a shortcut for `sys::Pod.locale` using the enclosing type:

  // original code
  class Foo { Void main() { echo("$<bar.baz>") } }

  // translated into
  class Foo { Void main() { echo(#Foo.pod.locale("bar.baz")) } }

You can also use a qualified key to lookup a localized prop in an
external pod:

  // original code
  "$<fwt::cancel.name>"

  // translated into
  Pod.find("fwt").locale("cancel.name")

The last format lets you actually define the key's value right in
your Fantom source code:

  // orginal code
  "$<fileNotFound=File not found>: $file"

  // translates into
  EnclosingType#.pod.locale("fileNotFound", "File not found") + ": $file"

  // and automatically adds the key/value pair to locale/en.props
  fileNotFound=File not found

If your pod doesn't have an explicit "locale/en.props" resource then it
is automatically created.  If it does exist then interpolated key/values
are automatically merged into the existing props file.  It is a compile
time error to declare a key's value in multiple places; each key must
be defined exactly once in either en.props or in an interpolated string.

