package trikita.anvil;
import android.view.View;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
final class PropertySetter implements Anvil.AttributeSetter {
private final Map<Class, Class> WRAP = new HashMap<Class, Class>() {{
put(int.class, Integer.class);
put(long.class, Long.class);
put(double.class, Double.class);
put(float.class, Float.class);
put(boolean.class, Boolean.class);
put(char.class, Character.class);
put(byte.class, Byte.class);
put(void.class, Void.class);
put(short.class, Short.class);
put(Integer.class, int.class);
put(Long.class, long.class);
put(Double.class, double.class);
put(Float.class, float.class);
put(Boolean.class, boolean.class);
put(Character.class, char.class);
put(Byte.class, byte.class);
put(Void.class, void.class);
put(Short.class, short.class);
}};
private boolean assignable(Class<?> a, Class<?> b) {
if (a == null) {
return false;
}
if (b == null) {
return !(a.isPrimitive());
}
if (b.isPrimitive() && !a.isPrimitive()) {
b = WRAP.get(b);
if (b == null) {
return false;
}
}
if (a.isPrimitive() && !b.isPrimitive()) {
b = WRAP.get(b);
if (b == null) {
return false;
}
}
if (b.equals(a)) {
return true;
}
if (b.isPrimitive()) {
if (a.isPrimitive() == false) {
return false;
}
if (Integer.TYPE.equals(b)) {
return Long.TYPE.equals(a) || Float.TYPE.equals(a) || Double.TYPE.equals(a);
}
if (Long.TYPE.equals(b)) {
return Float.TYPE.equals(a) || Double.TYPE.equals(a);
}
if (Boolean.TYPE.equals(b)) {
return false;
}
if (Double.TYPE.equals(b)) {
return false;
}
if (Float.TYPE.equals(b)) {
return Double.TYPE.equals(a);
}
if (Character.TYPE.equals(b)) {
return Integer.TYPE.equals(a) || Long.TYPE.equals(a) ||
Float.TYPE.equals(a) || Double.TYPE.equals(a);
}
if (Short.TYPE.equals(b)) {
return Integer.TYPE.equals(a) || Long.TYPE.equals(a) ||
Float.TYPE.equals(a) || Double.TYPE.equals(a);
}
if (Byte.TYPE.equals(b)) {
return Short.TYPE.equals(a) || Integer.TYPE.equals(a) ||
Long.TYPE.equals(a) || Float.TYPE.equals(a) ||
Double.TYPE.equals(a);
}
return false;
}
return a.isAssignableFrom(b);
}
@Override
public boolean set(View v, String name, Object value, Object prevValue) {
name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
String setter = "set" + name;
String listener = "set" + name + "Listener";
Class<?> cls = v.getClass();
while (cls != null) {
try {
for (Method m : cls.getDeclaredMethods()) {
if ((m.getName().equals(setter) || m.getName().equals(listener)) &&
m.getParameterTypes().length == 1) {
Class arg = m.getParameterTypes()[0];
if ((value == null && !arg.isPrimitive()) || (value != null && assignable(arg, value.getClass()))) {
m.invoke(v, value);
return true;
}
}
}
cls = cls.getSuperclass();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return false;
}
}