/*
* Copyright (C) 2016 Simon Vig Therkildsen
*
* 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 net.simonvt.cathode.ui.shows;
import android.database.Cursor;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import javax.inject.Inject;
import net.simonvt.cathode.CathodeApp;
import net.simonvt.cathode.R;
import net.simonvt.cathode.images.ImageType;
import net.simonvt.cathode.images.ImageUri;
import net.simonvt.cathode.provider.DatabaseContract.EpisodeColumns;
import net.simonvt.cathode.provider.DatabaseContract.LastModifiedColumns;
import net.simonvt.cathode.provider.DatabaseContract.ShowColumns;
import net.simonvt.cathode.provider.DatabaseSchematic.Tables;
import net.simonvt.cathode.scheduler.ShowTaskScheduler;
import net.simonvt.cathode.ui.LibraryType;
import net.simonvt.cathode.ui.adapter.RecyclerCursorAdapter;
import net.simonvt.cathode.ui.dialog.CheckInDialog;
import net.simonvt.cathode.ui.dialog.CheckInDialog.Type;
import net.simonvt.cathode.util.DataHelper;
import net.simonvt.cathode.widget.OverflowView;
import net.simonvt.cathode.widget.RemoteImageView;
import net.simonvt.cathode.widget.TimeStamp;
import net.simonvt.schematic.Cursors;
/**
* A show adapter that displays the next episode as well.
*/
public class ShowsWithNextAdapter extends RecyclerCursorAdapter<ShowsWithNextAdapter.ViewHolder> {
private static final String COLUMN_EPISODE_ID = "episodeId";
private static final String COLUMN_EPISODE_LAST_UPDATED = "episodeLastUpdated";
public static final String[] PROJECTION = new String[] {
Tables.SHOWS + "." + ShowColumns.ID, Tables.SHOWS + "." + ShowColumns.TITLE,
Tables.SHOWS + "." + ShowColumns.OVERVIEW, ShowColumns.AIRED_COUNT,
Tables.SHOWS + "." + ShowColumns.WATCHED_COUNT,
Tables.SHOWS + "." + ShowColumns.IN_COLLECTION_COUNT, Tables.SHOWS + "." + ShowColumns.STATUS,
ShowColumns.WATCHING, Tables.SHOWS + "." + ShowColumns.LAST_MODIFIED,
Tables.EPISODES + "." + EpisodeColumns.ID + " AS " + COLUMN_EPISODE_ID,
Tables.EPISODES + "." + EpisodeColumns.TITLE,
Tables.EPISODES + "." + EpisodeColumns.FIRST_AIRED,
Tables.EPISODES + "." + EpisodeColumns.SEASON, Tables.EPISODES + "." + EpisodeColumns.EPISODE,
Tables.EPISODES + "." + EpisodeColumns.LAST_MODIFIED + " AS " + COLUMN_EPISODE_LAST_UPDATED,
};
@Inject ShowTaskScheduler showScheduler;
private FragmentActivity activity;
private final LibraryType libraryType;
protected ShowClickListener clickListener;
public ShowsWithNextAdapter(FragmentActivity activity, ShowClickListener clickListener,
LibraryType libraryType) {
this(activity, clickListener, null, libraryType);
}
public ShowsWithNextAdapter(FragmentActivity activity, ShowClickListener clickListener,
Cursor cursor, LibraryType libraryType) {
super(activity, cursor);
CathodeApp.inject(activity, this);
this.activity = activity;
this.clickListener = clickListener;
this.libraryType = libraryType;
}
@Override public long getLastModified(int position) {
Cursor cursor = getCursor(position);
final long showLastModified = Cursors.getLong(cursor, LastModifiedColumns.LAST_MODIFIED);
final long episodeLastModified = Cursors.getLong(cursor, COLUMN_EPISODE_LAST_UPDATED);
return showLastModified + episodeLastModified;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(getContext()).inflate(R.layout.list_row_show, parent, false);
final ViewHolder holder = new ViewHolder(v);
v.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
final int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
Cursor cursor = getCursor(position);
final String title = Cursors.getString(cursor, ShowColumns.TITLE);
final String overview = Cursors.getString(cursor, ShowColumns.OVERVIEW);
clickListener.onShowClick(holder.getItemId(), title, overview);
}
}
});
holder.overflow.setListener(new OverflowView.OverflowActionListener() {
@Override public void onPopupShown() {
}
@Override public void onPopupDismissed() {
}
@Override public void onActionSelected(int action) {
final int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
switch (action) {
case R.id.action_watchlist_remove:
showScheduler.setIsInWatchlist(holder.getItemId(), false);
break;
case R.id.action_watched:
onWatchNext(holder.itemView, position, holder.getItemId(), holder.showTypeCount,
holder.showAiredCount);
break;
case R.id.action_watched_all:
showScheduler.setWatched(holder.getItemId(), true);
break;
case R.id.action_unwatch_all:
showScheduler.setWatched(holder.getItemId(), false);
break;
case R.id.action_checkin:
CheckInDialog.showDialogIfNecessary(activity, Type.SHOW, holder.episodeTitle,
holder.episodeId);
break;
case R.id.action_checkin_cancel:
showScheduler.cancelCheckin();
break;
case R.id.action_collection_add:
showScheduler.collectedNext(holder.getItemId());
break;
case R.id.action_watched_hide:
showScheduler.hideFromWatched(holder.getItemId(), true);
break;
case R.id.action_collection_hide:
showScheduler.hideFromCollected(holder.getItemId(), true);
break;
}
}
}
});
return holder;
}
@Override public void onViewRecycled(ViewHolder holder) {
holder.overflow.dismiss();
}
@Override protected void onBindViewHolder(ViewHolder holder, Cursor cursor, int position) {
final long id = Cursors.getLong(cursor, ShowColumns.ID);
final String showTitle = Cursors.getString(cursor, ShowColumns.TITLE);
final String showStatus = Cursors.getString(cursor, ShowColumns.STATUS);
final boolean watching = Cursors.getBoolean(cursor, ShowColumns.WATCHING);
final String showPosterUri = ImageUri.create(ImageUri.ITEM_SHOW, ImageType.POSTER, id);
final int showAiredCount = Cursors.getInt(cursor, ShowColumns.AIRED_COUNT);
int count = 0;
switch (libraryType) {
case WATCHED:
case WATCHLIST:
count = Cursors.getInt(cursor, ShowColumns.WATCHED_COUNT);
break;
case COLLECTION:
count = Cursors.getInt(cursor, ShowColumns.IN_COLLECTION_COUNT);
break;
}
final int showTypeCount = count;
final long episodeId = Cursors.getLong(cursor, COLUMN_EPISODE_ID);
final long episodeFirstAired = DataHelper.getFirstAired(cursor);
final int episodeSeasonNumber = Cursors.getInt(cursor, EpisodeColumns.SEASON);
final int episodeNumber = Cursors.getInt(cursor, EpisodeColumns.EPISODE);
String episodeTitle = null;
if (episodeSeasonNumber > 0) {
episodeTitle = DataHelper.getEpisodeTitle(getContext(), cursor, episodeSeasonNumber, episodeNumber);
}
holder.title.setText(showTitle);
holder.progressBar.setMax(showAiredCount);
holder.progressBar.setProgress(showTypeCount);
final String typeCount = getContext().getString(R.string.x_of_y, showTypeCount, showAiredCount);
holder.watched.setText(typeCount);
String episodeText;
if (episodeTitle == null) {
episodeText = showStatus;
holder.firstAired.setVisibility(View.GONE);
} else {
if (watching) {
episodeText = getContext().getString(R.string.show_watching);
} else {
episodeText =
getContext().getString(R.string.episode_next, episodeSeasonNumber, episodeNumber,
episodeTitle);
}
holder.firstAired.setVisibility(View.VISIBLE);
holder.firstAired.setTimeInMillis(episodeFirstAired);
}
holder.nextEpisode.setText(episodeText);
holder.overflow.setVisibility(showAiredCount > 0 ? View.VISIBLE : View.INVISIBLE);
holder.overflow.removeItems();
setupOverflowItems(holder.overflow, showTypeCount, showAiredCount, episodeTitle != null,
watching);
holder.poster.setImage(showPosterUri);
holder.showTypeCount = showTypeCount;
holder.showAiredCount = showAiredCount;
holder.episodeTitle = episodeTitle;
holder.episodeId = episodeId;
}
protected void onWatchNext(View view, int position, long showId, int watchedCount,
int airedCount) {
showScheduler.watchedNext(showId);
}
protected void setupOverflowItems(OverflowView overflow, int typeCount, int airedCount,
boolean hasNext, boolean watching) {
switch (libraryType) {
case WATCHLIST:
overflow.addItem(R.id.action_watchlist_remove, R.string.action_watchlist_remove);
case WATCHED:
if (airedCount - typeCount > 0) {
if (!watching && hasNext) {
overflow.addItem(R.id.action_checkin, R.string.action_checkin);
overflow.addItem(R.id.action_watched, R.string.action_watched);
} else if (watching) {
overflow.addItem(R.id.action_checkin_cancel, R.string.action_checkin_cancel);
}
}
overflow.addItem(R.id.action_watched_hide, R.string.action_watched_hide);
break;
case COLLECTION:
if (airedCount - typeCount > 0) {
overflow.addItem(R.id.action_collection_add, R.string.action_collect_next);
}
overflow.addItem(R.id.action_collection_hide, R.string.action_collection_hide);
break;
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title) TextView title;
@BindView(R.id.watched) TextView watched;
@BindView(R.id.progress) ProgressBar progressBar;
@BindView(R.id.nextEpisode) TextView nextEpisode;
@BindView(R.id.firstAired) TimeStamp firstAired;
@BindView(R.id.overflow) OverflowView overflow;
@BindView(R.id.poster) RemoteImageView poster;
public int showTypeCount;
public int showAiredCount;
public String episodeTitle;
public long episodeId;
ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
}
}
}