package chat.rocket.android.realm_helper;

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import io.realm.RealmObject;
import java.util.List;

public abstract class RealmModelListAdapter<T extends RealmObject, VM,
    VH extends RealmModelViewHolder<VM>> extends RecyclerView.Adapter<VH> {

  public interface Constructor<T extends RealmObject, VM, VH extends RealmModelViewHolder<VM>> {
    RealmModelListAdapter<T, VM, VH> getNewInstance(Context context);
  }

  protected final LayoutInflater inflater;
  private RealmListObserver<T> realmListObserver;
  private List<VM> adapterData;

  protected RealmModelListAdapter(Context context) {
    this.inflater = LayoutInflater.from(context);
  }

  /*package*/ RealmModelListAdapter<T, VM, VH> initializeWith(final RealmHelper realmHelper,
      RealmListObserver.Query<T> query) {
    realmListObserver = new RealmListObserver<>(realmHelper, query)
        .setOnUpdateListener(new RealmListObserver.OnUpdateListener<T>() {
          @Override public void onUpdateResults(List<T> results) {
            updateData(realmHelper.copyFromRealm(results));
          }
        });
    return this;
  }

  @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
    realmListObserver.sub();
  }

  @Override public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
    realmListObserver.unsub();
    super.onDetachedFromRecyclerView(recyclerView);
  }

  protected abstract int getRealmModelViewType(VM model);

  protected abstract @LayoutRes int getLayout(int viewType);

  protected abstract VH onCreateRealmModelViewHolder(int viewType, View itemView);

  protected abstract List<VM> mapResultsToViewModel(List<T> results);


  @Override public int getItemViewType(int position) {
    return getRealmModelViewType(getItem(position));
  }

  @Override public final VH onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = inflater.inflate(getLayout(viewType), parent, false);
    return onCreateRealmModelViewHolder(viewType, itemView);
  }

  @Override public void onBindViewHolder(VH holder, int position) {
    holder.bind(getItem(position));
  }

  @Override public int getItemCount() {
    return adapterData != null ? adapterData.size() : 0;
  }

  private VM getItem(int position) {
    return adapterData.get(position);
  }

  private void updateData(List<T> newData) {
    if (adapterData == null) {
      adapterData = mapResultsToViewModel(newData);
      notifyDataSetChanged();
    } else {
      // TODO: use DillUtils!
      adapterData = mapResultsToViewModel(newData);
      notifyDataSetChanged();
    }
  }
}

@@ -618,32 +618,114 @@
  context);%0A  %7D%0A%0A
+  public interface OnItemClickListener%3CVM%3E %7B%0A    void onItemClick(VM model);%0A  %7D%0A%0A
   protected fina
@@ -832,16 +832,71 @@
 terData;
+%0A  private OnItemClickListener%3CVM%3E onItemClickListener;
 %0A%0A  prot
@@ -2465,37 +2465,391 @@
     
-holder.bind(getItem(position)
+VM model = getItem(position);%0A    holder.itemView.setTag(model);%0A    holder.itemView.setOnClickListener(new View.OnClickListener() %7B%0A      @Override public void onClick(View view) %7B%0A        VM model2 = (VM) (view.getTag());%0A        if (model2 != null && onItemClickListener != null) %7B%0A          onItemClickListener.onItemClick(model2);%0A        %7D%0A      %7D%0A    %7D);%0A    holder.bind(model
 );%0A 
@@ -3313,24 +3313,24 @@
 tChanged();%0A
-
     %7D%0A  %7D%0A%7D%0A
@@ -3326,11 +3326,152 @@
    %7D%0A  %7D
+%0A%0A  public void setOnItemClickListener(OnItemClickListener%3CVM%3E onItemClickListener) %7B%0A    this.onItemClickListener = onItemClickListener;%0A  %7D
 %0A%7D%0A

add listener