// ============================================================================
// File:               I18n4Java1.java
//
// Project:            I18n support for the Java 1.x platform.
//
// Purpose:            Application specific support for internationalisation.
//
// Author:             Rammi
//-----------------------------------------------------------------------------
// Copyright Notice:   (c) 2002  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================

package de.caff.i18n;

import java.util.*;

/**
 *  Application specific support for internationalization,
 *  used for Java 1.1.
 *
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
class I18n4Java1 extends I18n
{
  /** The resource bundles. */
  protected Map     resourceBundles  = new HashMap();
  /** The resource bases. */
  protected List    appResourceBases = new ArrayList(1);
  /** The default locale. */
  protected Locale  defaultLocale    = Locale.getDefault();

  /**
   *  Collection of known localizables, which have to be informed
   *  of localization changes.
   *  <p>
   *  Because of the pseudo-static nature of this array be sure each
   *  element is removed when it's not longer used elsewhere,
   *  otherwise there's a memory leak.
   */
  protected List    localizables     = new ArrayList();


  /**
   *  Add an application specific resource class base name.
   *  This should be called by any application/applet before
   *  any other i18n specific code is used.
   *  @param  base  base class name for resources
   *  @see java.util.ResourceBundle
   */
  protected void _addAppResourceBase(String base)
  {  
    appResourceBases.add(base);
    resourceBundles.clear();
  }


  /**
   *  Set the locale to be used as a default for the application.
   *  @param  l   locale to be used as default
   */
  protected void _setDefaultLocale(Locale l)
  {
    // System.out.println("Default locale: "+l);
    if (l == null) {
      l = Locale.getDefault();
    }
    defaultLocale = l;

    _fireLocaleChanged(l);
  }

  /**
   *  Get the locale to be used as a default for the application.
   *  @return   locale to be used as default
   */
  protected Locale _getDefaultLocale() 
  {
    return defaultLocale;
  }

  /**
   *  Get a ResourceBundle for a locale.
   *  @param  l  locale
   *  @return ResourceBundle for that Locale
   *  @exception MissingResourceException  when no appResourceBase is set
   */
  protected ResourceBundle _getBundle(Locale l) 
  {
    if (l == null) {
      l = defaultLocale;
    }
    ResourceBundle res = (ResourceBundle)resourceBundles.get(l);
    if (res == null) {
      // this resource is unknown yet
      if (appResourceBases.size() == 0) {
	throw new MissingResourceException("No application specific resource base defined", 
					   "<unknown>",
					   "");
      }
     
      ResourceBundleCollection collect = new ResourceBundleCollection();

      for (Iterator iterator = appResourceBases.iterator(); iterator.hasNext();) {
        collect.addResourceBundle(ResourceBundle.getBundle((String)iterator.next()));
      }

      resourceBundles.put(l, collect);
	   
      return collect;
    }
    else {
      return res;
    }
  }


  /**
   *  Add a listener for localization changes.
   *  @param  localizable  listener for changes
   */
  protected void _addLocalizationChangeListener(Localizable localizable)
  {
    if (!localizables.contains(localizable)) {
      localizables.add(localizable);
      localizable.setLocale(_getDefaultLocale());
    }
  }

  /**
   *  Remove a listener for localization changes.
   *  @param  localizable  listener to be removed
   */
  protected void _removeLocalizationChangeListener(Localizable localizable)
  {
    localizables.remove(localizable);
  }

  /**
   *  Tell all registered localizables of localization changes.
   *  @param  locale  new locale
   */
  protected void _fireLocaleChanged(Locale locale)
  {
    for (Iterator iterator = localizables.iterator(); iterator.hasNext();) {
      ((Localizable)iterator.next()).setLocale(locale);
    }
  }
}




