package io.kaif.mobile.view;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.provider.Browser;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.text.format.DateUtils;
import android.util.StateSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.TextView;
import org.apache.commons.lang3.StringEscapeUtils;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.kaif.mobile.R;
import io.kaif.mobile.kmark.KmarkProcessor;
import io.kaif.mobile.model.Article;
import io.kaif.mobile.model.Vote;
import io.kaif.mobile.view.daemon.VoteDaemon;
import io.kaif.mobile.view.graphics.drawable.LevelDrawable;
import io.kaif.mobile.view.viewmodel.ArticleViewModel;
import io.kaif.mobile.view.viewmodel.DebateViewModel;
import io.kaif.mobile.view.widget.ArticleScoreTextView;
import io.kaif.mobile.view.widget.ClickableSpanTouchListener;
import io.kaif.mobile.view.widget.DebateActions;
import io.kaif.mobile.view.widget.OnVoteClickListener;
import io.kaif.mobile.view.widget.VoteArticleButton;
public class DebateListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public interface OnReplyClickListener {
void onReplyClicked(String parentDebateId, int newLevel);
}
static class ArticleViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.vote)
public VoteArticleButton vote;
@BindView(R.id.vote_count)
public ArticleScoreTextView voteCount;
@BindView(R.id.title)
public TextView title;
@BindView(R.id.link)
public TextView link;
@BindView(R.id.zone)
public TextView zone;
@BindView(R.id.debate_count)
public TextView debateCount;
@BindView(R.id.reply)
public ImageButton replyButton;
@BindView(R.id.self_content)
public TextView content;
@BindView(R.id.author_name)
public TextView authorName;
private ArticleViewModel articleViewModel;
public ArticleViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
content.setOnTouchListener(new ClickableSpanTouchListener());
}
@OnClick(R.id.title)
public void onClickTitle() {
if (articleViewModel.getArticleType() == Article.ArticleType.EXTERNAL_LINK) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(StringEscapeUtils.unescapeHtml4(articleViewModel.getLink())));
intent.putExtra(Browser.EXTRA_APPLICATION_ID, itemView.getContext().getPackageName());
itemView.getContext().startActivity(intent);
}
}
public void update(ArticleViewModel articleVm) {
this.articleViewModel = articleVm;
final Context context = itemView.getContext();
vote.updateVoteState(articleVm.getCurrentVoeState());
voteCount.update(articleVm.getScore(), articleVm.getCurrentVoeState());
voteCount.setOnClickListener(v -> vote.performClick());
debateCount.setText(context.getString(R.string.debate_count, articleVm.getDebateCount()));
zone.setText(articleVm.getZoneTitle());
title.setText(Html.fromHtml(articleVm.getTitle()));
authorName.setText(articleVm.getAuthorName());
if (articleVm.getArticleType() == Article.ArticleType.EXTERNAL_LINK) {
link.setText("(" + Uri.parse(articleVm.getLink()).getAuthority() + ")");
content.setVisibility(View.GONE);
content.setText(null);
} else {
link.setText("("
+ itemView.getContext().getString(R.string.zone_path, articleVm.getZone())
+ ")");
content.setVisibility(View.VISIBLE);
content.setText(KmarkProcessor.process(context, articleVm.getContent()));
}
}
void setOnReplyClickListener(View.OnClickListener onClickListener) {
replyButton.setOnClickListener(view -> {
Animation animation = AnimationUtils.loadAnimation(view.getContext(),
R.anim.scale_action_icon);
view.startAnimation(animation);
onClickListener.onClick(view);
});
}
void setOnVoteClickListener(OnVoteClickListener onVoteClickListener) {
vote.setOnVoteClickListener(onVoteClickListener);
}
public void showVoteEffect() {
vote.showVoteColor(true);
voteCount.showVoteColor(true);
}
}
static class DebateViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.content)
public TextView content;
@BindView(R.id.last_update_time)
public TextView lastUpdateTime;
@BindView(R.id.vote_score)
public TextView voteScore;
@BindView(R.id.debater_name)
public TextView debaterName;
@BindView(R.id.debate_actions)
public DebateActions debateActions;
public DebateViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
content.setOnTouchListener(new ClickableSpanTouchListener());
}
public void update(DebateViewModel debateViewModel, boolean showActions) {
final Context context = itemView.getContext();
itemView.setBackground(createDebateDrawable(debateViewModel, context));
debaterName.setText(debateViewModel.getDebaterName());
content.setText(KmarkProcessor.process(context, debateViewModel.getContent()));
lastUpdateTime.setText(DateUtils.getRelativeTimeSpanString(debateViewModel.getLastUpdateTime()
.getTime(), System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
voteScore.setText(String.valueOf(debateViewModel.getVoteScore()));
debateActions.updateVoteState(debateViewModel.getCurrentVoeState());
if (showActions) {
itemView.setActivated(true);
debateActions.setVisibility(View.VISIBLE);
} else {
itemView.setActivated(false);
debateActions.setVisibility(View.GONE);
}
}
void setOnVoteClickListener(OnVoteClickListener onVoteClickListener) {
debateActions.setOnVoteClickListener(onVoteClickListener);
}
void setOnReplyClickListener(View.OnClickListener onClickListener) {
debateActions.setOnReplyClickListener(onClickListener);
}
private Drawable createDebateDrawable(DebateViewModel debateViewModel, Context context) {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_activated},
new LevelDrawable(context,
debateViewModel.getLevel(),
context.getResources().getColor(R.color.kaif_selected_blue)));
stateListDrawable.addState(StateSet.WILD_CARD,
new LevelDrawable(context, debateViewModel.getLevel(), Color.TRANSPARENT));
return stateListDrawable;
}
public void showVoteEffect(Vote.VoteState from) {
debateActions.playAnimations(from);
}
}
private final List<DebateViewModel> debates;
private final ArticleViewModel article;
private final VoteDaemon voteDaemon;
private int selectedPosition = RecyclerView.NO_POSITION;
private final OnReplyClickListener onReplyClickListener;
public DebateListAdapter(ArticleViewModel article,
VoteDaemon voteDaemon,
OnReplyClickListener onReplyClickListener) {
this.onReplyClickListener = onReplyClickListener;
this.debates = new ArrayList<>();
this.article = article;
this.voteDaemon = voteDaemon;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == R.layout.item_article_full) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new ArticleViewHolder(view);
}
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new DebateViewHolder(view);
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return R.layout.item_article_full;
}
return R.layout.item_debate;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == 0) {
ArticleViewHolder articleViewHolder = (ArticleViewHolder) holder;
articleViewHolder.update(article);
articleViewHolder.setOnReplyClickListener(v -> onReplyClickListener.onReplyClicked(null, 1));
articleViewHolder.setOnVoteClickListener((from, to) -> voteDaemon.voteArticle(article.getArticleId(),
from,
to));
return;
}
DebateViewModel debateVm = debates.get(position - 1);
DebateViewHolder debateViewHolder = (DebateViewHolder) holder;
debateViewHolder.update(debateVm, position == selectedPosition);
debateViewHolder.setOnReplyClickListener(v -> onReplyClickListener.onReplyClicked(debateVm.getDebateId(),
debateVm.getLevel() + 1));
debateViewHolder.setOnVoteClickListener((from, to) -> voteDaemon.voteDebate(debateVm.getDebateId(),
from,
to));
holder.itemView.setOnClickListener(v -> selectItem(holder.getAdapterPosition()));
}
@Override
public int getItemCount() {
return debates.size() + 1;
}
public void refresh(List<DebateViewModel> debates) {
clearSelection();
this.debates.clear();
this.debates.addAll(debates);
notifyDataSetChanged();
}
public void clearSelection() {
int prev = selectedPosition;
selectedPosition = RecyclerView.NO_POSITION;
notifyItemChanged(prev);
}
public void selectItem(int position) {
int prev = selectedPosition;
selectedPosition = position;
notifyItemChanged(prev);
notifyItemChanged(position);
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
if (holder instanceof DebateViewHolder) {
int position = holder.getAdapterPosition();
DebateViewModel debateVm = debates.get(position - 1);
if (debateVm.shouldShowVoteEffect()) {
debateVm.setCanShowVoteAnimation(false);
((DebateViewHolder) holder).showVoteEffect(debateVm.getPrevVoteState());
}
return;
}
if (article.shouldShowVoteEffect()) {
article.setCanShowVoteAnimation(false);
((ArticleViewHolder) holder).showVoteEffect();
}
}
public void updateArticleVote(String articleId, Vote.VoteState voteState) {
if (article.getArticleId().equals(articleId)) {
article.updateVoteState(voteState);
notifyItemChanged(0);
}
}
public void updateDebateVote(String debateId, Vote.VoteState voteState) {
for (int i = 0; i < debates.size(); i++) {
DebateViewModel debateVm = debates.get(i);
if (debateVm.getDebateId().equals(debateId)) {
debateVm.updateVoteState(voteState);
notifyItemChanged(i + 1);
break;
}
}
}
public int findPositionByDebateId(String debateId) {
for (int i = 0; i < debates.size(); i++) {
DebateViewModel debate = debates.get(i);
if (debate.getDebateId().equals(debateId)) {
return i + 1;
}
}
return RecyclerView.NO_POSITION;
}
}