/*
 * $Revision: 1.6 $ $Date: 2005/05/04 15:59:33 $
 * Copyright (C) 2004-2005 SUGIMOTO Ken-ichi
 * 作成日: 2004/10/11
 */

package feat.v1.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import feat.v1.Util;

public class ResourcesDeclaration {

    private boolean valid;
    /** リソースを保存するマップ。キーはResourceKey型、内容はString型。*/
    private Map _resourceMap;

    // JiBX
    private String lang;
    /** ResourceDeclarationのリスト */
    private ArrayList resources;

    public ResourcesDeclaration() {
        valid = false;
        _resourceMap = new HashMap();
    }

    public Locale getLang() {
        return Util.parseLocale(lang);
    }

    /**
     * すべてのリソースの名前の集合を返す。
     * 返されるStringの集合はComparableインタフェースでソートされる。
     * @return
     */
    public Set getReourceNames() {
        Set names = new TreeSet();
        Set keys = _resourceMap.keySet();
        int i = 0;
        for(Iterator it=keys.iterator(); it.hasNext(); ) {
            ResourceKey key = (ResourceKey)it.next();
            names.add(key.name);
        }
        return names;
    }

    synchronized public void addResources(ResourcesDeclaration rd) {
        _resourceMap.putAll(rd._resourceMap);
    }

    /**
     * リソース文字列を返す。
     * langに厳密にマッチするリソースを返す。
     * @param name リソース名
     * @param lang 言語名(nullでも良い)
     * @return String
     */
    public String getString(String name, Locale lang) {
        String ret = (String)_resourceMap.get(new ResourceKey(name, lang));
        return ret;
    }

    synchronized public void init() {
        if ( !valid ) {
            for(int i=0; i<resources.size(); i++) {
                ResourceDeclaration r = (ResourceDeclaration)resources.get(i);

                ResourceKey key = new ResourceKey(r.getName(), Util.parseLocale(r.getLang()));
                _resourceMap.put(key, r.getText());
            }
            valid = true;
        }
    }

    private class ResourceKey {
        String name;
        Locale lang;
        int hash;

        /**
         *
         * @param name
         * @param lang 言語。nullでも良い
         */
        ResourceKey(String name, Locale lang) {
            this.name = name;
            if ( lang == null )
                this.lang = Util.NULL_LOCALE;
            else
                this.lang = lang;
            this.hash = -1;
        }

        public boolean equals(Object o) {
            ResourceKey k = (ResourceKey)o;
            return name.equals(k.name) && lang.equals(k.lang);
        }

        public int hashCode() {
            if ( hash == -1 )
                hash = name.hashCode() ^ lang.hashCode();
            return hash;
        }
    }

}
