package com.anysoftkeyboard.keyboards;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.util.SparseIntArray;
import android.util.TypedValue;
import com.anysoftkeyboard.utils.Log;
import com.menny.android.anysoftkeyboard.AnyApplication;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class KeyboardSupport {
private static final String TAG = "KeyboardSupport";
public static int[] parseCSV(String value) {
int count = 0;
int lastIndex = 0;
if (value.length() > 0) {
count++;
while ((lastIndex = value.indexOf(",", lastIndex + 1)) > 0) {
count++;
}
}
int[] values = new int[count];
count = 0;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreTokens()) {
String nextToken = st.nextToken();
try {
// Issue 395
// default behavior
if (nextToken.length() != 1) {
values[count++] = Integer.parseInt(nextToken);
} else {
// length == 1, assume a char!
values[count++] = (int) nextToken.charAt(0);
}
} catch (NumberFormatException nfe) {
Log.e(TAG, "Error parsing keycodes " + value);
}
}
return values;
}
public static void updateDrawableBounds(Drawable icon) {
if (icon == null) return;
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
}
public static int[] getKeyCodesFromTypedArray(TypedArray typedArray, int index) {
TypedValue codesValue = new TypedValue();
typedArray.getValue(index, codesValue);
if (codesValue.type == TypedValue.TYPE_INT_DEC || codesValue.type == TypedValue.TYPE_INT_HEX) {
return new int[]{ codesValue.data };
} else if (codesValue.type == TypedValue.TYPE_STRING) {
return parseCSV(codesValue.string.toString());
} else {
return null;
}
}
/**
* Creates a mapping between the local styleable and the remote.
* @param localStyleableArray the local styleable to map against
* @param localContext local APK's Context
* @param remoteContext remote package's Context
* @param attributeIdMap a mapping between the remote-id -> local-id
* @return Always returns the remote version of localStyleableArray
*/
public static int[] createBackwardCompatibleStyleable(@NonNull int[] localStyleableArray, @NonNull Context localContext, @NonNull Context remoteContext, @NonNull SparseIntArray attributeIdMap) {
final String remotePackageName = remoteContext.getPackageName();
if (localContext.getPackageName().equals(remotePackageName)) {
Log.d(TAG, "This is a local context ("+remotePackageName+"), optimization will be done.");
//optimization
for(int attrId : localStyleableArray) {
attributeIdMap.put(attrId, attrId);
}
return localStyleableArray;
}
final Resources localRes = localContext.getResources();
final Resources remoteRes = remoteContext.getResources();
List<Integer> styleableIdList = new ArrayList<Integer>(localStyleableArray.length);
for(int attrId : localStyleableArray) {
final boolean isAndroidAttribute = localRes.getResourcePackageName(attrId).equals("android");
final int remoteAttrId;
if (isAndroidAttribute) {
//android attribute IDs are the same always. So, I can optimize.
remoteAttrId = attrId;
} else {
final String attributeName = localRes.getResourceEntryName(attrId);
remoteAttrId = remoteRes.getIdentifier(attributeName, "attr", remotePackageName);
Log.d(TAG, "attr "+attributeName+", local id "+attrId+", remote id "+remoteAttrId);
}
if (remoteAttrId != 0) {
attributeIdMap.put(remoteAttrId, attrId);
styleableIdList.add(remoteAttrId);
}
}
final int[] remoteMappedStyleable = new int[styleableIdList.size()];
for(int i=0; i<remoteMappedStyleable.length; i++) {
remoteMappedStyleable[i] = styleableIdList.get(i);
}
return remoteMappedStyleable;
}
public static int getKeyHeightFromHeightCode(KeyboardDimens keyboardDimens, int heightCode, int orientation) {
int height;
switch (heightCode) {
case 0:
height = 0;
break;
case -2:
height = keyboardDimens.getSmallKeyHeight();
break;
case -3:
height = keyboardDimens.getLargeKeyHeight();
break;
default:// -1
height = keyboardDimens.getNormalKeyHeight();
break;
}
if (orientation == Configuration.ORIENTATION_LANDSCAPE)
height = (int) (height * AnyApplication.getConfig()
.getKeysHeightFactorInLandscape());
else
height = (int) (height * AnyApplication.getConfig().getKeysHeightFactorInPortrait());
return height;
}
}