package com.ftinc.scoop; import android.app.Activity; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.util.Log; import android.util.SparseArray; import android.view.View; import android.view.animation.Interpolator; import com.ftinc.scoop.binding.IBinding; import com.ftinc.scoop.binding.StatusBarBinding; import com.ftinc.scoop.binding.ViewBinding; import com.ftinc.scoop.adapters.ColorAdapter; import com.ftinc.scoop.internal.ToppingBinder; import com.ftinc.scoop.util.BindingUtils; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * This class is not deprecated, please use {@link Scoop} class to bind everything * * Package: com.ftinc.scoop * Created by drew.heavner on 6/17/16. */ @Deprecated public class SugarCone { private static final String TAG = "SugarCone"; static final Map<Class<?>, ToppingBinder<Object>> BINDERS = new LinkedHashMap<>(); static final ToppingBinder<Object> NOP_VIEW_BINDER = new ToppingBinder<Object>() { @Override public List<IBinding> bind(Object target) { return new ArrayList<>(); } }; /*********************************************************************************************** * * Variables * */ private SparseArray<Topping> mToppings = new SparseArray<>(); private HashMap<Class, Set<IBinding>> mBindings = new HashMap<>(); private static boolean debug = false; /*********************************************************************************************** * * Api Methods * */ public void bind(Activity activity){ List<IBinding> bindings = getViewBinder(activity).bind(activity); // add to system Set<IBinding> _bindings = getBindings(activity.getClass()); _bindings.addAll(bindings); } public SugarCone bind(Object obj, int toppingId, View view){ return bind(obj, toppingId, view, null); } public SugarCone bind(Object obj, int toppingId, View view, @Nullable ColorAdapter colorAdapter){ return bind(obj, toppingId, view, colorAdapter, null); } public SugarCone bind(Object obj, int toppingId, View view, @Nullable ColorAdapter colorAdapter, @Nullable Interpolator interpolator){ // Get a default color adapter if not supplied if(colorAdapter == null){ colorAdapter = BindingUtils.getColorAdapter(view.getClass()); } // Generate Binding IBinding binding = new ViewBinding(toppingId, view, colorAdapter, interpolator); // Bind return bind(obj, toppingId, binding); } public SugarCone bindStatusBar(Activity activity, int toppingId){ return bindStatusBar(activity, toppingId, null); } public SugarCone bindStatusBar(Activity activity, int toppingId, @Nullable Interpolator interpolator){ IBinding binding = new StatusBarBinding(toppingId, activity, interpolator); return bind(activity, toppingId, binding); } public SugarCone bind(Object obj, int toppingId, IBinding binding){ // Find Topping Topping topping = mToppings.get(toppingId); if(topping != null){ // Store binding Set<IBinding> bindings = getBindings(obj.getClass()); bindings.add(binding); return this; }else{ throw new InvalidParameterException("No Topping for the given id (" + toppingId + ") was found."); } } public void unbind(Object obj){ Set<IBinding> bindings = getBindings(obj.getClass()); for (IBinding binding : bindings) { binding.unbind(); } // Clear the bindings out of the map mBindings.remove(obj.getClass()); } public SugarCone update(int toppingId, @ColorInt int color){ // Get the topping Topping topping = mToppings.get(toppingId); if(topping != null){ topping.updateColor(color); // Update bindings Collection<Set<IBinding>> bindings = mBindings.values(); for (Set<IBinding> bindingSet : bindings) { for (IBinding binding : bindingSet) { if(binding.getToppingId() == toppingId) { binding.update(topping); } } } }else{ throw new InvalidParameterException("No Topping for the given id (" + toppingId + ") was found."); } return this; } /*********************************************************************************************** * * Helper Methods * */ @NonNull @UiThread static ToppingBinder<Object> getViewBinder(@NonNull Object target) { Class<?> targetClass = target.getClass(); if (debug) Log.d(TAG, "Looking up topping binder for " + targetClass.getName()); return findViewBinderForClass(targetClass); } @NonNull @UiThread private static ToppingBinder<Object> findViewBinderForClass(Class<?> cls) { ToppingBinder<Object> viewBinder = BINDERS.get(cls); if (viewBinder != null) { if (debug) Log.d(TAG, "HIT: Cached in topping binder map."); return viewBinder; } String clsName = cls.getName(); if (clsName.startsWith("android.") || clsName.startsWith("java.")) { if (debug) Log.d(TAG, "MISS: Reached framework class. Abandoning search."); return NOP_VIEW_BINDER; } //noinspection TryWithIdenticalCatches Resolves to API 19+ only type. try { Class<?> viewBindingClass = Class.forName(clsName + "_ToppingBinder"); //noinspection unchecked viewBinder = (ToppingBinder<Object>) viewBindingClass.newInstance(); if (debug) Log.d(TAG, "HIT: Loaded topping binder class."); } catch (ClassNotFoundException e) { if (debug) Log.d(TAG, "Not found. Trying superclass " + cls.getSuperclass().getName()); viewBinder = findViewBinderForClass(cls.getSuperclass()); } catch (InstantiationException e) { throw new RuntimeException("Unable to create topping binder for " + clsName, e); } catch (IllegalAccessException e) { throw new RuntimeException("Unable to create topping binder for " + clsName, e); } BINDERS.put(cls, viewBinder); return viewBinder; } Set<IBinding> getBindings(Class clazz){ Set<IBinding> bindings = mBindings.get(clazz); if(bindings == null){ bindings = new HashSet<>(); mBindings.put(clazz, bindings); } return bindings; } public SugarCone addTopping(Topping... topping) { return addToppings(Arrays.asList(topping)); } public SugarCone addToppings(Collection<Topping> toppings){ for (Topping topping : toppings) { mToppings.put(topping.getId(), topping); } return this; } public SparseArray<Topping> getToppings(){ return mToppings; } }