!=========================================================================
! Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
!
! $Id: locale.gs,v 1.8 2008-01-09 22:50:12 stever Exp $
!
! Superclass Hierarchy:
!   Locale, Object
!
!=========================================================================

expectvalue %String
run

Globals at: #Locale ifAbsent:[
^ Object _newKernelSubclass: 'Locale'
  instVarNames: #(#decimalPoint #thousandsSep #grouping
	          #intCurrSymbol #currencySymbol #monDecimalPoint 
                  #monThousandsSep #monGrouping #positiveSign #negativeSign
                  #intFracDigits #fracDigits #pCsPrecedes #pSepBySpace 
                  #nCsPrecedes #nSepBySpace #pSignPosn #nSignPosn)
  classVars: #()
  classInstVars: #()
  poolDictionaries: #[]
  inDictionary: Globals
  constraints: #[  ]
  instancesInvariant: false
  isModifiable: false
  reservedOop: 971. "GS64 v1.1 reserved OOP!"
]. 
^'Locale already exists'
%

! Remove existing behavior from Locale
removeallmethods Locale
removeallclassmethods Locale


! bugfix 34879/36628
category: 'For Documentation Installation only'
classmethod: Locale
installDocumentation

| doc txt |
doc := GsClassDocumentation newForClass: self.

txt := (GsDocText new) details:
' The Locale class provides access to the host operating system Locale 
 environment (see "man -s 5 locale" for details).

 The current Locale is setup in System sessionState field 16, using the
 internal method System(class)>>_locale.  Applications should access this
 object using the method Locale(class)>>current, rather than calling
 System(class)>>_locale directly.

 The various fields in the Locale object match those available in the
 C structure lconv after a localeconv() call (see "man localeconv" for 
 details).

 As a convenience, class-side methods allow access to the various fields
 of the current Locale object.  For example:

      Locale decimalPoint

 is the same as:

      Locale current decimalPoint

'.
doc documentClassWith: txt.

txt := (GsDocText new) details:
' Methods in this category provide access to individual locale fields
 from the current Locale, such as decimal point or currency sign.'.
doc documentClassCategory: #'Accessing' with: txt.

txt := (GsDocText new) details:
' This category overrides the #new method, which must not be used for
 creating a Locale.  Use the method Locale(class)>>current instead.'.
doc documentClassCategory: #'Instance Creation' with: txt.

txt := (GsDocText new) details:
' Methods in this category provide access to individual locale fields,
 such as decimal point or currency sign.'.
doc documentCategory: #'Accessing' with: txt.

self description: doc.
%

! ------------------- Class methods for Locale
category: 'Accessing'
classmethod: Locale
currencySymbol

   "Return appropriate instvar from the current Locale instance"
   ^self current currencySymbol
%
category: 'Accessing'
classmethod: Locale
current

"Get the current Locale instance from session transient state.
  If we dont have one, go ahead and initialize one "

| locale systm |
systm := System .
( locale := systm _sessionStateAt: 16 ) == nil ifTrue: [
    locale := systm _locale.
    systm _sessionStateAt: 16 put: locale ].
^ locale
%
category: 'Accessing'
classmethod: Locale
decimalPoint

   "Return appropriate instvar from the current Locale instance"
   ^self current decimalPoint
%
category: 'Accessing'
classmethod: Locale
fracDigits

   "Return appropriate instvar from the current Locale instance"
   ^self current fracDigits
%
category: 'Accessing'
classmethod: Locale
grouping

   "Return appropriate instvar from the current Locale instance"
   ^self current grouping
%
category: 'Accessing'
classmethod: Locale
intCurrSymbol

   "Return appropriate instvar from the current Locale instance"
   ^self current intCurrSymbol
%
category: 'Accessing'
classmethod: Locale
intFracDigits

   "Return appropriate instvar from the current Locale instance"
   ^self current intFracDigits
%
category: 'Accessing'
classmethod: Locale
monDecimalPoint

   "Return appropriate instvar from the current Locale instance"
   ^self current monDecimalPoint
%
category: 'Accessing'
classmethod: Locale
monGrouping

   "Return appropriate instvar from the current Locale instance"
   ^self current monGrouping
%
category: 'Accessing'
classmethod: Locale
monThousandsSep

   "Return appropriate instvar from the current Locale instance"
   ^self current monThousandsSep
%
category: 'Accessing'
classmethod: Locale
nCsPrecedes

   "Return appropriate instvar from the current Locale instance"
   ^self current nCsPrecedes
%
category: 'Accessing'
classmethod: Locale
negativeSign

   "Return appropriate instvar from the current Locale instance"
   ^self current negativeSign
%
category: 'Instance Creation'
classmethod: Locale
new

" Use Locale>>current instead "

