/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.inputmethod.keyboard.internal;

import java.util.HashMap;
import java.util.Locale;

/**
 * !!!!! DO NOT EDIT THIS FILE !!!!!
 *
 * This file is generated by tools/make-keyboard-text. The base template file is
 *   tools/make-keyboard-text/res/src/com/android/inputmethod/keyboard/internal/
 *   KeyboardTextsTable.tmpl
 *
 * This file must be updated when any text resources in keyboard layout files have been changed.
 * These text resources are referred as "!text/<resource_name>" in keyboard XML definitions,
 * and should be defined in
 *   tools/make-keyboard-text/res/values-<locale>/donottranslate-more-keys.xml
 *
 * To update this file, please run the following commands.
 *   $ cd $ANDROID_BUILD_TOP
 *   $ mmm packages/inputmethods/LatinIME/tools/make-keyboard-text
 *   $ make-keyboard-text -java packages/inputmethods/LatinIME/java
 *
 * The updated source file will be generated to the following path (this file).
 *   packages/inputmethods/LatinIME/java/src/com/android/inputmethod/keyboard/internal/
 *   KeyboardTextsTable.java
 */
public final class KeyboardTextsTable {
    // Name to index map.
    private static final HashMap<String, Integer> sNameToIndexesMap = new HashMap<>();
    // Locale to texts table map.
    private static final HashMap<String, String[]> sLocaleToTextsTableMap = new HashMap<>();
    // TODO: Remove this variable after debugging.
    // Texts table to locale maps.
    private static final HashMap<String[], String> sTextsTableToLocaleMap = new HashMap<>();

    public static String getText(final String name, final String[] textsTable) {
        final Integer indexObj = sNameToIndexesMap.get(name);
        if (indexObj == null) {
            throw new RuntimeException("Unknown text name=" + name + " locale="
                    + sTextsTableToLocaleMap.get(textsTable));
        }
        final int index = indexObj;
        final String text = (index < textsTable.length) ? textsTable[index] : null;
        if (text != null) {
            return text;
        }
        // Validity check.
        if (index >= 0 && index < TEXTS_DEFAULT.length) {
            return TEXTS_DEFAULT[index];
        }
        // Throw exception for debugging purpose.
        throw new RuntimeException("Illegal index=" + index + " for name=" + name
                + " locale=" + sTextsTableToLocaleMap.get(textsTable));
    }

    public static String[] getTextsTable(final Locale locale) {
        final String localeKey = locale.toString();
        if (sLocaleToTextsTableMap.containsKey(localeKey)) {
            return sLocaleToTextsTableMap.get(localeKey);
        }
        final String languageKey = locale.getLanguage();
        if (sLocaleToTextsTableMap.containsKey(languageKey)) {
            return sLocaleToTextsTableMap.get(languageKey);
        }
        return TEXTS_DEFAULT;
    }

    private static final String[] NAMES = {
    //  /* index:histogram */ "name",
        /* @NAMES@ */
    };

    private static final String EMPTY = "";

    /* Default texts */
    private static final String[] TEXTS_DEFAULT = {
        /* @DEFAULT_TEXTS@ */
    };

    /* @TEXTS@ */
    private static final Object[] LOCALES_AND_TEXTS = {
    // "locale", TEXT_ARRAY,  /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
        /* @LOCALES_AND_TEXTS@ */
    };

    static {
        for (int index = 0; index < NAMES.length; index++) {
            sNameToIndexesMap.put(NAMES[index], index);
        }

        for (int i = 0; i < LOCALES_AND_TEXTS.length; i += 2) {
            final String locale = (String)LOCALES_AND_TEXTS[i];
            final String[] textsTable = (String[])LOCALES_AND_TEXTS[i + 1];
            sLocaleToTextsTableMap.put(locale, textsTable);
            sTextsTableToLocaleMap.put(textsTable, locale);
        }
    }
}
