package net.gotev.recycleradapter;

import android.os.Bundle;
import android.view.View;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;

/**
 * Abstract class to extend to create ViewHolders.
 * @author Aleksandar Gotev
 * @param <T> ViewHolder subclass
 */
public abstract class AdapterItem<T extends RecyclerAdapterViewHolder> {

    /**
     * Gets called by {@link RecyclerAdapter#sendEvent(RecyclerAdapterViewHolder, Bundle)}
     * @param position position at which the event happened
     * @param data additional click data
     * @return true if the view must be rebinded after this method returns (e.g. you updated some
     *         data in the model and you want to display it), otherwise false (e.g. if you are
     *         simply handling a click which does not involve data changes)
     */
    public boolean onEvent(int position, Bundle data) {
        return false;
    }

    /**
     * Gets called for every item when the {@link RecyclerAdapter#filter(String)} method gets called.
     * @param searchTerm term to search for
     * @return true if the items matches the search term, false otherwise
     */
    public boolean onFilter(final String searchTerm) {
        return true;
    }

    /**
     * Creates a new ViewHolder instance, by inferring the ViewHolder type from the generic passed
     * to this class
     * @param view View to be passed to the ViewHolder
     * @param adapter {@link RecyclerAdapter} instance
     * @return ViewHolder
     * @throws NoSuchMethodException if no mathing constructor are found in the ViewHolder subclass
     * @throws InstantiationException if an error happens during instantiation of the ViewHolder subclass
     * @throws InvocationTargetException if an error happens during a method invocation of the ViewHolder subclass
     * @throws IllegalAccessException if a method, field or class has been declared with insufficient access control modifiers
     */
    @SuppressWarnings("unchecked")
    T getViewHolder(View view, RecyclerAdapterNotifier adapter)
            throws NoSuchMethodException, InstantiationException,
            InvocationTargetException, IllegalAccessException {

        // find the class of the generic type passed, to be able to get a new instance
        // it it less performant than passing Class<T> directly in the costructor, but avoids
        // writing additional code, making the subclasses stay lighter
        Class<T> clazz = (Class<T>) ((ParameterizedType)getClass()
                .getGenericSuperclass())
                .getActualTypeArguments()[0];

        return clazz.getConstructor(View.class, RecyclerAdapterNotifier.class)
                .newInstance(view, adapter);
    }

    /**
     * Returns the layout ID for this item
     * @return layout ID
     */
    public abstract int getLayoutId();

    /**
     * Bind the current item with the view
     * @param holder ViewHolder on which to bind data
     */
    protected abstract void bind(T holder);
}

@@ -55,16 +55,41 @@
 Bundle;%0A
+import android.util.Log;%0A
 import a
@@ -162,52 +162,8 @@
 ion;
-%0Aimport java.lang.reflect.ParameterizedType;
 %0A%0A/*
@@ -2201,404 +2201,532 @@
  // 
-find the class of the generic type passed, to be able to get a new instance%0A        // it it less performant than passing Class%3CT%3E directly in the costructor, but avoids%0A        // writing additional code, making the subclasses stay lighter%0A        Class%3CT%3E clazz = (Class%3CT%3E) ((ParameterizedType)getClass()%0A                .getGenericSup
+analyze all the public classes and interfaces that are members of the class represented%0A        // by this Class object and search for the first RecyclerAdapterViewHolder%0A        // implementation. This should also work if RecyclerAdapterViewHolder subclass%0A        // hierarchy is present, as the first one should be the last of the subclasses%0A        for (Class cl : getClass().getClasses()) %7B%0A            if (RecyclerAdapterViewHold
 er
+.
 class
-())%0A                .getActualTypeArguments()%5B0%5D;%0A%0A
+.isAssignableFrom(cl)) %7B%0A                Class%3CT%3E clazz = (Class%3CT%3E) cl;%0A        
     
@@ -2816,16 +2816,24 @@
         
+        
 .newInst
@@ -2853,16 +2853,145 @@
 apter);%0A
+            %7D%0A        %7D%0A%0A        Log.e(getClass().getSimpleName(), %22No ViewHolder implementation found!%22);%0A        return null;%0A%0A
     %7D%0A%0A 

improve view holder implementation detection in the subclass hierarchy. To be tested.