self shouldNotImplement: #new
%
category: 'Accessing'
classmethod: Locale
nSepBySpace

   "Return appropriate instvar from the current Locale instance"
   ^self current nSepBySpace
%
category: 'Accessing'
classmethod: Locale
nSignPosn

   "Return appropriate instvar from the current Locale instance"
   ^self current nSignPosn
%
category: 'Accessing'
classmethod: Locale
pCsPrecedes

   "Return appropriate instvar from the current Locale instance"
   ^self current pCsPrecedes
%
category: 'Accessing'
classmethod: Locale
positiveSign

   "Return appropriate instvar from the current Locale instance"
   ^self current positiveSign
%
category: 'Accessing'
classmethod: Locale
pSepBySpace

   "Return appropriate instvar from the current Locale instance"
   ^self current pSepBySpace
%
category: 'Accessing'
classmethod: Locale
pSignPosn

   "Return appropriate instvar from the current Locale instance"
   ^self current pSignPosn
%
category: 'Accessing'
classmethod: Locale
thousandsSep

   "Return appropriate instvar from the current Locale instance"
   ^self current thousandsSep
%
! fix 36394 / 36587
! fix 37843: modify to pass categorySymbol directly to _setCategory:locale:
category: 'Updating'
classmethod: Locale
setCategory: categorySymbol locale: LocaleString

   " Modify OS locale setting.

   See man page for setlocale( ) for more details.

   Valid categories:

      #LC_CTYPE        locale's character type handling 
      #LC_NUMERIC      locale's decimal handling
      #LC_TIME         locale's time handling 
      #LC_COLLATE      locale's collation data 
      #LC_MONETARY     locale's monetary handling
      #LC_MESSAGES     locale's messages handling 
      #LC_ALL          all locale categories 
   "

   | locale |
   " call the setLocale primitive "
   ( System _setCategory: categorySymbol locale: LocaleString ) 
      ifFalse: [ ^ nil ].
   " Now reset the transient locale info "
    locale := System _locale.
    System _sessionStateAt: 16 put: locale.
   ^ locale
%
! ------------------- Instance methods for Locale
category: 'Accessing'
method: Locale
currencySymbol

   "Return the value of the instance variable 'currencySymbol'."
   ^currencySymbol
%
category: 'Accessing'
method: Locale
decimalPoint

   "Return the value of the instance variable 'decimalPoint'."
   ^decimalPoint
%
category: 'Accessing'
method: Locale
fracDigits

   "Return the value of the instance variable 'fracDigits'."
   ^fracDigits
%
category: 'Accessing'
method: Locale
grouping

   "Return the value of the instance variable 'grouping'."
   ^grouping
%
category: 'Accessing'
method: Locale
intCurrSymbol

   "Return the value of the instance variable 'intCurrSymbol'."
   ^intCurrSymbol
%
category: 'Accessing'
method: Locale
intFracDigits

   "Return the value of the instance variable 'intFracDigits'."
   ^intFracDigits
%
category: 'Accessing'
method: Locale
monDecimalPoint

   "Return the value of the instance variable 'monDecimalPoint'."
   ^monDecimalPoint
%
category: 'Accessing'
method: Locale
monGrouping

   "Return the value of the instance variable 'monGrouping'."
   ^monGrouping
%
category: 'Accessing'
method: Locale
monThousandsSep

   "Return the value of the instance variable 'monThousandsSep'."
   ^monThousandsSep
%
category: 'Accessing'
method: Locale
nCsPrecedes

   "Return the value of the instance variable 'nCsPrecedes'."
   ^nCsPrecedes
%
category: 'Accessing'
method: Locale
negativeSign

   "Return the value of the instance variable 'negativeSign'."
   ^negativeSign
%
category: 'Accessing'
method: Locale
nSepBySpace

   "Return the value of the instance variable 'nSepBySpace'."
   ^nSepBySpace
%
category: 'Accessing'
method: Locale
nSignPosn

   "Return the value of the instance variable 'nSignPosn'."
   ^nSignPosn
%
category: 'Accessing'
method: Locale
pCsPrecedes

   "Return the value of the instance variable 'pCsPrecedes'."
   ^pCsPrecedes
%
category: 'Accessing'
method: Locale
positiveSign

   "Return the value of the instance variable 'positiveSign'."
   ^positiveSign
%
category: 'Accessing'
method: Locale
pSepBySpace

   "Return the value of the instance variable 'pSepBySpace'."
   ^pSepBySpace
%
category: 'Accessing'
method: Locale
pSignPosn

   "Return the value of the instance variable 'pSignPosn'."
   ^pSignPosn
%
category: 'Accessing'
method: Locale
thousandsSep

   "Return the value of the instance variable 'thousandsSep'."
   ^thousandsSep
%
