/*
* Copyright (C) 2014 Michell Bak
*
* 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.miz.mizuu.fragments;
import android.animation.Animator;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.melnykov.fab.FloatingActionButton;
import com.miz.apis.tmdb.Movie;
import com.miz.apis.tmdb.TMDbMovieService;
import com.miz.apis.trakt.Trakt;
import com.miz.base.MizActivity;
import com.miz.functions.MizLib;
import com.miz.functions.PaletteLoader;
import com.miz.functions.SimpleAnimatorListener;
import com.miz.functions.TmdbTrailerSearch;
import com.miz.mizuu.MizuuApplication;
import com.miz.mizuu.R;
import com.miz.utils.IntentUtils;
import com.miz.utils.TypefaceUtils;
import com.miz.utils.ViewUtils;
import com.miz.views.HorizontalCardLayout;
import com.miz.views.ObservableScrollView;
import com.miz.views.ObservableScrollView.OnScrollChangedListener;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
public class TmdbMovieDetailsFragment extends Fragment {
private Activity mContext;
private TextView mTitle, mPlot, mGenre, mRuntime, mReleaseDate, mRating, mTagline, mCertification;
private ImageView mBackground, mCover;
private Movie mMovie;
private ObservableScrollView mScrollView;
private View mProgressBar, mDetailsArea;
private boolean mRetained = false;
private Picasso mPicasso;
private Typeface mMediumItalic, mMedium, mBold, mCondensedRegular;
private TMDbMovieService mMovieApiService;
private HorizontalCardLayout mActorsLayout, mSimilarMoviesLayout;
private int mImageThumbSize, mImageThumbSpacing, mToolbarColor = 0;
private Toolbar mToolbar;
private FloatingActionButton mFab;
private PaletteLoader mPaletteLoader;
/**
* Empty constructor as per the Fragment documentation
*/
public TmdbMovieDetailsFragment() {}
public static TmdbMovieDetailsFragment newInstance(String movieId) {
TmdbMovieDetailsFragment pageFragment = new TmdbMovieDetailsFragment();
Bundle bundle = new Bundle();
bundle.putString("movieId", movieId);
pageFragment.setArguments(bundle);
return pageFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
setRetainInstance(true);
mContext = getActivity();
mMediumItalic = TypefaceUtils.getRobotoMediumItalic(mContext);
mMedium = TypefaceUtils.getRobotoMedium(mContext);
mBold = TypefaceUtils.getRobotoBold(mContext);
mCondensedRegular = TypefaceUtils.getRobotoCondensedRegular(mContext);
mMovieApiService = TMDbMovieService.getInstance(mContext);
// Get the database ID of the movie in question
mMovie = new Movie();
mMovie.setId(getArguments().getString("movieId"));
mPicasso = MizuuApplication.getPicasso(getActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.movie_and_tv_show_details, container, false);
mToolbar = (Toolbar) v.findViewById(R.id.toolbar);
mToolbar.setBackgroundResource(android.R.color.transparent);
ViewUtils.setProperToolbarSize(mContext, mToolbar);
((MizActivity) getActivity()).setSupportActionBar(mToolbar);
((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// This needs to be re-initialized here and not in onCreate()
mImageThumbSize = getResources().getDimensionPixelSize(R.dimen.horizontal_grid_item_width);
mImageThumbSpacing = getResources().getDimensionPixelSize(R.dimen.image_thumbnail_spacing);
mProgressBar = v.findViewById(R.id.progress_layout);
mDetailsArea = v.findViewById(R.id.details_area);
mBackground = (ImageView) v.findViewById(R.id.imageBackground);
mTitle = (TextView) v.findViewById(R.id.movieTitle);
mPlot = (TextView) v.findViewById(R.id.textView2);
mGenre = (TextView) v.findViewById(R.id.textView7);
mRuntime = (TextView) v.findViewById(R.id.textView9);
mReleaseDate = (TextView) v.findViewById(R.id.textReleaseDate);
mRating = (TextView) v.findViewById(R.id.textView12);
mTagline = (TextView) v.findViewById(R.id.textView6);
mCertification = (TextView) v.findViewById(R.id.textView11);
mCover = (ImageView) v.findViewById(R.id.traktIcon);
mActorsLayout = (HorizontalCardLayout) v.findViewById(R.id.horizontal_card_layout);
mSimilarMoviesLayout = (HorizontalCardLayout) v.findViewById(R.id.horizontal_card_layout_extra);
mScrollView = (ObservableScrollView) v.findViewById(R.id.observableScrollView);
mFab = (FloatingActionButton) v.findViewById(R.id.fab);
mFab.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ViewUtils.animateFabJump(v, new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
watchTrailer();
}
});
}
});
if (MizLib.isTablet(mContext))
mFab.setType(FloatingActionButton.TYPE_NORMAL);
// Get rid of these...
v.findViewById(R.id.textView3).setVisibility(View.GONE); // File
final int height = MizLib.getActionBarAndStatusBarHeight(mContext);
mScrollView.setOnScrollChangedListener(new OnScrollChangedListener() {
@Override
public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
ViewUtils.handleOnScrollChangedEvent(
getActivity(), v, mBackground, mMovie.getTitle(),
height, t, mToolbar, mToolbarColor);
}
});
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ViewUtils.setLayoutParamsForDetailsEmptyView(mContext, v,
mBackground, mScrollView, this);
}
});
if (!mRetained) { // Nothing has been retained - load the data
setLoading(true);
new MovieLoader().execute();
mRetained = true;
} else {
setupFields();
}
return v;
}
private class MovieLoader extends AsyncTask<String, Object, Object> {
@Override
protected Object doInBackground(String... params) {
mMovie = mMovieApiService.getCompleteMovie(mMovie.getId(), "en");
for (int i = 0; i < mMovie.getSimilarMovies().size(); i++) {
String id = mMovie.getSimilarMovies().get(i).getId();
mMovie.getSimilarMovies().get(i).setInLibrary(MizuuApplication.getMovieAdapter().movieExists(id));
}
return null;
}
@Override
protected void onPostExecute(Object result) {
getActivity().invalidateOptionsMenu();
setupFields();
}
}
private void setupFields() {
if (isAdded() && mMovie != null) {
// Set the movie title
mTitle.setVisibility(View.VISIBLE);
mTitle.setText(mMovie.getTitle());
mTitle.setTypeface(mCondensedRegular);
mPlot.setTypeface(mCondensedRegular);
mReleaseDate.setTypeface(mMedium);
mRuntime.setTypeface(mMedium);
mCertification.setTypeface(mMedium);
mRating.setTypeface(mMedium);
// Set the movie plot
mPlot.setBackgroundResource(R.drawable.selectable_background);
if (!mMovie.getTagline().isEmpty())
mPlot.setMaxLines(getActivity().getResources().getInteger(R.integer.movie_details_max_lines));
else
mPlot.setMaxLines(getActivity().getResources().getInteger(R.integer.show_details_max_lines));
mPlot.setTag(true); // true = collapsed
mPlot.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (((Boolean) mPlot.getTag())) {
// Animate
ViewUtils.animateTextViewMaxLines(mPlot, 50); // It seems highly unlikely that there would every be more than 50 lines
// Reverse the tag
mPlot.setTag(false);
} else {
// Animate
ViewUtils.animateTextViewMaxLines(mPlot, mMovie.getTagline().isEmpty() ?
getResources().getInteger(R.integer.show_details_max_lines) : getResources().getInteger(R.integer.movie_details_max_lines));
// Reverse the tag
mPlot.setTag(true);
}
}
});
mPlot.setEllipsize(TextUtils.TruncateAt.END);
mPlot.setFocusable(true);
if (MizLib.isTablet(getActivity()))
mPlot.setLineSpacing(0, 1.15f);
mPlot.setText(mMovie.getPlot());
// Set movie tag line
mTagline.setTypeface(mBold);
if (mMovie.getTagline().equals("NOTAGLINE") || mMovie.getTagline().isEmpty())
mTagline.setVisibility(TextView.GONE);
else
mTagline.setText(mMovie.getTagline());
// Set the movie genre
mGenre.setTypeface(mMediumItalic);
if (!TextUtils.isEmpty(mMovie.getGenres())) {
mGenre.setText(mMovie.getGenres());
} else {
mGenre.setVisibility(View.GONE);
}
// Set the movie runtime
mRuntime.setText(MizLib.getPrettyRuntime(getActivity(), Integer.parseInt(mMovie.getRuntime())));
// Set the movie release date
mReleaseDate.setTypeface(mMedium);
mReleaseDate.setText(MizLib.getPrettyDate(getActivity(), mMovie.getReleasedate()));
// Set the movie rating
if (!mMovie.getRating().equals("0.0")) {
try {
int rating = (int) (Double.parseDouble(mMovie.getRating()) * 10);
mRating.setText(Html.fromHtml(rating + "<small> %</small>"));
} catch (NumberFormatException e) {
mRating.setText(mMovie.getRating());
}
} else {
mRating.setText(R.string.stringNA);
}
// Set the movie certification
if (!TextUtils.isEmpty(mMovie.getCertification())) {
mCertification.setText(mMovie.getCertification());
} else {
mCertification.setText(R.string.stringNA);
}
mActorsLayout.setTitle(R.string.detailsActors);
mActorsLayout.setSeeMoreVisibility(true);
mActorsLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (mActorsLayout.getWidth() > 0) {
final int numColumns = (int) Math.floor(mActorsLayout.getWidth() / (mImageThumbSize + mImageThumbSpacing));
mImageThumbSize = (mActorsLayout.getWidth() - (numColumns * mImageThumbSpacing)) / numColumns;
mActorsLayout.loadItems(mContext, mPicasso, numColumns, mImageThumbSize, mMovie.getActors(), HorizontalCardLayout.ACTORS, mToolbarColor);
MizLib.removeViewTreeObserver(mActorsLayout.getViewTreeObserver(), this);
}
}
});
mActorsLayout.setSeeMoreOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(IntentUtils.getActorBrowserMovies(mContext, mMovie.getTitle(), mMovie.getId(), mToolbarColor));
}
});
mSimilarMoviesLayout.setVisibility(View.VISIBLE);
mSimilarMoviesLayout.setTitle(R.string.relatedMovies);
mSimilarMoviesLayout.setSeeMoreVisibility(true);
mSimilarMoviesLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (mSimilarMoviesLayout.getWidth() > 0) {
final int numColumns = (int) Math.floor(mSimilarMoviesLayout.getWidth() / (mImageThumbSize + mImageThumbSpacing));
mImageThumbSize = (mSimilarMoviesLayout.getWidth() - (numColumns * mImageThumbSpacing)) / numColumns;
mSimilarMoviesLayout.loadItems(mContext, mPicasso, numColumns, mImageThumbSize, mMovie.getSimilarMovies(), HorizontalCardLayout.RELATED_MOVIES, mToolbarColor);
MizLib.removeViewTreeObserver(mSimilarMoviesLayout.getViewTreeObserver(), this);
}
}
});
mSimilarMoviesLayout.setSeeMoreOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(IntentUtils.getSimilarMovies(mContext, mMovie.getTitle(), mMovie.getId(), mToolbarColor));
}
});
ViewUtils.updateToolbarBackground(getActivity(), mToolbar, 0, mMovie.getTitle(), mToolbarColor);
setLoading(false);
loadImages();
}
}
private void loadImages() {
if (!mMovie.getCover().isEmpty())
mPicasso.load(mMovie.getCover()).placeholder(R.drawable.gray).error(R.drawable.loading_image).into(mCover, new Callback() {
@Override
public void onSuccess() {
if (mPaletteLoader == null) {
mPaletteLoader = new PaletteLoader(mPicasso, Uri.parse(mMovie.getCover()), new PaletteLoader.OnPaletteLoadedCallback() {
@Override
public void onPaletteLoaded(int swatchColor) {
mToolbarColor = swatchColor;
}
});
mPaletteLoader.addView(mDetailsArea);
mPaletteLoader.addView(mActorsLayout.getSeeMoreView());
mPaletteLoader.addView(mSimilarMoviesLayout.getSeeMoreView());
mPaletteLoader.setFab(mFab);
mPaletteLoader.execute();
} else {
// Clear old views after configuration change
mPaletteLoader.clearViews();
// Add views after configuration change
mPaletteLoader.addView(mDetailsArea);
mPaletteLoader.addView(mActorsLayout.getSeeMoreView());
mPaletteLoader.addView(mSimilarMoviesLayout.getSeeMoreView());
mPaletteLoader.setFab(mFab);
// Re-color the views
mPaletteLoader.colorViews();
}
}
@Override
public void onError() {}
});
else
mCover.setImageResource(R.drawable.gray);
if (!mMovie.getBackdrop().isEmpty())
mPicasso.load(mMovie.getBackdrop()).placeholder(R.drawable.gray).error(R.drawable.bg).into(mBackground, new Callback() {
@Override
public void onError() {
if (!isAdded())
return;
if (!mMovie.getCover().isEmpty())
mPicasso.load(mMovie.getCover()).placeholder(R.drawable.bg).error(R.drawable.bg).into(mBackground);
else
mBackground.setImageResource(R.drawable.bg);
}
@Override
public void onSuccess() {
}
});
else {
if (!mMovie.getCover().isEmpty())
mPicasso.load(mMovie.getCover()).placeholder(R.drawable.bg).error(R.drawable.bg).into(mBackground);
else
mBackground.setImageResource(R.drawable.bg);
}
}
private void setLoading(boolean isLoading) {
mProgressBar.setVisibility(isLoading ? View.VISIBLE : View.GONE);
mScrollView.setVisibility(isLoading ? View.GONE : View.VISIBLE);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (mMovie != null) {
inflater.inflate(R.menu.tmdb_details, menu);
if (MizLib.isTablet(mContext)) {
menu.findItem(R.id.share).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.findItem(R.id.checkIn).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
if (!Trakt.hasTraktAccount(mContext))
menu.findItem(R.id.checkIn).setVisible(false);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getActivity().finish();
break;
case R.id.share:
shareMovie();
break;
case R.id.checkIn:
checkIn();
break;
}
return super.onOptionsItemSelected(item);
}
public void shareMovie() {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "http://www.themoviedb.org/movie/" + mMovie.getId());
startActivity(Intent.createChooser(intent, getString(R.string.shareWith)));
}
public void watchTrailer() {
new TmdbTrailerSearch(getActivity(), mMovie.getId()).execute();
}
public void checkIn() {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
return Trakt.performMovieCheckin(mMovie.getId(), mContext);
}
@Override
protected void onPostExecute(Boolean result) {
if (result)
Toast.makeText(mContext, getString(R.string.checked_in), Toast.LENGTH_SHORT).show();
else
Toast.makeText(mContext, getString(R.string.errorSomethingWentWrong), Toast.LENGTH_SHORT).show();
}
}.execute();
}
}