package net.dev123.yibo.service.adapter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import net.dev123.commons.util.ListUtil;
import net.dev123.mblog.entity.Comment;
import net.dev123.mblog.entity.UnreadCount;
import net.dev123.yibo.R;
import net.dev123.yibo.common.NotificationEntity;
import net.dev123.yibo.common.theme.ThemeUtil;
import net.dev123.yibo.db.LocalAccount;
import net.dev123.yibo.db.LocalComment;
import net.dev123.yibo.service.cache.CommentCache;
import net.dev123.yibo.service.cache.ReclaimLevel;
import net.dev123.yibo.service.cache.wrap.CommentWrap;
import net.dev123.yibo.service.task.CommentsPageDownTask;
import net.dev123.yibo.service.task.CommentsReadLocalTask;
import net.dev123.yibo.service.task.FlushTask;
import net.dev123.yibo.service.task.InitAdapterTask;
import net.dev123.yibo.widget.Skeleton;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.HeaderViewListAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class CommentsListAdapter extends CacheAdapter<Comment> {
private CommentCache cache;
private List<Comment> listNewComments;
private int newCount = 0; //新评论数量;
public CommentsListAdapter(Context context, LocalAccount account) {
super(context, account);
cache = new CommentCache(context, account);
listNewComments = new ArrayList<Comment>();
InitAdapterTask task = new InitAdapterTask(cache, this);
task.execute();
}
@Override
public int getCount() {
return cache.size();
}
@Override
public Object getItem(int position) {
if (position < 0 || position > getCount() - 1) {
return null;
}
Object obj = getItemWrap(position);
if (obj != null) {
obj = ((CommentWrap)obj).getWrap();
}
return obj;
}
public Object getItemWrap(int position) {
if (position < 0) {
position = 0;
}
if (position > getCount() - 1) {
position = getCount() - 1;
}
return cache.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Object obj = getItemWrap(position);
CommentWrap commentWrap = (CommentWrap)obj;
if (commentWrap == null) {
return convertView;
}
int itemViewType = getItemViewType(position);
if (itemViewType == ITEM_VIEW_TYPE_DATA) {
convertView = CommentUtil.initConvertView(context, convertView);
CommentUtil.fillConvertView(convertView, commentWrap);
} else if (itemViewType == ITEM_VIEW_TYPE_REMOTE_DIVIDER) {
convertView = fillInRemoteDividerView(convertView, commentWrap, position);
} else {
convertView = fillInLocalDividerView(convertView, commentWrap, position);
}
return convertView;
}
private View fillInRemoteDividerView(View convertView, CommentWrap wrap, final int position) {
if (wrap == null || !(wrap.getWrap() instanceof LocalComment)) {
return convertView;
}
final LocalComment divider = (LocalComment)wrap.getWrap();
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_gap, null);
ThemeUtil.setListViewGap(convertView);
}
View llLoadingState = convertView.findViewById(R.id.llLoadingState);
if (divider.isLoading()) {
llLoadingState.setVisibility(View.VISIBLE);
} else {
llLoadingState.setVisibility(View.GONE);
}
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setClickable(false);
v.findViewById(R.id.llLoadingState).setVisibility(View.VISIBLE);
Comment max = (Comment)getItem(position - 1);
if (max instanceof LocalComment
&& ((LocalComment)max).isDivider()) {
max = null;
}
Comment since = (Comment)getItem(position + 1);
if (since instanceof LocalComment
&& ((LocalComment)since).isDivider()) {
since = null;
}
CommentsPageDownTask task = new CommentsPageDownTask(CommentsListAdapter.this, divider);
task.execute(max, since);
}
});
return convertView;
}
private View fillInLocalDividerView(View convertView, CommentWrap wrap, final int position) {
if (wrap == null || !(wrap.getWrap() instanceof LocalComment)) {
return null;
}
final LocalComment divider = (LocalComment)wrap.getWrap();
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_more, null);
ThemeUtil.setListViewMore(convertView);
}
if (divider.isLoading()) {
convertView.findViewById(R.id.llLoadingState).setVisibility(View.VISIBLE);
convertView.findViewById(R.id.tvFooter).setVisibility(View.GONE);
} else {
convertView.findViewById(R.id.llLoadingState).setVisibility(View.GONE);
convertView.findViewById(R.id.tvFooter).setVisibility(View.VISIBLE);
}
if (paging.hasNext()) {
convertView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if (divider.isLoading()) {
return;
}
v.setClickable(false);
v.findViewById(R.id.llLoadingState).setVisibility(View.VISIBLE);
v.findViewById(R.id.tvFooter).setVisibility(View.GONE);
Comment max = (Comment)getItem(position - 1);
Comment since = (Comment)getItem(position + 1);
CommentsReadLocalTask localCacheTask = new CommentsReadLocalTask(
CommentsListAdapter.this, cache, divider
);
localCacheTask.execute(max, since);
}
});
} else {
((TextView)convertView.findViewById(R.id.tvFooter)).setText(R.string.label_no_more);
}
return convertView;
}
@Override
public boolean addCacheToFirst(List<Comment> list) {
if (list == null || list.size() == 0) {
return false;
}
List<CommentWrap> listCommentWrap = new ArrayList<CommentWrap>(list.size());
Date currentDate = new Date();
for (Comment comment : list) {
listCommentWrap.add(toWrap(comment, currentDate));
}
cache.addAll(0, listCommentWrap);
this.notifyDataSetChanged();
FlushTask task = new FlushTask(cache);
task.execute();
return true;
}
@Override
public boolean addCacheToDivider(Comment value, List<Comment> list) {
if (list == null || list.size() == 0) {
return false;
}
int i = cache.indexOf(new CommentWrap(value));
if (i == -1) {
return false;
}
cache.remove(i);
List<CommentWrap> listWrap = new ArrayList<CommentWrap>(list.size());
Date currentDate = new Date();
CommentWrap wrap = null;
for (Comment temp : list) {
wrap = toWrap(temp, currentDate);
listWrap.add(wrap);
}
cache.addAll(i, listWrap);
this.notifyDataSetChanged();
FlushTask task = new FlushTask(cache);
task.execute();
return true;
}
@Override
public boolean addCacheToLast(List<Comment> list) {
if (ListUtil.isEmpty(list)) {
return false;
}
List<CommentWrap> listCommentWrap = new ArrayList<CommentWrap>(list.size());
Date currentDate = new Date();
for (Comment comment : list) {
listCommentWrap.add(toWrap(comment, currentDate));
}
cache.addAll(cache.size(), listCommentWrap);
this.notifyDataSetChanged();
FlushTask task = new FlushTask(cache);
task.execute();
return true;
}
@Override
public void clear() {
cache.clear();
}
@Override
public void reclaim(ReclaimLevel level) {
boolean isReclaim = cache.reclaim(level);
if (isReclaim) {
try {
this.notifyDataSetChanged();
} catch(Exception e) {
this.notifyDataSetInvalidated();
}
}
}
public void addNewComments(List<Comment> list) {
if (list == null || list.size() == 0) {
return;
}
listNewComments.addAll(0, list);
}
public NotificationEntity getNotificationEntity(UnreadCount remindCount) {
if (remindCount != null) {
newCount += remindCount.getCommentCount();
} else {
newCount = listNewComments.size();
if (newCount > 0
&& listNewComments.get(newCount - 1) instanceof LocalComment) {
newCount--;
}
}
NotificationEntity entity = new NotificationEntity();
entity.setTickerText(context.getString(R.string.msg_comments_ticker_text));
String accountName = account.getUser().getScreenName();
entity.setContentTitle(context.getString(
R.string.msg_comments_content_title,
accountName, newCount));
entity.setContentText(account.getServiceProvider().getServiceProviderName() + ": "
+ getNewBlogsDesc(newCount));
entity.setContentType(Skeleton.TYPE_COMMENT);
return entity;
}
public String getNewBlogsDesc(int newCount) {
StringBuffer desc = new StringBuffer();
if (ListUtil.isEmpty(listNewComments) || newCount <= 0) {
return desc.toString();
}
List<String> listScreenName = new ArrayList<String>();
String screenName = null;
int showScreenNameCount = 3;
if (showScreenNameCount > newCount) {
showScreenNameCount = newCount;
}
for (int i = 0; i < listNewComments.size() && listScreenName.size() < showScreenNameCount; i++) {
Comment comment = listNewComments.get(i);
if (comment == null
|| comment instanceof LocalComment
|| comment.getUser() == null) {
continue;
}
screenName = comment.getUser().getScreenName();
if (!listScreenName.contains(screenName)) {
listScreenName.add(screenName);
}
}
if (listScreenName.size() >= 3) {
desc.append(
context.getString(
R.string.msg_comments_content_text_3, listScreenName.get(0),
listScreenName.get(1), listScreenName.get(2)
)
);
} else if (listScreenName.size() == 2) {
desc.append(
context.getString(
R.string.msg_comments_content_text_2, listScreenName.get(0), listScreenName.get(1)
)
);
} else if (listScreenName.size() == 1) {
desc.append(context.getString(R.string.msg_comments_content_text_1, listScreenName.get(0)));
}
return desc.toString();
}
public boolean refresh() {
if (ListUtil.isEmpty(listNewComments)) {
return false;
}
addCacheToFirst(listNewComments);
int offset = listNewComments.size();
listNewComments.clear();
newCount = 0;
ListView lvMicroBlog = (ListView)((Activity)context).findViewById(R.id.lvMicroBlog);
if (lvMicroBlog == null) {
return true;
}
Adapter adapter = lvMicroBlog.getAdapter();
if (adapter instanceof HeaderViewListAdapter) {
adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
}
if (lvMicroBlog != null &&
adapter == this
) {
int position = lvMicroBlog.getFirstVisiblePosition();
View view = lvMicroBlog.getChildAt(0);
int y = 0;
if (view != null && position >= 1) {
y = view.getTop();
position += offset;
lvMicroBlog.setSelectionFromTop(position, y);
}
}
return true;
}
@Override
public Comment getMax() {
Comment max = null;
if (cache != null && cache.size() > 0) {
CommentWrap wrap = cache.get(0);
max = wrap.getWrap();
}
if (ListUtil.isNotEmpty(listNewComments)) {
Comment temp = listNewComments.get(0);
if (max != null && max.getCreatedAt() != null) {
max = max.getCreatedAt().before(temp.getCreatedAt()) ? temp : max;
} else {
max = temp;
}
}
return max;
}
@Override
public Comment getMin() {
Comment min = null;
if (cache != null && cache.size() > 0) {
CommentWrap wrap = cache.get(cache.size() - 1);
min = wrap.getWrap();
}
return min;
}
@Override
public boolean remove(int position) {
if (position < 0 || position >= getCount()) {
return false;
}
cache.remove(position);
this.notifyDataSetChanged();
return true;
}
@Override
public boolean remove(Comment comment) {
if (comment == null) {
return false;
}
cache.remove(new CommentWrap(comment));
this.notifyDataSetChanged();
return true;
}
private CommentWrap toWrap(Comment comment, Date date) {
if (comment == null) {
return null;
}
CommentWrap wrap = new CommentWrap(comment);
wrap.setReadedTime(date);
return wrap;
}
public LocalAccount getAccount() {
return account;
}
public void setAccount(LocalAccount account) {
this.account = account;
}
public List<Comment> getListNewComments() {
return listNewComments;
}
@Override
public int getItemViewType(int position) {
Comment comment = (Comment)getItem(position);
if (comment == null) {
return ITEM_VIEW_TYPE_REMOTE_DIVIDER;
}
if (!(comment instanceof LocalComment)) {
return ITEM_VIEW_TYPE_DATA;
}
LocalComment localComment = (LocalComment)comment;
if (!localComment.isDivider()) {
return ITEM_VIEW_TYPE_DATA;
}
if (localComment.isLocalDivider()) {
return ITEM_VIEW_TYPE_LOCAL_DIVIDER;
}
return ITEM_VIEW_TYPE_REMOTE_DIVIDER;
}
@Override
public int getViewTypeCount() {
return 3;
}
}