content: package de.danoeh.antennapod.ui.screen.drawer;
  
  import android.app.Activity;
  import android.content.SharedPreferences;
  import android.os.Build;
  import android.view.ContextMenu;
  import android.view.InputDevice;
  import android.view.LayoutInflater;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ImageView;
  import android.widget.LinearLayout;
  import android.widget.TextView;
  import androidx.annotation.NonNull;
  import androidx.annotation.StringRes;
  import androidx.preference.PreferenceManager;
  import androidx.recyclerview.widget.RecyclerView;
  import com.bumptech.glide.Glide;
  import com.bumptech.glide.load.resource.bitmap.FitCenter;
  import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
  import com.bumptech.glide.request.RequestOptions;
  import de.danoeh.antennapod.R;
  import de.danoeh.antennapod.model.feed.Feed;
  import de.danoeh.antennapod.storage.database.NavDrawerData;
  import de.danoeh.antennapod.storage.preferences.UserPreferences;
  import de.danoeh.antennapod.ui.common.ImagePlaceholder;
  import de.danoeh.antennapod.ui.screen.InboxFragment;
  import de.danoeh.antennapod.ui.screen.queue.QueueFragment;
  import de.danoeh.antennapod.ui.screen.subscriptions.SubscriptionFragment;
  
  import java.lang.ref.WeakReference;
  import java.text.NumberFormat;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  /**
   * BaseAdapter for the navigation drawer
   */
  public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
          implements SharedPreferences.OnSharedPreferenceChangeListener {
  
      public static final int VIEW_TYPE_NAV = 0;
      public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
      private static final int VIEW_TYPE_SUBSCRIPTION = 2;
  
      /**
       * a tag used as a placeholder to indicate if the subscription list should be displayed or not
       * This tag doesn't correspond to any specific activity.
       */
      public static final String SUBSCRIPTION_LIST_TAG = "SubscriptionList";
  
      private final List<String> fragmentTags = new ArrayList<>();
      private final ItemAccess itemAccess;
      private final WeakReference<Activity> activity;
      public boolean showSubscriptionList = true;
  
      public NavListAdapter(ItemAccess itemAccess, Activity context) {
          this.itemAccess = itemAccess;
          this.activity = new WeakReference<>(context);
          loadItems();
          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
          prefs.registerOnSharedPreferenceChangeListener(this);
      }
  
      public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
          if (UserPreferences.PREF_HIDDEN_DRAWER_ITEMS.equals(key)
                  || UserPreferences.PREF_DRAWER_ITEM_ORDER.equals(key)) {
              loadItems();
          }
      }
  
      private void loadItems() {
          List<String> newTags = UserPreferences.getVisibleDrawerItemOrder();
  
          if (newTags.contains(SUBSCRIPTION_LIST_TAG)) {
              // we never want SUBSCRIPTION_LIST_TAG to be in 'tags'
              // since it doesn't actually correspond to a position in the list, but is
              // a placeholder that indicates if we should show the subscription list in the
              // nav drawer at all.
              showSubscriptionList = true;
              newTags.remove(SUBSCRIPTION_LIST_TAG);
          } else {
              showSubscriptionList = false;
          }
  
          fragmentTags.clear();
          fragmentTags.addAll(newTags);
          notifyDataSetChanged();
      }
  
      public List<String> getFragmentTags() {
          return Collections.unmodifiableList(fragmentTags);
      }
  
      @Override
      public int getItemCount() {
          int baseCount = getSubscriptionOffset();
          if (showSubscriptionList) {
              baseCount += itemAccess.getCount();
          }
          return baseCount;
      }
  
      @Override
      public long getItemId(int position) {
          int viewType = getItemViewType(position);
          if (viewType == VIEW_TYPE_SUBSCRIPTION) {
              return itemAccess.getItem(position - getSubscriptionOffset()).getId();
          } else if (viewType == VIEW_TYPE_NAV) {
              return -Math.abs((long) fragmentTags.get(position).hashCode()) - 1; // Folder IDs are >0
          } else {
              return 0;
          }
      }
  
      @Override
      public int getItemViewType(int position) {
          if (0 <= position && position < fragmentTags.size()) {
              return VIEW_TYPE_NAV;
          } else if (position < getSubscriptionOffset()) {
              return VIEW_TYPE_SECTION_DIVIDER;
          } else {
              return VIEW_TYPE_SUBSCRIPTION;
          }
      }
  
      public int getSubscriptionOffset() {
          return fragmentTags.size() > 0 ? fragmentTags.size() + 1 : 0;
      }
  
      @NonNull
      @Override
      public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          LayoutInflater inflater = LayoutInflater.from(activity.get());
          if (viewType == VIEW_TYPE_NAV) {
              return new NavHolder(inflater.inflate(R.layout.nav_listitem, parent, false));
          } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
              return new DividerHolder(inflater.inflate(R.layout.nav_section_item, parent, false));
          } else {
              return new FeedHolder(inflater.inflate(R.layout.nav_listitem, parent, false));
          }
      }
  
      @Override
      public void onBindViewHolder(@NonNull Holder holder, int position) {
          int viewType = getItemViewType(position);
  
          holder.itemView.setOnCreateContextMenuListener(null);
          if (viewType == VIEW_TYPE_NAV) {
              bindNavView(NavigationNames.getLabel(fragmentTags.get(position)), position, (NavHolder) holder);
          } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
              bindSectionDivider((DividerHolder) holder);
          } else {
              int itemPos = position - getSubscriptionOffset();
              DrawerItem item = itemAccess.getItem(itemPos);
              bindListItem(item, (FeedHolder) holder);
              if (item.isFeed()) {
                  bindFeedView(item.asFeed(), (FeedHolder) holder);
              } else {
                  bindTagView(item.asTag(), (FeedHolder) holder);
              }
              holder.itemView.setOnCreateContextMenuListener(itemAccess);
          }
          if (viewType != VIEW_TYPE_SECTION_DIVIDER) {
              holder.itemView.setSelected(itemAccess.isSelected(position));
              holder.itemView.setOnClickListener(v -> itemAccess.onItemClick(position));
              holder.itemView.setOnLongClickListener(v -> itemAccess.onItemLongClick(position));
              holder.itemView.setOnTouchListener((v, e) -> {
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                      if (e.isFromSource(InputDevice.SOURCE_MOUSE)
                              && e.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
                          itemAccess.onItemLongClick(position);
                          return false;
                      }
                  }
                  return false;
              });
          }
      }
  
      private void bindNavView(@StringRes int title, int position, NavHolder holder) {
          Activity context = activity.get();
          if (context == null) {
              return;
          }
          holder.title.setText(title);
  
          // reset for re-use
          holder.count.setVisibility(View.GONE);
          holder.count.setOnClickListener(null);
          holder.count.setClickable(false);
  
          String tag = fragmentTags.get(position);
          if (tag.equals(QueueFragment.TAG)) {
              int queueSize = itemAccess.getQueueSize();
              if (queueSize > 0) {
                  holder.count.setText(NumberFormat.getInstance().format(queueSize));
                  holder.count.setVisibility(View.VISIBLE);
              }
          } else if (tag.equals(InboxFragment.TAG)) {
              int unreadItems = itemAccess.getNumberOfNewItems();
              if (unreadItems > 0) {
                  holder.count.setText(NumberFormat.getInstance().format(unreadItems));
                  holder.count.setVisibility(View.VISIBLE);
              }
          } else if (tag.equals(SubscriptionFragment.TAG)) {
              int sum = itemAccess.getFeedCounterSum();
              if (sum > 0) {
                  holder.count.setText(NumberFormat.getInstance().format(sum));
                  holder.count.setVisibility(View.VISIBLE);
              }
          }
  
          holder.image.setImageResource(NavigationNames.getDrawable(fragmentTags.get(position)));
      }
  
      private void bindSectionDivider(DividerHolder holder) {
          Activity context = activity.get();
          if (context == null) {
              return;
          }
  
          if (UserPreferences.getSubscriptionsFilter().isEnabled() && showSubscriptionList) {
              holder.itemView.setEnabled(true);
              holder.feedsFilteredMsg.setVisibility(View.VISIBLE);
          } else {
              holder.itemView.setEnabled(false);
              holder.feedsFilteredMsg.setVisibility(View.GONE);
          }
      }
  
      private void bindListItem(DrawerItem item, FeedHolder holder) {
          if (item.getCounter() > 0) {
              holder.count.setVisibility(View.VISIBLE);
              holder.count.setText(NumberFormat.getInstance().format(item.getCounter()));
          } else {
              holder.count.setVisibility(View.GONE);
          }
          holder.title.setText(item.getTitle());
          int padding = (int) (activity.get().getResources().getDimension(R.dimen.thumbnail_length_navlist) / 2);
          holder.itemView.setPadding(item.getLayer() * padding, 0, 0, 0);
      }
  
      private void bindFeedView(Feed feed, FeedHolder holder) {
          Activity context = activity.get();
          if (context == null) {
              return;
          }
  
          float radius = 4 * context.getResources().getDisplayMetrics().density;
          Glide.with(context)
                  .load(feed.getImageUrl())
                  .apply(new RequestOptions()
                      .placeholder(ImagePlaceholder.getDrawable(context, radius))
                      .error(ImagePlaceholder.getDrawable(context, radius))
                      .transform(new FitCenter(),
                              new RoundedCorners((int) radius))
                      .dontAnimate())
                  .into(holder.image);
  
          holder.failure.setVisibility(feed.hasLastUpdateFailed() ? View.VISIBLE : View.GONE);
      }
  
      private void bindTagView(NavDrawerData.TagItem tag, FeedHolder holder) {
          Activity context = activity.get();
          if (context == null) {
              return;
          }
          if (tag.isOpen()) {
              holder.count.setVisibility(View.GONE);
          }
          Glide.with(context).clear(holder.image);
          holder.image.setImageResource(R.drawable.ic_tag);
          holder.failure.setVisibility(View.GONE);
      }
  
      static class Holder extends RecyclerView.ViewHolder {
          public Holder(@NonNull View itemView) {
              super(itemView);
          }
      }
  
      static class DividerHolder extends Holder {
          final LinearLayout feedsFilteredMsg;
  
          public DividerHolder(@NonNull View itemView) {
              super(itemView);
              feedsFilteredMsg = itemView.findViewById(R.id.nav_feeds_filtered_message);
          }
      }
  
      static class NavHolder extends Holder {
          final ImageView image;
          final TextView title;
          final TextView count;
  
          public NavHolder(@NonNull View itemView) {
              super(itemView);
              image = itemView.findViewById(R.id.imgvCover);
              title = itemView.findViewById(R.id.txtvTitle);
              count = itemView.findViewById(R.id.txtvCount);
          }
      }
  
      static class FeedHolder extends Holder {
          final ImageView image;
          final TextView title;
          final ImageView failure;
          final TextView count;
  
          public FeedHolder(@NonNull View itemView) {
              super(itemView);
              image = itemView.findViewById(R.id.imgvCover);
              title = itemView.findViewById(R.id.txtvTitle);
              failure = itemView.findViewById(R.id.itxtvFailure);
              count = itemView.findViewById(R.id.txtvCount);
          }
      }
  
      public interface ItemAccess extends View.OnCreateContextMenuListener {
          int getCount();
  
          DrawerItem getItem(int position);
  
          boolean isSelected(int position);
  
          int getQueueSize();
  
          int getNumberOfNewItems();
  
          int getNumberOfDownloadedItems();
  
          int getReclaimableItems();
  
          int getFeedCounterSum();
  
          void onItemClick(int position);
  
          boolean onItemLongClick(int position);
  
          @Override
          void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo);
      }
  
  }
  