package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.afollestad.materialcab.MaterialCab;
import com.afollestad.materialdialogs.util.DialogUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
import com.kabouzeid.appthemehelper.util.ColorUtil;
import com.kabouzeid.appthemehelper.util.MaterialValueHelper;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.song.AlbumSongAdapter;
import com.kabouzeid.gramophone.dialogs.SleepTimerDialog;
import com.kabouzeid.gramophone.glide.PhonographColoredTarget;
import com.kabouzeid.gramophone.glide.SongGlideRequest;
import com.kabouzeid.gramophone.glide.palette.BitmapPaletteWrapper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.LoaderIds;
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
import com.kabouzeid.gramophone.ui.activities.tageditor.AlbumTagEditorActivity;
import com.kabouzeid.gramophone.util.NavigationUtil;
import com.kabouzeid.gramophone.util.PhonographColorUtil;
import com.kabouzeid.gramophone.util.Util;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Be careful when changing things in this Activity!
*/
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder, LoaderManager.LoaderCallbacks<Album> {
public static final String TAG = AlbumDetailActivity.class.getSimpleName();
private static final int TAG_EDITOR_REQUEST = 2001;
private static final int LOADER_ID = LoaderIds.ALBUM_DETAIL_ACTIVITY;
public static final String EXTRA_ALBUM_ID = "extra_album_id";
private Album album;
@BindView(R.id.list)
ObservableRecyclerView recyclerView;
@BindView(R.id.image)
ImageView albumArtImageView;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.title)
TextView albumTitleView;
@BindView(R.id.list_background)
View songsBackgroundView;
private AlbumSongAdapter adapter;
private MaterialCab cab;
private int headerOffset;
private int titleViewHeight;
private int albumArtViewHeight;
private int toolbarColor;
private float toolbarAlpha;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setDrawUnderStatusbar(true);
ButterKnife.bind(this);
supportPostponeEnterTransition();
setUpObservableListViewParams();
setUpToolBar();
setUpViews();
getSupportLoaderManager().initLoader(LOADER_ID, getIntent().getExtras(), this);
}
@Override
protected View createContentView() {
return wrapSlidingMusicPanel(R.layout.activity_album_detail);
}
private final SimpleObservableScrollViewCallbacks observableScrollViewCallbacks = new SimpleObservableScrollViewCallbacks() {
@Override
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
scrollY += albumArtViewHeight + titleViewHeight;
float flexibleRange = albumArtViewHeight - headerOffset;
// Translate album cover
albumArtImageView.setTranslationY(Math.max(-albumArtViewHeight, -scrollY / 2));
// Translate list background
songsBackgroundView.setTranslationY(Math.max(0, -scrollY + albumArtViewHeight));
// Change alpha of overlay
toolbarAlpha = Math.max(0, Math.min(1, (float) scrollY / flexibleRange));
toolbar.setBackgroundColor(ColorUtil.withAlpha(toolbarColor, toolbarAlpha));
setStatusbarColor(ColorUtil.withAlpha(toolbarColor, cab != null && cab.isActive() ? 1 : toolbarAlpha));
// Translate name text
int maxTitleTranslationY = albumArtViewHeight;
int titleTranslationY = maxTitleTranslationY - scrollY;
titleTranslationY = Math.max(headerOffset, titleTranslationY);
albumTitleView.setTranslationY(titleTranslationY);
}
};
private void setUpObservableListViewParams() {
albumArtViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
toolbarColor = DialogUtils.resolveColor(this, R.attr.defaultFooterColor);
int toolbarHeight = Util.getActionBarSize(this);
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
headerOffset = toolbarHeight;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
headerOffset += getResources().getDimensionPixelSize(R.dimen.status_bar_padding);
}
}
private void setUpViews() {
setUpRecyclerView();
setUpSongsAdapter();
}
private void loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(this), getAlbum().safeGetFirstSong())
.checkIgnoreMediaStore(this)
.generatePalette(this).build()
.dontAnimate()
.listener(new RequestListener<Object, BitmapPaletteWrapper>() {
@Override
public boolean onException(Exception e, Object model, Target<BitmapPaletteWrapper> target, boolean isFirstResource) {
supportStartPostponedEnterTransition();
return false;
}
@Override
public boolean onResourceReady(BitmapPaletteWrapper resource, Object model, Target<BitmapPaletteWrapper> target, boolean isFromMemoryCache, boolean isFirstResource) {
supportStartPostponedEnterTransition();
return false;
}
})
.into(new PhonographColoredTarget(albumArtImageView) {
@Override
public void onColorReady(int color) {
setColors(color);
}
});
}
private void setColors(int color) {
toolbarColor = color;
albumTitleView.setBackgroundColor(color);
albumTitleView.setTextColor(MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(color)));
setNavigationbarColor(color);
setTaskDescriptionColor(color);
}
@Override
public int getPaletteColor() {
return toolbarColor;
}
private void setUpRecyclerView() {
setUpRecyclerViewPadding();
recyclerView.setScrollViewCallbacks(observableScrollViewCallbacks);
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
contentView.post(new Runnable() {
@Override
public void run() {
songsBackgroundView.getLayoutParams().height = contentView.getHeight();
observableScrollViewCallbacks.onScrollChanged(-(albumArtViewHeight + titleViewHeight), false, false);
// necessary to fix a bug
recyclerView.scrollBy(0, 1);
recyclerView.scrollBy(0, -1);
}
});
}
private void setUpRecyclerViewPadding() {
recyclerView.setPadding(0, albumArtViewHeight + titleViewHeight, 0, 0);
}
private void setUpToolBar() {
setSupportActionBar(toolbar);
//noinspection ConstantConditions
getSupportActionBar().setTitle(null);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void setUpSongsAdapter() {
adapter = new AlbumSongAdapter(this, getAlbum().songs, R.layout.item_list, false, this);
recyclerView.setLayoutManager(new GridLayoutManager(this, 1));
recyclerView.setAdapter(adapter);
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
if (adapter.getItemCount() == 0) finish();
}
});
}
private void reload() {
getSupportLoaderManager().restartLoader(LOADER_ID, getIntent().getExtras(), this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_sleep_timer:
new SleepTimerDialog().show(getSupportFragmentManager(), "SET_SLEEP_TIMER");
return true;
case R.id.action_equalizer:
NavigationUtil.openEqualizer(this);
return true;
case R.id.action_shuffle_album:
MusicPlayerRemote.openAndShuffleQueue(adapter.getDataSet(), true);
return true;
case android.R.id.home:
super.onBackPressed();
return true;
case R.id.action_tag_editor:
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, getAlbum().getId());
startActivityForResult(intent, TAG_EDITOR_REQUEST);
return true;
case R.id.action_go_to_artist:
NavigationUtil.goToArtist(this, getAlbum().getArtistId());
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAG_EDITOR_REQUEST) {
reload();
setResult(RESULT_OK);
}
}
@NonNull
@Override
public MaterialCab openCab(int menuRes, @NonNull final MaterialCab.Callback callback) {
if (cab != null && cab.isActive()) cab.finish();
cab = new MaterialCab(this, R.id.cab_stub)
.setMenu(menuRes)
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
.setBackgroundColor(PhonographColorUtil.shiftBackgroundColorForLightText(getPaletteColor()))
.start(new MaterialCab.Callback() {
@Override
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
setStatusbarColor(ColorUtil.stripAlpha(toolbarColor));
return callback.onCabCreated(materialCab, menu);
}
@Override
public boolean onCabItemClicked(MenuItem menuItem) {
return callback.onCabItemClicked(menuItem);
}
@Override
public boolean onCabFinished(MaterialCab materialCab) {
setStatusbarColor(ColorUtil.withAlpha(toolbarColor, toolbarAlpha));
return callback.onCabFinished(materialCab);
}
});
return cab;
}
@Override
public void onBackPressed() {
if (cab != null && cab.isActive()) cab.finish();
else {
recyclerView.stopScroll();
super.onBackPressed();
}
}
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
reload();
}
@Override
public void setStatusbarColor(int color) {
super.setStatusbarColor(color);
setLightStatusbar(false);
}
private void setAlbum(Album album) {
this.album = album;
loadAlbumCover();
albumTitleView.setText(album.getTitle());
adapter.swapDataSet(album.songs);
}
private Album getAlbum() {
if (album == null) album = new Album();
return album;
}
@Override
public Loader<Album> onCreateLoader(int id, Bundle args) {
return new AsyncAlbumLoader(this, args.getInt(EXTRA_ALBUM_ID));
}
@Override
public void onLoadFinished(Loader<Album> loader, Album data) {
supportStartPostponedEnterTransition();
setAlbum(data);
}
@Override
public void onLoaderReset(Loader<Album> loader) {
this.album = new Album();
adapter.swapDataSet(album.songs);
}
private static class AsyncAlbumLoader extends WrappedAsyncTaskLoader<Album> {
private final int albumId;
public AsyncAlbumLoader(Context context, int albumId) {
super(context);
this.albumId = albumId;
}
@Override
public Album loadInBackground() {
return AlbumLoader.getAlbum(getContext(), albumId);
}
}
}