package de.danoeh.antennapod.menuhandler;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction.Action;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.ShareUtils;
/**
* Handles interactions with the FeedItemMenu.
*/
public class FeedItemMenuHandler {
private static final String TAG = "FeedItemMenuHandler";
private FeedItemMenuHandler() {
}
/**
* Used by the MenuHandler to access different types of menus through one
* interface
*/
public interface MenuInterface {
/**
* Implementations of this method should call findItem(id) on their
* menu-object and call setVisibility(visibility) on the returned
* MenuItem object.
*/
void setItemVisibility(int id, boolean visible);
}
/**
* This method should be called in the prepare-methods of menus. It changes
* the visibility of the menu items depending on a FeedItem's attributes.
*
* @param mi An instance of MenuInterface that the method uses to change a
* MenuItem's visibility
* @param selectedItem The FeedItem for which the menu is supposed to be prepared
* @param showExtendedMenu True if MenuItems that let the user share information about
* the FeedItem and visit its website should be set visible. This
* parameter should be set to false if the menu space is limited.
* @param queueAccess Used for testing if the queue contains the selected item; only used for
* move to top/bottom in the queue
* @return Returns true if selectedItem is not null.
*/
public static boolean onPrepareMenu(MenuInterface mi,
FeedItem selectedItem,
boolean showExtendedMenu,
@Nullable LongList queueAccess) {
if (selectedItem == null) {
return false;
}
boolean hasMedia = selectedItem.getMedia() != null;
boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING;
if (!isPlaying) {
mi.setItemVisibility(R.id.skip_episode_item, false);
}
boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
if(queueAccess == null || queueAccess.size() == 0 || queueAccess.get(0) == selectedItem.getId()) {
mi.setItemVisibility(R.id.move_to_top_item, false);
}
if(queueAccess == null || queueAccess.size() == 0 || queueAccess.get(queueAccess.size()-1) == selectedItem.getId()) {
mi.setItemVisibility(R.id.move_to_bottom_item, false);
}
if (!isInQueue || isPlaying) {
mi.setItemVisibility(R.id.remove_from_queue_item, false);
}
if (!(!isInQueue && selectedItem.getMedia() != null)) {
mi.setItemVisibility(R.id.add_to_queue_item, false);
}
if (!showExtendedMenu || selectedItem.getLink() == null) {
mi.setItemVisibility(R.id.visit_website_item, false);
mi.setItemVisibility(R.id.share_link_item, false);
mi.setItemVisibility(R.id.share_link_with_position_item, false);
}
if (!showExtendedMenu || !hasMedia || selectedItem.getMedia().getDownload_url() == null) {
mi.setItemVisibility(R.id.share_download_url_item, false);
mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
}
if(!hasMedia || selectedItem.getMedia().getPosition() <= 0) {
mi.setItemVisibility(R.id.share_link_with_position_item, false);
mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
}
if (selectedItem.isPlayed()) {
mi.setItemVisibility(R.id.mark_read_item, false);
} else {
mi.setItemVisibility(R.id.mark_unread_item, false);
}
if(selectedItem.getMedia() == null || selectedItem.getMedia().getPosition() == 0) {
mi.setItemVisibility(R.id.reset_position, false);
}
if(!UserPreferences.isEnableAutodownload()) {
mi.setItemVisibility(R.id.activate_auto_download, false);
mi.setItemVisibility(R.id.deactivate_auto_download, false);
} else if(selectedItem.getAutoDownload()) {
mi.setItemVisibility(R.id.activate_auto_download, false);
} else {
mi.setItemVisibility(R.id.deactivate_auto_download, false);
}
if (selectedItem.getPaymentLink() == null || !selectedItem.getFlattrStatus().flattrable()) {
mi.setItemVisibility(R.id.support_item, false);
}
boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
mi.setItemVisibility(R.id.add_to_favorites_item, !isFavorite);
mi.setItemVisibility(R.id.remove_from_favorites_item, isFavorite);
return true;
}
/**
* The same method as onPrepareMenu(MenuInterface, FeedItem, boolean, QueueAccess), but lets the
* caller also specify a list of menu items that should not be shown.
*
* @param excludeIds Menu item that should be excluded
* @return true if selectedItem is not null.
*/
public static boolean onPrepareMenu(MenuInterface mi,
FeedItem selectedItem,
boolean showExtendedMenu,
LongList queueAccess,
int... excludeIds) {
boolean rc = onPrepareMenu(mi, selectedItem, showExtendedMenu, queueAccess);
if (rc && excludeIds != null) {
for (int id : excludeIds) {
mi.setItemVisibility(id, false);
}
}
return rc;
}
public static boolean onMenuItemClicked(Context context, int menuItemId,
FeedItem selectedItem) throws DownloadRequestException {
switch (menuItemId) {
case R.id.skip_episode_item:
context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
break;
case R.id.remove_item:
DBWriter.deleteFeedMediaOfItem(context, selectedItem.getMedia().getId());
break;
case R.id.mark_read_item:
selectedItem.setPlayed(true);
DBWriter.markItemPlayed(selectedItem, FeedItem.PLAYED, false);
if(GpodnetPreferences.loggedIn()) {
FeedMedia media = selectedItem.getMedia();
// not all items have media, Gpodder only cares about those that do
if (media != null) {
GpodnetEpisodeAction actionPlay = new GpodnetEpisodeAction.Builder(selectedItem, Action.PLAY)
.currentDeviceId()
.currentTimestamp()
.started(media.getDuration() / 1000)
.position(media.getDuration() / 1000)
.total(media.getDuration() / 1000)
.build();
GpodnetPreferences.enqueueEpisodeAction(actionPlay);
}
}
break;
case R.id.mark_unread_item:
selectedItem.setPlayed(false);
DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, false);
if(GpodnetPreferences.loggedIn() && selectedItem.getMedia() != null) {
GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW)
.currentDeviceId()
.currentTimestamp()
.build();
GpodnetPreferences.enqueueEpisodeAction(actionNew);
}
break;
case R.id.add_to_queue_item:
DBWriter.addQueueItem(context, selectedItem);
break;
case R.id.remove_from_queue_item:
DBWriter.removeQueueItem(context, selectedItem, true);
break;
case R.id.add_to_favorites_item:
DBWriter.addFavoriteItem(selectedItem);
break;
case R.id.remove_from_favorites_item:
DBWriter.removeFavoriteItem(selectedItem);
break;
case R.id.reset_position:
selectedItem.getMedia().setPosition(0);
DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, true);
break;
case R.id.activate_auto_download:
selectedItem.setAutoDownload(true);
DBWriter.setFeedItemAutoDownload(selectedItem, true);
break;
case R.id.deactivate_auto_download:
selectedItem.setAutoDownload(false);
DBWriter.setFeedItemAutoDownload(selectedItem, false);
break;
case R.id.visit_website_item:
Uri uri = Uri.parse(selectedItem.getLink());
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if(IntentUtils.isCallable(context, intent)) {
context.startActivity(intent);
} else {
Toast.makeText(context, context.getString(R.string.download_error_malformed_url),
Toast.LENGTH_SHORT).show();
}
break;
case R.id.support_item:
DBTasks.flattrItemIfLoggedIn(context, selectedItem);
break;
case R.id.share_link_item:
ShareUtils.shareFeedItemLink(context, selectedItem);
break;
case R.id.share_download_url_item:
ShareUtils.shareFeedItemDownloadLink(context, selectedItem);
break;
case R.id.share_link_with_position_item:
ShareUtils.shareFeedItemLink(context, selectedItem, true);
break;
case R.id.share_download_url_with_position_item:
ShareUtils.shareFeedItemDownloadLink(context, selectedItem, true);
break;
default:
Log.d(TAG, "Unknown menuItemId: " + menuItemId);
return false;
}
// Refresh menu state
return true;
}
}