public class BookmarksAdapter extends RecyclerView.Adapter<BaseViewHolder> {

    private Context context;

    public static final int TYPE_ZHIHU_NORMAL = 0;
    public static final int TYPE_ZHIHU_WITH_HEADER = 1;
    public static final int TYPE_GUOKE_NORMAL = 2;
    public static final int TYPE_GUOKE_WITH_HEADER = 3;
    public static final int TYPE_DOUBAN_NORMAL = 4;
    public static final int TYPE_DOUBAN_WITH_HEADER = 5;

    private List<DoubanMomentNews.Posts> doubanList;
    private List<GuokeHandpickNews.Result> guokeList;
    private List<ZhihuDailyNews.Question> zhihuList;

    private OnRecyclerViewOnClickListener listener;

    private List<Integer> types; // to store which type the item is.

    public BookmarksAdapter(@NonNull Context context, List<DoubanMomentNews.Posts> doubanList, List<GuokeHandpickNews.Result> guokeList, List<ZhihuDailyNews.Question> zhihuList, List<Integer> types) {
        this.context=context;
        this.doubanList = doubanList;
        this.guokeList = guokeList;
        this.zhihuList = zhihuList;
        this.types = types;//types.size = zhihuList.size + guokrList.size + doubanList.size
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_ZHIHU_NORMAL:
            case TYPE_GUOKE_NORMAL:
            case TYPE_DOUBAN_NORMAL:
                return new WithListenerViewHolder(
                        DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.home_list_item_layout, parent, false)
                        , this.listener);
            default:break;
        }
        return new BaseViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.bookmark_header, parent, false));
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        switch (types.get(position)) {
            case TYPE_ZHIHU_WITH_HEADER:
                holder.getBinding().setVariable(BR.viewType,context.getResources().getString(R.string.zhihu_daily));
                break;
            case TYPE_ZHIHU_NORMAL:
                if (!zhihuList.isEmpty()) {
                    ZhihuDailyNews.Question question = zhihuList.get(position - 1);
                    holder.getBinding().setVariable(BR.imgUrl, question.getImages().get(0));
                    holder.getBinding().setVariable(BR.title, question.getTitle());
                }
                break;
            case TYPE_GUOKE_WITH_HEADER:
                holder.getBinding().setVariable(BR.viewType,context.getResources().getString(R.string.guokr_handpick));
                break;
            case TYPE_GUOKE_NORMAL:
                if (!guokeList.isEmpty()) {
                    GuokeHandpickNews.Result result = guokeList.get(position - zhihuList.size() - 2);
                    holder.getBinding().setVariable(BR.imgUrl, result.getHeadline_img_tb());
                    holder.getBinding().setVariable(BR.title, result.getTitle());
                }
                break;
            case TYPE_DOUBAN_WITH_HEADER:
                holder.getBinding().setVariable(BR.viewType,context.getResources().getString(R.string.douban_moment));
                break;
            case TYPE_DOUBAN_NORMAL:
                if (!doubanList.isEmpty()){
                    DoubanMomentNews.Posts posts=doubanList.get(position - zhihuList.size() - guokeList.size() - 3);
                    if (posts.getThumbs().size()==0) {
                        holder.getBinding().getRoot().findViewById(R.id.imageViewCover).setVisibility(View.INVISIBLE);
                    } else {
                        holder.getBinding().setVariable(BR.imgUrl, posts.getThumbs().get(0).getMedium().getUrl());
                    }
                    holder.getBinding().setVariable(BR.title, posts.getTitle());
                }
                break;
            default:break;
        }
    }

    public void setItemListener(OnRecyclerViewOnClickListener listener) {
        this.listener = listener;
    }

    @Override
    public int getItemViewType(int position) {
        return types.get(position);
    }

    @Override
    public int getItemCount() {
        return types.size();
    }
} public enum BeanType {

    TYPE_ZHIHU, TYPE_GUOKE,TYPE_DOUBAN;

} public class DoubanCache extends DataSupport {
    private int douban_id;
    private String douban_news;
    private float douban_time;
    private String douban_content;
    private boolean bookmark=false;

    public int getDouban_id() {
        return douban_id;
    }

    public void setDouban_id(int douban_id) {
        this.douban_id = douban_id;
    }

    public String getDouban_news() {
        return douban_news;
    }

    public void setDouban_news(String douban_news) {
        this.douban_news = douban_news;
    }

    public float getDouban_time() {
        return douban_time;
    }

    public void setDouban_time(float douban_time) {
        this.douban_time = douban_time;
    }

    public String getDouban_content() {
        return douban_content;
    }

    public void setDouban_content(String douban_content) {
        this.douban_content = douban_content;
    }

    public boolean isBookmark() {
        return bookmark;
    }

    public void setBookmark(boolean bookmark) {
        this.bookmark = bookmark;
    }

    @Override
    public String toString() {
        return "douban_id="+douban_id+",bookmark="+bookmark;
    }
} public class DoubanMomentNews {

    private int count;
    private ArrayList<Posts> posts;
    private int offset;
    private String date;
    private int total;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public ArrayList<Posts> getPosts() {
        return posts;
    }

    public void setPosts(ArrayList<Posts> posts) {
        this.posts = posts;
    }

    public int getOffset() {
        return offset;
    }

    public void setOffset(int offset) {
        this.offset = offset;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public class Posts {

        private int display_style;
        private boolean is_editor_choice;
        private String published_time;
        private String url;
        private String short_url;
        private boolean is_liked;
        private author author;
        private String column;
        private int app_css;
        @SerializedName("abstract")
        private String abs;
        private String date;
        private int like_count;
        private int comments_count;
        private ArrayList<thumbs> thumbs;
        private String created_time;
        private String title;
        private String share_pic_url;
        private String type;
        private int id;

        public class thumbs {
            medium medium;
            String description;
            large large;
            String tag_name;
            small small;
            int id;

            public Posts.medium getMedium() {
                return medium;
            }

            public void setMedium(Posts.medium medium) {
                this.medium = medium;
            }

            public String getDescription() {
                return description;
            }

            public void setDescription(String description) {
                this.description = description;
            }

            public Posts.large getLarge() {
                return large;
            }

            public void setLarge(Posts.large large) {
                this.large = large;
            }

            public String getTag_name() {
                return tag_name;
            }

            public void setTag_name(String tag_name) {
                this.tag_name = tag_name;
            }

            public Posts.small getSmall() {
                return small;
            }

            public void setSmall(Posts.small small) {
                this.small = small;
            }

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }
        }

        public class small {
            String url;
            int width;
            int height;

            public String getUrl() {
                return url;
            }
        }

        public class medium {
            String url;
            int width;
            int height;

            public String getUrl() {
                return url;
            }
        }

        public class large {
            String url;
            int width;
            int height;

            public String getUrl() {
                return url;
            }
        }

        public int getDisplay_style() {
            return display_style;
        }

        public void setDisplay_style(int display_style) {
            this.display_style = display_style;
        }

        public boolean is_editor_choice() {
            return is_editor_choice;
        }

        public void setIs_editor_choice(boolean is_editor_choice) {
            this.is_editor_choice = is_editor_choice;
        }

        public String getPublished_time() {
            return published_time;
        }

        public void setPublished_time(String published_time) {
            this.published_time = published_time;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getShort_url() {
            return short_url;
        }

        public void setShort_url(String short_url) {
            this.short_url = short_url;
        }

        public boolean is_liked() {
            return is_liked;
        }

        public void setIs_liked(boolean is_liked) {
            this.is_liked = is_liked;
        }

        public DoubanMomentNews.author getAuthor() {
            return author;
        }

        public void setAuthor(DoubanMomentNews.author author) {
            this.author = author;
        }

        public String getColumn() {
            return column;
        }

        public void setColumn(String column) {
            this.column = column;
        }

        public int getApp_css() {
            return app_css;
        }

        public void setApp_css(int app_css) {
            this.app_css = app_css;
        }

        public String getAbs() {
            return abs;
        }

        public void setAbs(String abs) {
            this.abs = abs;
        }

        public String getDate() {
            return date;
        }

        public void setDate(String date) {
            this.date = date;
        }

        public int getLike_count() {
            return like_count;
        }

        public void setLike_count(int like_count) {
            this.like_count = like_count;
        }

        public int getComments_count() {
            return comments_count;
        }

        public void setComments_count(int comments_count) {
            this.comments_count = comments_count;
        }

        public ArrayList<thumbs> getThumbs() {
            return thumbs;
        }

        public void setThumbs(ArrayList<thumbs> thumbs) {
            this.thumbs = thumbs;
        }

        public String getCreated_time() {
            return created_time;
        }

        public void setCreated_time(String created_time) {
            this.created_time = created_time;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getShare_pic_url() {
            return share_pic_url;
        }

        public void setShare_pic_url(String share_pic_url) {
            this.share_pic_url = share_pic_url;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }
    }

    private class author {
        boolean is_followed;
        String uid;
        String url;
        String avatar;
        String name;
        boolean is_special_user;
        int n_posts;
        String alt;
        String large_avatar;
        String id;
        boolean is_auth_author;
    }

} public class GuokeCache extends DataSupport {
    private int guoke_id;
    private String guoke_news;
    private float guoke_time;
    private String guoke_content;
    private boolean bookmark=false;

    public int getGuoke_id() {
        return guoke_id;
    }

    public void setGuoke_id(int guoke_id) {
        this.guoke_id = guoke_id;
    }

    public String getGuoke_news() {
        return guoke_news;
    }

    public void setGuoke_news(String guoke_news) {
        this.guoke_news = guoke_news;
    }

    public float getGuoke_time() {
        return guoke_time;
    }

    public void setGuoke_time(float guoke_time) {
        this.guoke_time = guoke_time;
    }

    public String getGuoke_content() {
        return guoke_content;
    }

    public void setGuoke_content(String guoke_content) {
        this.guoke_content = guoke_content;
    }

    public boolean isBookmark() {
        return bookmark;
    }

    public void setBookmark(boolean bookmark) {
        this.bookmark = bookmark;
    }

    @Override
    public String toString() {
        return "guoke_id="+guoke_id+",bookmark="+bookmark;
    }
} public class GuokeHandpickNews {

    private String now;
    private boolean ok;
    private ArrayList<Result> result;

    public String getNow() {
        return now;
    }

    public void setNow(String now) {
        this.now = now;
    }

    public boolean isOk() {
        return ok;
    }

    public void setOk(boolean ok) {
        this.ok = ok;
    }

    public ArrayList<Result> getResult() {
        return result;
    }

    public void setResult(ArrayList<Result> result) {
        this.result = result;
    }

    public class Result {
        private String link_v2_sync_img;
        private String source_name;
        private String video_url;
        private boolean current_user_has_collected;
        private int likings_count;
        private String[] images;
        private String video_duration;
        private int id;
        private String category;
        private String style;
        private String title;
        private source_data source_data;
        private String headline_img_tb;
        private String link_v2;
        private double date_picked;
        private boolean is_top;
        private String link;
        private String headline_img;
        private int replies_count;
        private boolean current_user_has_liked;
        private String page_source;
        private String author;
        private String summary;
        private String source;
        private int reply_root_id;
        private double date_created;

        public String getLink_v2_sync_img() {
            return link_v2_sync_img;
        }

        public void setLink_v2_sync_img(String link_v2_sync_img) {
            this.link_v2_sync_img = link_v2_sync_img;
        }

        public String getSource_name() {
            return source_name;
        }

        public void setSource_name(String source_name) {
            this.source_name = source_name;
        }

        public String getVideo_url() {
            return video_url;
        }

        public void setVideo_url(String video_url) {
            this.video_url = video_url;
        }

        public boolean isCurrent_user_has_collected() {
            return current_user_has_collected;
        }

        public void setCurrent_user_has_collected(boolean current_user_has_collected) {
            this.current_user_has_collected = current_user_has_collected;
        }

        public int getLikings_count() {
            return likings_count;
        }

        public void setLikings_count(int likings_count) {
            this.likings_count = likings_count;
        }

        public String[] getImages() {
            return images;
        }

        public void setImages(String[] images) {
            this.images = images;
        }

        public String getVideo_duration() {
            return video_duration;
        }

        public void setVideo_duration(String video_duration) {
            this.video_duration = video_duration;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getCategory() {
            return category;
        }

        public void setCategory(String category) {
            this.category = category;
        }

        public String getStyle() {
            return style;
        }

        public void setStyle(String style) {
            this.style = style;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public GuokeHandpickNews.source_data getSource_data() {
            return source_data;
        }

        public void setSource_data(GuokeHandpickNews.source_data source_data) {
            this.source_data = source_data;
        }

        public String getHeadline_img_tb() {
            return headline_img_tb;
        }

        public void setHeadline_img_tb(String headline_img_tb) {
            this.headline_img_tb = headline_img_tb;
        }

        public String getLink_v2() {
            return link_v2;
        }

        public void setLink_v2(String link_v2) {
            this.link_v2 = link_v2;
        }

        public double getDate_picked() {
            return date_picked;
        }

        public void setDate_picked(double date_picked) {
            this.date_picked = date_picked;
        }

        public boolean is_top() {
            return is_top;
        }

        public void setIs_top(boolean is_top) {
            this.is_top = is_top;
        }

        public String getLink() {
            return link;
        }

        public void setLink(String link) {
            this.link = link;
        }

        public String getHeadline_img() {
            return headline_img;
        }

        public void setHeadline_img(String headline_img) {
            this.headline_img = headline_img;
        }

        public int getReplies_count() {
            return replies_count;
        }

        public void setReplies_count(int replies_count) {
            this.replies_count = replies_count;
        }

        public boolean isCurrent_user_has_liked() {
            return current_user_has_liked;
        }

        public void setCurrent_user_has_liked(boolean current_user_has_liked) {
            this.current_user_has_liked = current_user_has_liked;
        }

        public String getPage_source() {
            return page_source;
        }

        public void setPage_source(String page_source) {
            this.page_source = page_source;
        }

        public String getAuthor() {
            return author;
        }

        public void setAuthor(String author) {
            this.author = author;
        }

        public String getSummary() {
            return summary;
        }

        public void setSummary(String summary) {
            this.summary = summary;
        }

        public String getSource() {
            return source;
        }

        public void setSource(String source) {
            this.source = source;
        }

        public int getReply_root_id() {
            return reply_root_id;
        }

        public void setReply_root_id(int reply_root_id) {
            this.reply_root_id = reply_root_id;
        }

        public double getDate_created() {
            return date_created;
        }

        public void setDate_created(double date_created) {
            this.date_created = date_created;
        }
    }

    public class source_data {
        private String image;
        private String summary;
        private int id;
        private String title;

        public String getImage() {
            return image;
        }

        public void setImage(String image) {
            this.image = image;
        }

        public String getSummary() {
            return summary;
        }

        public void setSummary(String summary) {
            this.summary = summary;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

} public class ZhihuCache extends DataSupport {
    //由于LitePal默认含有主键，所以在这里不另外设置了
    private int zhihu_id;//知乎日报消息id
    private String zhihu_news;//知乎日报消息内容
    private float zhihu_time;//知乎日报消息发布的时间
    private String zhihu_content;//知乎日报消息详细内容
    private boolean bookmark=false;//是否被收藏

    public boolean isBookmark() {
        return bookmark;
    }

    public void setBookmark(boolean bookmark) {
        this.bookmark = bookmark;
    }

    public int getZhihu_id() {
        return zhihu_id;
    }

    public void setZhihu_id(int zhihu_id) {
        this.zhihu_id = zhihu_id;
    }

    public String getZhihu_news() {
        return zhihu_news;
    }

    public void setZhihu_news(String zhihu_news) {
        this.zhihu_news = zhihu_news;
    }

    public float getZhihu_time() {
        return zhihu_time;
    }

    public void setZhihu_time(float zhihu_time) {
        this.zhihu_time = zhihu_time;
    }

    public String getZhihu_content() {
        return zhihu_content;
    }

    public void setZhihu_content(String zhihu_content) {
        this.zhihu_content = zhihu_content;
    }

    @Override
    public String toString() {
        return "zhihu_id="+zhihu_id+",bookmark="+bookmark;
    }
} public class ZhihuDailyNews {

    private String date;
    private ArrayList<Question> stories;

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public ArrayList<Question> getStories() {
        return stories;
    }

    public void setStories(ArrayList<Question> stories) {
        this.stories = stories;
    }

    public class Question {

        private ArrayList<String> images;
        private int type;
        private int id;
        private String ga_prefix;
        private String title;

        public ArrayList<String> getImages() {
            return images;
        }

        public void setImages(ArrayList<String> images) {
            this.images = images;
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getGa_prefix() {
            return ga_prefix;
        }

        public void setGa_prefix(String ga_prefix) {
            this.ga_prefix = ga_prefix;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

} public class DetailActivity extends AppCompatActivity {
    private DetailFragment fragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frame);

        if (savedInstanceState != null) {
            fragment = (DetailFragment) getSupportFragmentManager().getFragment(savedInstanceState,"detailFragment");
        } else {
            fragment = new DetailFragment();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.container, fragment)
                    .commit();
        }

        Intent intent = getIntent();
        DetailPresenter presenter = new DetailPresenter(DetailActivity.this, fragment);
        presenter.setType((BeanType) intent.getSerializableExtra("type"));
        presenter.setId(intent.getIntExtra("id", 0));
        presenter.setTitle(intent.getStringExtra("title"));
        presenter.setCoverUrl(intent.getStringExtra("coverUrl"));
        presenter.logMsg();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (fragment.isAdded()) {
            getSupportFragmentManager().putFragment(outState, "detailFragment", fragment);
        }
    }
} public static final int TYPE_DOUBAN_NORMAL = 4; public static final int TYPE_DOUBAN_WITH_HEADER = 5; public static final int TYPE_GUOKE_NORMAL = 2; public static final int TYPE_GUOKE_WITH_HEADER = 3; public static final int TYPE_ZHIHU_NORMAL = 0; public static final int TYPE_ZHIHU_WITH_HEADER = 1;
import android.content.Context;
import android.content.Intent;
import com.google.gson.Gson;
import com.hut.zero.adapter.BookmarksAdapter;
import com.hut.zero.bean.BeanType;
import com.hut.zero.bean.DoubanCache;
import com.hut.zero.bean.DoubanMomentNews;
import com.hut.zero.bean.GuokeCache;
import com.hut.zero.bean.GuokeHandpickNews;
import com.hut.zero.bean.ZhihuCache;
import com.hut.zero.bean.ZhihuDailyNews;
import com.hut.zero.detail.DetailActivity;
import org.litepal.crud.DataSupport;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import rx.Observable;
import static com.hut.zero.adapter.BookmarksAdapter.TYPE_DOUBAN_NORMAL;
import static com.hut.zero.adapter.BookmarksAdapter.TYPE_DOUBAN_WITH_HEADER;
import static com.hut.zero.adapter.BookmarksAdapter.TYPE_GUOKE_NORMAL;
import static com.hut.zero.adapter.BookmarksAdapter.TYPE_GUOKE_WITH_HEADER;
import static com.hut.zero.adapter.BookmarksAdapter.TYPE_ZHIHU_NORMAL;
import static com.hut.zero.adapter.BookmarksAdapter.TYPE_ZHIHU_WITH_HEADER;
/*
 * Copyright 2017 lizhaotailang
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hut.zero.bookmarks;







/**
 * Created by lizhaotailang on 2016/12/23.
 */

public class BookmarksPresenter implements BookmarksContract.Presenter {
    private BookmarksContract.View view;
    private Context context;
    private Gson gson;

    private ArrayList<DoubanMomentNews.Posts> doubanList;
    private ArrayList<GuokeHandpickNews.Result> guokeList;
    private ArrayList<ZhihuDailyNews.Question> zhihuList;

    private ArrayList<Integer> types;

    public BookmarksPresenter(Context context, BookmarksContract.View view) {
        this.context = context;
        this.view = view;
        this.view.setPresenter(this);
        gson = new Gson();

        zhihuList = new ArrayList<>();
        guokeList = new ArrayList<>();
        doubanList = new ArrayList<>();

        types = new ArrayList<>();
    }

    /**
     * 请求结果
     *
     * @param refresh
     */
    @Override
    public void loadResults(boolean refresh) {
        if (!refresh) {
            view.showLoading();
        } else {
            zhihuList.clear();
            guokeList.clear();
            doubanList.clear();
            types.clear();
        }

        checkForFreshData();
        view.showResults(zhihuList, guokeList, doubanList, types);
        view.stopLoading();
    }

    @Override
    public void checkForFreshData() {
        // every first one of the 3 lists is with header
        // add them in advance

        //如果zhihuList、guokeList、doubanList分别在三个单独的线程添加数据，会因线程不同步使得使得types的数据与list不对应，从而在适配器在加载子项时出错
        //但是在同一个线程中顺序添加数据时，就不会导致错误(如下)
        //LitePal在存储布尔值的时候是以1和0的值存储的，不是以true或者false，所以在以布尔值为字段存储为查询条件时应该为 fieldName = 1 or 0

        types.add(TYPE_ZHIHU_WITH_HEADER);
        List<ZhihuCache> list1 = DataSupport.where("bookmark = 1").find(ZhihuCache.class);
        Observable.from(list1)
                .subscribe(zhihuCache -> {
                    ZhihuDailyNews.Question question = gson.fromJson(zhihuCache.getZhihu_news(), ZhihuDailyNews.Question.class);
                    zhihuList.add(question);
                    types.add(TYPE_ZHIHU_NORMAL);
                });

        types.add(TYPE_GUOKE_WITH_HEADER);
        List<GuokeCache> list2 = DataSupport.where("bookmark = 1").find(GuokeCache.class);
        Observable.from(list2)
                .subscribe(guokeCache -> {
                    GuokeHandpickNews.Result result = gson.fromJson(guokeCache.getGuoke_news(), GuokeHandpickNews.Result.class);
                    guokeList.add(result);
                    types.add(TYPE_GUOKE_NORMAL);
                });


        types.add(TYPE_DOUBAN_WITH_HEADER);