package com.battlelancer.seriesguide.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.PopupMenu;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import com.battlelancer.seriesguide.R;
import com.battlelancer.seriesguide.SgApp;
import com.battlelancer.seriesguide.adapters.MoviesAdapter;
import com.battlelancer.seriesguide.adapters.MoviesDiscoverAdapter;
import com.battlelancer.seriesguide.enums.MoviesDiscoverLink;
import com.battlelancer.seriesguide.loaders.TmdbMoviesLoader;
import com.battlelancer.seriesguide.provider.SeriesGuideContract;
import com.battlelancer.seriesguide.util.AutoGridLayoutManager;
import com.battlelancer.seriesguide.util.MovieTools;
import com.battlelancer.seriesguide.util.Utils;
import com.battlelancer.seriesguide.widgets.EmptyView;
import com.battlelancer.seriesguide.widgets.EmptyViewSwipeRefreshLayout;
/**
* Integrates with a search interface and displays movies based on query results. Can pre-populate
* the displayed movies based on a sent link.
*/
public class MoviesSearchFragment extends Fragment {
public interface OnSearchClickListener {
void onSearchClick();
}
private static final String ARG_SEARCH_QUERY = "search_query";
private static final String ARG_ID_LINK = "linkId";
@BindView(R.id.swipeRefreshLayoutMoviesSearch) EmptyViewSwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.recyclerViewMoviesSearch) RecyclerView recyclerView;
@BindView(R.id.emptyViewMoviesSearch) EmptyView emptyView;
@Nullable private MoviesDiscoverLink link;
private OnSearchClickListener searchClickListener;
private MoviesAdapter adapter;
private Unbinder unbinder;
public static MoviesSearchFragment newInstance(@NonNull MoviesDiscoverLink link) {
MoviesSearchFragment f = new MoviesSearchFragment();
Bundle args = new Bundle();
args.putInt(ARG_ID_LINK, link.id);
f.setArguments(args);
return f;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
searchClickListener = (OnSearchClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnSearchClickListener");
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
link = MoviesDiscoverLink.fromId(getArguments().getInt(ARG_ID_LINK));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_movies_search, container, false);
unbinder = ButterKnife.bind(this, v);
swipeRefreshLayout.setSwipeableChildren(R.id.scrollViewMoviesSearch,
R.id.recyclerViewMoviesSearch);
swipeRefreshLayout.setOnRefreshListener(onRefreshListener);
Utils.setSwipeRefreshLayoutColors(getActivity().getTheme(), swipeRefreshLayout);
// setup grid view
AutoGridLayoutManager layoutManager = new AutoGridLayoutManager(getContext(),
R.dimen.movie_grid_columnWidth, 1, 1);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
// setup empty view button
emptyView.setButtonClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
searchClickListener.onSearchClick();
}
});
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// setup adapter
adapter = new MoviesAdapter(getContext(), new MovieItemClickListener(getActivity()));
recyclerView.setAdapter(adapter);
swipeRefreshLayout.setRefreshing(true);
getLoaderManager().initLoader(MoviesActivity.SEARCH_LOADER_ID, buildLoaderArgs(null),
searchLoaderCallbacks);
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@NonNull
private Bundle buildLoaderArgs(@Nullable String query) {
Bundle args = new Bundle();
args.putInt(ARG_ID_LINK, link == null ? -1 : link.id);
args.putString(ARG_SEARCH_QUERY, query);
return args;
}
public void search(String query) {
if (!swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(true);
}
getLoaderManager().restartLoader(MoviesActivity.SEARCH_LOADER_ID, buildLoaderArgs(query),
searchLoaderCallbacks);
}
private LoaderCallbacks<TmdbMoviesLoader.Result> searchLoaderCallbacks
= new LoaderCallbacks<TmdbMoviesLoader.Result>() {
@Override
public Loader<TmdbMoviesLoader.Result> onCreateLoader(int id, Bundle args) {
MoviesDiscoverLink link = MoviesDiscoverAdapter.DISCOVER_LINK_DEFAULT;
String query = null;
if (args != null) {
link = MoviesDiscoverLink.fromId(args.getInt(ARG_ID_LINK));
query = args.getString(ARG_SEARCH_QUERY);
}
return new TmdbMoviesLoader(SgApp.from(getActivity()), link, query);
}
@Override
public void onLoadFinished(Loader<TmdbMoviesLoader.Result> loader,
TmdbMoviesLoader.Result data) {
if (!isAdded()) {
return;
}
emptyView.setMessage(data.emptyText);
boolean hasNoResults = data.results == null || data.results.size() == 0;
emptyView.setVisibility(hasNoResults ? View.VISIBLE : View.GONE);
recyclerView.setVisibility(hasNoResults ? View.GONE : View.VISIBLE);
adapter.updateMovies(data.results);
swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onLoaderReset(Loader<TmdbMoviesLoader.Result> loader) {
adapter.updateMovies(null);
}
};
private SwipeRefreshLayout.OnRefreshListener onRefreshListener
= new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
searchClickListener.onSearchClick();
}
};
public static class MovieItemClickListener implements MoviesAdapter.ItemClickListener {
private Activity activity;
public MovieItemClickListener(Activity activity) {
this.activity = activity;
}
public Activity getActivity() {
return activity;
}
@Override
public void onClickMovie(int movieTmdbId, ImageView posterView) {
// launch details activity
Intent intent = new Intent(getActivity(), MovieDetailsActivity.class);
intent.putExtra(MovieDetailsFragment.InitBundle.TMDB_ID, movieTmdbId);
// transition poster
Utils.startActivityWithTransition(getActivity(), intent, posterView,
R.string.transitionNameMoviePoster);
}
@Override
public void onClickMovieMoreOptions(final int movieTmdbId, View anchor) {
PopupMenu popupMenu = new PopupMenu(anchor.getContext(), anchor);
popupMenu.inflate(R.menu.movies_popup_menu);
// check if movie is already in watchlist or collection
boolean isInWatchlist = false;
boolean isInCollection = false;
Cursor movie = getActivity().getContentResolver().query(
SeriesGuideContract.Movies.buildMovieUri(movieTmdbId),
new String[] { SeriesGuideContract.Movies.IN_WATCHLIST,
SeriesGuideContract.Movies.IN_COLLECTION }, null, null, null
);
if (movie != null) {
if (movie.moveToFirst()) {
isInWatchlist = movie.getInt(0) == 1;
isInCollection = movie.getInt(1) == 1;
}
movie.close();
}
Menu menu = popupMenu.getMenu();
menu.findItem(R.id.menu_action_movies_watchlist_add).setVisible(!isInWatchlist);
menu.findItem(R.id.menu_action_movies_watchlist_remove).setVisible(isInWatchlist);
menu.findItem(R.id.menu_action_movies_collection_add).setVisible(!isInCollection);
menu.findItem(R.id.menu_action_movies_collection_remove).setVisible(isInCollection);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_action_movies_watchlist_add: {
MovieTools.addToWatchlist(SgApp.from(getActivity()), movieTmdbId);
return true;
}
case R.id.menu_action_movies_watchlist_remove: {
MovieTools.removeFromWatchlist(SgApp.from(getActivity()), movieTmdbId);
return true;
}
case R.id.menu_action_movies_collection_add: {
MovieTools.addToCollection(SgApp.from(getActivity()), movieTmdbId);
return true;
}
case R.id.menu_action_movies_collection_remove: {
MovieTools.removeFromCollection(SgApp.from(getActivity()), movieTmdbId);
return true;
}
}
return false;
}
});
popupMenu.show();
}
}
}