/**
 *******************************************************************************
 * Copyright (C) 2001-2002, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/ICULocaleService.java,v $
 * $Date: 2002/08/13 23:40:52 $
 * $Revision: 1.5 $
 *
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;


public class ICULocaleService extends ICUService {
    Locale fallbackLocale;
    String fallbackLocaleName;

    /**
     * Construct an ICULocaleService with a fallback locale string based on the current
     * default locale at the time of construction.
     */
    public ICULocaleService() {
	fallbackLocale = Locale.getDefault();
	fallbackLocaleName = LocaleUtility.canonicalLocaleString(fallbackLocale.toString());
    }

    /**
     * A subclass of Key that implements a locale fallback mechanism.
     * The first locale to search for is the locale provided by the
     * client, and the fallback locale to search for is the current default
     * locale.  This is instantiated by ICULocaleService.</p>
     *
     * <p>Canonicalization adjusts the locale string so that the
     * section before the first understore is in lower case, and the rest
     * is in upper case, with no trailing underscores.</p>
     */
    public static class LocaleKey extends ICUService.Key {
	private String primaryID;
	private String fallbackID;
	private String currentID;

	/**
	 * Convenience method for createWithCanonical that canonicalizes both the
	 * primary and fallback IDs first.
	 */
	public static LocaleKey create(String primaryID, String fallbackID) {
	    String canonicalPrimaryID = LocaleUtility.canonicalLocaleString(primaryID);
	    String canonicalFallbackID = LocaleUtility.canonicalLocaleString(fallbackID);
	    return new LocaleKey(primaryID, canonicalPrimaryID, canonicalFallbackID);
	}

	/**
	 * Convenience method for createWithCanonical that canonicalizes the
	 * primary ID first, the fallback is assumed to already be canonical.
	 */
	public static LocaleKey createWithCanonicalFallback(String primaryID, String canonicalFallbackID) {
	    String canonicalPrimaryID = LocaleUtility.canonicalLocaleString(primaryID);
	    return new LocaleKey(primaryID, canonicalPrimaryID, canonicalFallbackID);
	}

	/**
	 * Create a LocaleKey with canonical primary and fallback IDs.
	 */
	public static LocaleKey createWithCanonical(String canonicalPrimaryID, String canonicalFallbackID) {
	    return new LocaleKey(canonicalPrimaryID, canonicalPrimaryID, canonicalFallbackID);
	}
	    
	/**
	 * PrimaryID is the user's requested locale string,
	 * canonicalPrimaryID is this string in canonical form,
	 * fallbackID is the current default locale's string in
	 * canonical form.
	 */
        protected LocaleKey(String primaryID, String canonicalPrimaryID, String canonicalFallbackID) {
	    super(primaryID);
	    
	    if (canonicalPrimaryID == null) {
		this.primaryID = "";
	    } else {
		this.primaryID = canonicalPrimaryID;
	    }
	    if (this.primaryID == "") {
		this.fallbackID = null;
	    } else {
		if (canonicalFallbackID == null || this.primaryID.equals(canonicalFallbackID)) {
		    this.fallbackID = "";
		} else {
		    this.fallbackID = canonicalFallbackID;
		}
	    }

	    this.currentID = this.primaryID;
        }

	/**
	 * Return the (canonical) original ID.
	 */
	public String canonicalID() {
	    return primaryID;
	}

        /**
         * Return the (canonical) current ID.
         */
        public String currentID() {
	    return currentID;
        }

        /**
         * If the key has a fallback, modify the key and return true,
         * otherwise return false.</p>
	 *
	 * <p>First falls back through the primary ID, then through
	 * the fallbackID.  The final fallback is the empty string,
	 * unless the primary id was the empty string, in which case
	 * there is no fallback.  
	 */
        public boolean fallback() {
	    String current = currentID();
	    int x = current.lastIndexOf('_');
	    if (x != -1) {
		currentID = current.substring(0, x);
		return true;
	    }
	    if (fallbackID != null) {
		currentID = fallbackID;
		fallbackID = fallbackID.length() == 0 ? null : "";
		return true;
	    }
	    currentID = null;
	    return false;
        }
    }

    /**
     * This is a factory that handles multiple keys, and records
     * information about the keys it handles or doesn't handle.  This
     * allows it to quickly filter subsequent queries on keys it has
     * seen before.  Subclasses implement handleCreate instead of
     * create.  Before updateVisibleIDs is called, it keeps track of
     * keys that it doesn't handle.  If its ids are visible, once
     * updateVisibleIDs is called, it builds a set of all the keys it
     * does handle and keeps track of the keys it does handle.  
     */
    public static abstract class MultipleKeyFactory implements ICUService.Factory {
	protected final boolean visible;
	private SoftReference cacheref;
	private boolean included;

	/**
	 * Convenience overload of MultipleKeyFactory(boolean) that defaults
	 * visible to true.
	 */
	public MultipleKeyFactory() {
	    this(true);
	}

	/**
	 * Constructs a MultipleKeyFactory whose ids are visible iff visible is true.
	 */
	public MultipleKeyFactory(boolean visible) {
	    this.visible = visible;
	}

	/**
	 * Get the cache of IDs.  These are either the ids that we know we
	 * don't understand, if included is false, or the entire set of ids
	 * we do know we understand, if included is true.  Note that if
	 * the cache has been freed by gc, we reset the included flag, so
	 * it must not be tested before this method is called.
	 */
	private HashSet getCache() {
	    HashSet cache = null;
	    if (cacheref != null) {
		cache = (HashSet)cacheref.get();
	    }
	    if (cache == null) {
		cache = new HashSet();
		cacheref = new SoftReference(cache);
		included = false;
	    }
	    return cache;
	}

	/**
	 * Get the cache of IDs we understand.
	 */
	private HashSet getIncludedCache() {
	    HashSet cache = getCache();
	    if (!included) {
		cache.clear();
		handleUpdateVisibleIDs(cache);
		included = true;
	    }
	    return cache;
	}

	public final Object create(Key key) {
	    Object result = null;
	    String id = key.currentID();
	    HashSet cache = getCache();
	    if (cache.contains(id) == included) {
		result = handleCreate(key);
		if (!included && result == null) {
		    cache.add(id);
		}
	    }
	    return result;
	}

	public final void updateVisibleIDs(Map result) {
	    if (visible) {
		Set cache = getIncludedCache();
		Iterator iter = cache.iterator();
		while (iter.hasNext()) {
		    result.put((String)iter.next(), this);
		}
	    }
	}

	public final String getDisplayName(String id, Locale locale) {
	    if (visible) {
		Set cache = getIncludedCache();
		if (cache.contains(id)) {
		    return handleGetDisplayName(id, locale);
		}
	    }
	    return null;
	}

	/**
	 * Subclasses implement this instead of create.
	 */
	protected abstract Object handleCreate(Key key);

	/**
	 * Subclasses implement this instead of updateVisibleIDs.  Any
	 * id known to and handled by this class should be added to
	 * result.  
	 */
	protected abstract void handleUpdateVisibleIDs(Set result);

	/**
	 * Subclasses implement this instead of getDisplayName.
	 * Return the display name for the (visible) id in the
	 * provided locale.  The default implementation just returns
	 * the id.  
	 */
	protected String handleGetDisplayName(String id, Locale locale) {
	    return id;
	}
    }

    /**
     * A factory that creates a service based on the ICU locale data.
     * Subclasses specify a prefix (default is LocaleElements), a
     * semicolon-separated list of required resources, and a visible flag.
     * This factory will search the ICU locale data for a bundle with
     * the exact prefix.  Then it will test whether the required resources
     * are all in this exact bundle.  If so, it instantiates the full
     * resource bundle, and hands it to createServiceFromResource, which
     * subclasses must implement.  Otherwise it returns null.
     */
    public static class ICUResourceBundleFactory extends MultipleKeyFactory {
	protected final String name;
	protected final String[] requiredContents;

	/**
	 * A service factory based on ICU resource data in the LocaleElements resources.
	 */
	public ICUResourceBundleFactory(String requiredContents, boolean visible) {
	    this(ICULocaleData.LOCALE_ELEMENTS, requiredContents, visible);
	}

	/**
	 * A service factory based on ICU resource data in resources
	 * with the given name.  If requiredContents is not null, all
	 * listed resources must come directly from the same bundle.  
	 */
	public ICUResourceBundleFactory(String name, String requiredContents, boolean visible) {
	    super(visible);

	    this.name = name;
	    if (requiredContents != null) {
		ArrayList list = new ArrayList();
		for (int i = 0, len = requiredContents.length();;) {
		    while (i < len && requiredContents.charAt(i) == ';') {
			++i;
		    }
		    if (i == len) {
		      break;
		    }
		    int j = requiredContents.indexOf(';', i);
		    if (j == -1) {
		      j = len;
		    }
		    list.add(requiredContents.substring(i, j));
		    i = j;
		}
		this.requiredContents = (String[])list.toArray(new String[list.size()]);
	    } else {
		this.requiredContents = null;
	    }
	}

	/**
	 * Overrides parent handleCreate call.  Parent will filter out keys that it
	 * knows are not accepted by this factory before calling this method.
	 */
	protected Object handleCreate(Key key) {
	    Locale loc = LocaleUtility.getLocaleFromName(key.currentID());
	    if (acceptsLocale(loc)) {
		ResourceBundle bundle = ICULocaleData.getResourceBundle(name, loc); // full resource bundle tree lookup
		return createFromBundle(bundle, key);
	    }
	    return null;
	}

	/**
	 * Queries all the available locales in ICU and adds the names
	 * of those which it accepts to result.  This is quite
	 * time-consuming so we don't want to do it more than once if
	 * we have to.  This is only called if we are visible.  
	 */
	protected void handleUpdateVisibleIDs(Set result) {
	    Locale[] locales = ICULocaleData.getAvailableLocales(name);
	    for (int i = 0; i < locales.length; ++i) {
		Locale locale = locales[i];
		if (acceptsLocale(locale)) {
		    result.add(LocaleUtility.canonicalLocaleString(locale.toString()));
		}
	    }
	}

	/**
	 * Return a localized name for the locale represented by id.
	 */
	protected String handleGetDisplayName(String id, Locale locale) {
	    // use java's display name formatting for now
	    return LocaleUtility.getLocaleFromName(id).getDisplayName(locale);
	}

	/**
	 * We only accept the locale if there is a bundle for this exact locale and if
	 * all the required resources are directly in this bundle (none is from an
	 * inherited bundle);
	 */
	protected boolean acceptsLocale(Locale loc) {
	    try {
		ResourceBundle bundle = ICULocaleData.loadResourceBundle(name, loc); // single resource bundle lookup
		if (requiredContents != null) {
		    for (int i = 0; i < requiredContents.length; ++i) {
			if (bundle.getObject(requiredContents[i]) == null) {
			    return false;
			}
		    }
		}
		return true;
	    }
	    catch (Exception e) {
	    }
	    return false;
	}

	/**
	 * Subclassers implement this to create their service object based on the bundle and key.
	 * The default implementation just returns the bundle.
	 */
         protected Object createFromBundle(ResourceBundle bundle, Key key) {
	     return bundle;
         }
    }

    protected Key createKey(String id) {
	Locale loc = Locale.getDefault();
	if (loc != fallbackLocale) {
	    synchronized (this) {
		if (loc != fallbackLocale) {
		    fallbackLocale = loc;
		    fallbackLocaleName = LocaleUtility.canonicalLocaleString(loc.toString());
		    clearServiceCache();
		}
	    }
	}
	    
	return LocaleKey.createWithCanonicalFallback(id, fallbackLocaleName);
    }
}
