content: /*
   * Copyright (C) 2011 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.amnesica.kryptey.inputmethod.keyboard.internal;
  
  import android.content.res.Resources;
  import android.content.res.TypedArray;
  import android.graphics.drawable.Drawable;
  import android.util.Log;
  import android.util.SparseIntArray;
  
  import com.amnesica.kryptey.inputmethod.R;
  
  import java.util.HashMap;
  
  public final class KeyboardIconsSet {
    private static final String TAG = KeyboardIconsSet.class.getSimpleName();
  
    public static final String PREFIX_ICON = "!icon/";
    public static final int ICON_UNDEFINED = 0;
    private static final int ATTR_UNDEFINED = 0;
  
    private static final String NAME_UNDEFINED = "undefined";
    public static final String NAME_SHIFT_KEY = "shift_key";
    public static final String NAME_SHIFT_KEY_SHIFTED = "shift_key_shifted";
    public static final String NAME_DELETE_KEY = "delete_key";
    public static final String NAME_SETTINGS_KEY = "settings_key";
    public static final String NAME_SPACE_KEY = "space_key";
    public static final String NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout";
    public static final String NAME_ENTER_KEY = "enter_key";
    public static final String NAME_GO_KEY = "go_key";
    public static final String NAME_SEARCH_KEY = "search_key";
    public static final String NAME_SEND_KEY = "send_key";
    public static final String NAME_NEXT_KEY = "next_key";
    public static final String NAME_DONE_KEY = "done_key";
    public static final String NAME_PREVIOUS_KEY = "previous_key";
    public static final String NAME_TAB_KEY = "tab_key";
    public static final String NAME_LANGUAGE_SWITCH_KEY = "language_switch_key";
    public static final String NAME_ZWNJ_KEY = "zwnj_key";
    public static final String NAME_ZWJ_KEY = "zwj_key";
  
    private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray();
  
    // Icon name to icon id map.
    private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<>();
  
    private static final Object[] NAMES_AND_ATTR_IDS = {
        NAME_UNDEFINED, ATTR_UNDEFINED,
        NAME_SHIFT_KEY, R.styleable.Keyboard_iconShiftKey,
        NAME_DELETE_KEY, R.styleable.Keyboard_iconDeleteKey,
        NAME_SETTINGS_KEY, R.styleable.Keyboard_iconSettingsKey,
        NAME_SPACE_KEY, R.styleable.Keyboard_iconSpaceKey,
        NAME_ENTER_KEY, R.styleable.Keyboard_iconEnterKey,
        NAME_GO_KEY, R.styleable.Keyboard_iconGoKey,
        NAME_SEARCH_KEY, R.styleable.Keyboard_iconSearchKey,
        NAME_SEND_KEY, R.styleable.Keyboard_iconSendKey,
        NAME_NEXT_KEY, R.styleable.Keyboard_iconNextKey,
        NAME_DONE_KEY, R.styleable.Keyboard_iconDoneKey,
        NAME_PREVIOUS_KEY, R.styleable.Keyboard_iconPreviousKey,
        NAME_TAB_KEY, R.styleable.Keyboard_iconTabKey,
        NAME_SPACE_KEY_FOR_NUMBER_LAYOUT, R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
        NAME_SHIFT_KEY_SHIFTED, R.styleable.Keyboard_iconShiftKeyShifted,
        NAME_LANGUAGE_SWITCH_KEY, R.styleable.Keyboard_iconLanguageSwitchKey,
        NAME_ZWNJ_KEY, R.styleable.Keyboard_iconZwnjKey,
        NAME_ZWJ_KEY, R.styleable.Keyboard_iconZwjKey,
    };
  
    private static final int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
    private static final String[] ICON_NAMES = new String[NUM_ICONS];
    private final Drawable[] mIcons = new Drawable[NUM_ICONS];
    private final int[] mIconResourceIds = new int[NUM_ICONS];
  
    static {
      int iconId = ICON_UNDEFINED;
      for (int i = 0; i < NAMES_AND_ATTR_IDS.length; i += 2) {
        final String name = (String) NAMES_AND_ATTR_IDS[i];
        final Integer attrId = (Integer) NAMES_AND_ATTR_IDS[i + 1];
        if (attrId != ATTR_UNDEFINED) {
          ATTR_ID_TO_ICON_ID.put(attrId, iconId);
        }
        sNameToIdsMap.put(name, iconId);
        ICON_NAMES[iconId] = name;
        iconId++;
      }
    }
  
    public void loadIcons(final TypedArray keyboardAttrs) {
      final int size = ATTR_ID_TO_ICON_ID.size();
      for (int index = 0; index < size; index++) {
        final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index);
        try {
          final Drawable icon = keyboardAttrs.getDrawable(attrId);
          setDefaultBounds(icon);
          final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
          mIcons[iconId] = icon;
          mIconResourceIds[iconId] = keyboardAttrs.getResourceId(attrId, 0);
        } catch (Resources.NotFoundException e) {
          Log.w(TAG, "Drawable resource for icon #"
              + keyboardAttrs.getResources().getResourceEntryName(attrId)
              + " not found");
        }
      }
    }
  
    private static boolean isValidIconId(final int iconId) {
      return iconId >= 0 && iconId < ICON_NAMES.length;
    }
  
    public static String getIconName(final int iconId) {
      return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
    }
  
    public static int getIconId(final String name) {
      Integer iconId = sNameToIdsMap.get(name);
      if (iconId != null) {
        return iconId;
      }
      throw new RuntimeException("unknown icon name: " + name);
    }
  
    public Drawable getIconDrawable(final int iconId) {
      if (isValidIconId(iconId)) {
        return mIcons[iconId];
      }
      throw new RuntimeException("unknown icon id: " + getIconName(iconId));
    }
  
    private static void setDefaultBounds(final Drawable icon) {
      if (icon != null) {
        icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
      }
    }
  }
  