package com.actionbarsherlock.internal.nineoldandroids.animation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import android.util.Log;
String mPropertyName;
Method mSetter = null;
private Method mGetter = null;
Class mValueType;
KeyframeSet mKeyframeSet = null;
private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class,
Double.class, Integer.class};
private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class,
Float.class, Double.class};
private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class,
Float.class, Integer.class};
private static final HashMap<Class, HashMap<String, Method>> sSetterPropertyMap =
new HashMap<Class, HashMap<String, Method>>();
private static final HashMap<Class, HashMap<String, Method>> sGetterPropertyMap =
new HashMap<Class, HashMap<String, Method>>();
final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock();
final Object[] mTmpValueArray = new Object[1];
private TypeEvaluator mEvaluator;
private Object mAnimatedValue;
mPropertyName = propertyName;
}
public static PropertyValuesHolder
ofInt(String propertyName,
int... values) {
return new IntPropertyValuesHolder(propertyName, values);
}
public static PropertyValuesHolder
ofFloat(String propertyName,
float... values) {
return new FloatPropertyValuesHolder(propertyName, values);
}
public static PropertyValuesHolder
ofObject(String propertyName, TypeEvaluator evaluator,
Object... values) {
PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
pvh.setObjectValues(values);
pvh.setEvaluator(evaluator);
return pvh;
}
public static PropertyValuesHolder
ofKeyframe(String propertyName, Keyframe... values) {
KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
if (keyframeSet instanceof IntKeyframeSet) {
return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet);
} else if (keyframeSet instanceof FloatKeyframeSet) {
return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet);
}
else {
PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
pvh.mKeyframeSet = keyframeSet;
pvh.mValueType = ((Keyframe)values[0]).getType();
return pvh;
}
}
mValueType = int.class;
mKeyframeSet = KeyframeSet.ofInt(values);
}
mValueType = float.class;
mKeyframeSet = KeyframeSet.ofFloat(values);
}
int numKeyframes = values.length;
Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
mValueType = ((Keyframe)values[0]).getType();
for (int i = 0; i < numKeyframes; ++i) {
keyframes[i] = (Keyframe)values[i];
}
mKeyframeSet = new KeyframeSet(keyframes);
}
mValueType = values[0].getClass();
mKeyframeSet = KeyframeSet.ofObject(values);
}
Method returnVal = null;
String methodName = getMethodName(prefix, mPropertyName);
Class args[] = null;
if (valueType == null) {
try {
returnVal = targetClass.getMethod(methodName, args);
} catch (NoSuchMethodException e) {
Log.e("PropertyValuesHolder", targetClass.getSimpleName() + " - " +
"Couldn't find no-arg method for property " + mPropertyName + ": " + e);
}
} else {
args = new Class[1];
Class typeVariants[];
if (mValueType.equals(Float.class)) {
typeVariants = FLOAT_VARIANTS;
} else if (mValueType.equals(Integer.class)) {
typeVariants = INTEGER_VARIANTS;
} else if (mValueType.equals(Double.class)) {
typeVariants = DOUBLE_VARIANTS;
} else {
typeVariants = new Class[1];
typeVariants[0] = mValueType;
}
for (Class typeVariant : typeVariants) {
args[0] = typeVariant;
try {
returnVal = targetClass.getMethod(methodName, args);
mValueType = typeVariant;
return returnVal;
} catch (NoSuchMethodException e) {
}
}
Log.e("PropertyValuesHolder",
"Couldn't find " + prefix + "ter property " + mPropertyName +
" for " + targetClass.getSimpleName() +
" with value type "+ mValueType);
}
return returnVal;
}
HashMap<Class, HashMap<String, Method>> propertyMapMap,
String prefix, Class valueType) {
Method setterOrGetter = null;
try {
mPropertyMapLock.writeLock().lock();
HashMap<String, Method> propertyMap = propertyMapMap.get(targetClass);
if (propertyMap != null) {
setterOrGetter = propertyMap.get(mPropertyName);
}
if (setterOrGetter == null) {
setterOrGetter = getPropertyFunction(targetClass, prefix, valueType);
if (propertyMap == null) {
propertyMap = new HashMap<String, Method>();
propertyMapMap.put(targetClass, propertyMap);
}
propertyMap.put(mPropertyName, setterOrGetter);
}
} finally {
mPropertyMapLock.writeLock().unlock();
}
return setterOrGetter;
}
mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
}
mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null);
}
Class targetClass = target.getClass();
if (mSetter == null) {
setupSetter(targetClass);
}
for (Keyframe kf : mKeyframeSet.mKeyframes) {
if (!kf.hasValue()) {
if (mGetter == null) {
setupGetter(targetClass);
}
try {
kf.setValue(mGetter.invoke(target));
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
}
}
private void setupValue(Object target, Keyframe kf) {
try {
if (mGetter == null) {
Class targetClass = target.getClass();
setupGetter(targetClass);
}
kf.setValue(mGetter.invoke(target));
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
setupValue(target, mKeyframeSet.mKeyframes.get(0));
}
setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1));
}
@Override
public PropertyValuesHolder
clone() {
try {
PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone();
newPVH.mPropertyName = mPropertyName;
newPVH.mKeyframeSet = mKeyframeSet.clone();
newPVH.mEvaluator = mEvaluator;
return newPVH;
} catch (CloneNotSupportedException e) {
return null;
}
}
if (mSetter != null) {
try {
mTmpValueArray[0] = getAnimatedValue();
mSetter.invoke(target, mTmpValueArray);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
}
if (mEvaluator == null) {
mEvaluator = (mValueType == Integer.class) ? sIntEvaluator :
(mValueType == Float.class) ? sFloatEvaluator :
null;
}
if (mEvaluator != null) {
mKeyframeSet.setEvaluator(mEvaluator);
}
}
mEvaluator = evaluator;
mKeyframeSet.setEvaluator(evaluator);
}
mAnimatedValue = mKeyframeSet.getValue(fraction);
}
mPropertyName = propertyName;
}
return mPropertyName;
}
return mAnimatedValue;
}
@Override
return mPropertyName + ": " + mKeyframeSet.toString();
}
static String
getMethodName(String prefix, String propertyName) {
if (propertyName == null || propertyName.length() == 0) {
return prefix;
}
char firstLetter = Character.toUpperCase(propertyName.charAt(0));
String theRest = propertyName.substring(1);
return prefix + firstLetter + theRest;
}
IntKeyframeSet mIntKeyframeSet;
int mIntAnimatedValue;
super(propertyName);
mValueType = int.class;
mKeyframeSet = keyframeSet;
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
super(propertyName);
setIntValues(values);
}
@Override
super.setIntValues(values);
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
@Override
mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction);
}
@Override
return mIntAnimatedValue;
}
@Override
public IntPropertyValuesHolder
clone() {
IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone();
newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet;
return newPVH;
}
@Override
if (mSetter != null) {
try {
mTmpValueArray[0] = mIntAnimatedValue;
mSetter.invoke(target, mTmpValueArray);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
}
@Override
super.setupSetter(targetClass);
}
}
FloatKeyframeSet mFloatKeyframeSet;
float mFloatAnimatedValue;
super(propertyName);
mValueType = float.class;
mKeyframeSet = keyframeSet;
mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
}
super(propertyName);
setFloatValues(values);
}
@Override
super.setFloatValues(values);
mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
}
@Override
mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction);
}
@Override
return mFloatAnimatedValue;
}
@Override
public FloatPropertyValuesHolder
clone() {
FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone();
newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet;
return newPVH;
}
@Override
if (mSetter != null) {
try {
mTmpValueArray[0] = mFloatAnimatedValue;
mSetter.invoke(target, mTmpValueArray);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
}
@Override
super.setupSetter(targetClass);
}
}
}