package tv.emby.embyatv.details;
import android.animation.Animator;
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.app.RowsFragment;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.flaviofaria.kenburnsview.KenBurnsView;
import com.flaviofaria.kenburnsview.RandomTransitionGenerator;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
import mediabrowser.model.dto.BaseItemDto;
import tv.emby.embyatv.R;
import tv.emby.embyatv.TvApp;
import tv.emby.embyatv.base.BaseActivity;
import tv.emby.embyatv.base.IKeyListener;
import tv.emby.embyatv.itemhandling.BaseRowItem;
import tv.emby.embyatv.itemhandling.ItemRowAdapter;
import tv.emby.embyatv.playback.MediaManager;
import tv.emby.embyatv.presentation.MyRandomeKBGenerator;
import tv.emby.embyatv.presentation.PositionableListRowPresenter;
import tv.emby.embyatv.util.Utils;
/**
* Created by Eric on 10/22/2015.
*/
public class PhotoPlayerActivity extends BaseActivity {
BaseItemDto currentPhoto;
KenBurnsView[] mainImages = new KenBurnsView[2];
ImageView nextImage;
ImageView prevImage;
int currentImageNdx = 0;
int nextImageNdx = 1;
int displayWidth;
int displayHeight;
boolean isLoadingNext;
boolean isLoadingPrev;
boolean isTransitioning;
boolean isPlaying;
FrameLayout mPopupArea;
RowsFragment mPopupRowsFragment;
ArrayObjectAdapter mPopupRowAdapter;
ListRow mThumbRow;
PositionableListRowPresenter mPopupRowPresenter;
Animation showPopup;
Animation hidePopup;
boolean mPopupPanelVisible;
Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_player);
mainImages[0] = (KenBurnsView) findViewById(R.id.mainImage);
mainImages[1] = (KenBurnsView) findViewById(R.id.mainImage2);
nextImage = new ImageView(this);
nextImage.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
prevImage = new ImageView(this);
prevImage.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
displayWidth = getResources().getDisplayMetrics().widthPixels;
displayHeight = getResources().getDisplayMetrics().heightPixels;
mPopupArea = (FrameLayout) findViewById(R.id.popupArea);
handler = new Handler();
currentImageView().setTransitionGenerator(new MyRandomeKBGenerator(9000, new AccelerateDecelerateInterpolator()));
nextImageView().setTransitionGenerator(new MyRandomeKBGenerator(9000, new AccelerateDecelerateInterpolator()));
currentImageView().pause();
nextImageView().pause();
currentPhoto = MediaManager.getCurrentMediaItem().getBaseItem();
loadImage(currentPhoto, currentImageView(), getIntent().getBooleanExtra("Play", false));
loadImage(currentPhoto, nextImageView());
loadNext();
loadPrev();
// Inject the RowsFragment in the popup container
if (getFragmentManager().findFragmentById(R.id.rows_area) == null) {
mPopupRowsFragment = new RowsFragment();
getFragmentManager().beginTransaction()
.replace(R.id.rows_area, mPopupRowsFragment).commit();
} else {
mPopupRowsFragment = (RowsFragment) getFragmentManager()
.findFragmentById(R.id.rows_area);
}
mPopupRowPresenter = new PositionableListRowPresenter();
mPopupRowAdapter = new ArrayObjectAdapter(mPopupRowPresenter);
mPopupRowsFragment.setAdapter(mPopupRowAdapter);
mThumbRow = new ListRow(new HeaderItem(""), MediaManager.getCurrentMediaAdapter());
mPopupRowAdapter.add(mThumbRow);
mPopupRowsFragment.setOnItemViewClickedListener(itemViewClickedListener);
mPopupRowsFragment.setOnItemViewSelectedListener(itemViewSelectedListener);
setupPopupAnimations();
registerKeyListener(new IKeyListener() {
@Override
public boolean onKeyUp(int key, KeyEvent event) {
switch (key) {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_B:
if (mPopupPanelVisible) {
hideThumbPanel();
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!mPopupPanelVisible && MediaManager.hasNextMediaItem()) {
if (isLoadingNext || isTransitioning)
return true; //swallow too fast requests
if (isPlaying) {
stop();
play();
} else {
next(750);
}
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (!mPopupPanelVisible && MediaManager.hasPrevMediaItem()) {
if (isLoadingPrev || isTransitioning)
return true; //swallow too fast requests
if (isPlaying) stop();
currentPhoto = MediaManager.prevMedia().getBaseItem();
nextImage.setImageDrawable(currentImageView().getDrawable());
nextImageView().setImageDrawable(prevImage.getDrawable());
transition(750);
loadPrev();
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
if (mPopupPanelVisible) hideThumbPanel(); else showThumbPanel();
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
return handlePlayKey();
case KeyEvent.KEYCODE_MEDIA_PLAY:
return handlePlayKey();
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_STOP:
stop();
return true;
default:
return false;
}
return false;
}
});
}
protected boolean handlePlayKey() {
if (mPopupPanelVisible) {
if (isPlaying) stop();
Utils.Beep();
hideThumbPanel();
MediaManager.setCurrentMediaPosition(mPopupRowPresenter.getPosition());
loadImage(MediaManager.getCurrentMediaItem().getBaseItem(), currentImageView());
nextImageView().setAlpha(0f);
currentImageView().resume();
loadNext();
handler.postDelayed(new Runnable() {
@Override
public void run() {
play();
}
}, 8000);
return true;
}
if (isPlaying) stop();
else play();
return true;
}
protected boolean handleSelectKey() {
if (mPopupPanelVisible) {
if (isPlaying) stop();
hideThumbPanel();
MediaManager.setCurrentMediaPosition(mPopupRowPresenter.getPosition());
loadImage(MediaManager.getCurrentMediaItem().getBaseItem(), currentImageView());
nextImageView().setAlpha(0f);
loadNext();
return true;
}
return false;
}
@Override
protected void onPause() {
super.onPause();
if (isPlaying) stop();
}
private void next(int transDuration) {
currentPhoto = MediaManager.nextMedia().getBaseItem();
prevImage.setImageDrawable(currentImageView().getDrawable());
nextImageView().setImageDrawable(nextImage.getDrawable());
transition(transDuration);
loadNext();
}
Runnable playRunnable = new Runnable() {
@Override
public void run() {
if (MediaManager.hasNextMediaItem()) {
next(1800);
handler.postDelayed(this, 8000);
} else {
currentImageView().pause();
mainImages[0].setKeepScreenOn(false);
}
}
};
private void play() {
isPlaying = true;
mainImages[0].setKeepScreenOn(true);
currentImageView().resume();
nextImageView().resume();
next(1800);
handler.postDelayed(playRunnable, 8000);
}
private void stop() {
currentImageView().pause();
nextImageView().pause();
handler.removeCallbacks(playRunnable);
mainImages[0].setKeepScreenOn(false);
isPlaying = false;
}
private KenBurnsView currentImageView() { return mainImages[currentImageNdx]; }
private KenBurnsView nextImageView() { return mainImages[nextImageNdx]; }
private void loadNext() {
if (MediaManager.hasNextMediaItem()) loadImage(MediaManager.peekNextMediaItem().getBaseItem(), nextImage);
}
private void loadPrev() {
if (MediaManager.hasPrevMediaItem()) loadImage(MediaManager.peekPrevMediaItem().getBaseItem(), prevImage);
}
private void transition(int duration) {
//transition between current image and the next one
isTransitioning = true;
currentImageView().animate().alpha(0f).setDuration(duration-50).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
currentImageView().setAlpha(0f);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
nextImageView().animate().alpha(1).setDuration(duration).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
nextImageView().setAlpha(1f);
currentImageNdx = nextImageNdx;
nextImageNdx = currentImageNdx == 0 ? 1 : 0;
//TvApp.getApplication().getLogger().Debug("Current ndx: "+currentImageNdx+" next: "+nextImageNdx);
isTransitioning = false;
}
@Override
public void onAnimationCancel(Animator animation) {
isTransitioning = false;
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
private void loadImage(final BaseItemDto photo, final ImageView target) {
loadImage(photo, target, false);
}
private void loadImage(final BaseItemDto photo, final ImageView target, final boolean play) {
if (photo != null) {
if (target == nextImage) isLoadingNext = true;
if (target == prevImage) isLoadingPrev = true;
Picasso.with(this)
.load(Utils.getPrimaryImageUrl(photo, displayWidth, displayHeight))
.resize(displayWidth, displayHeight)
.centerInside()
.skipMemoryCache()
.error(R.drawable.photo)
.into(target, new Callback() {
@Override
public void onSuccess() {
if (target == nextImage) isLoadingNext = false;
if (target == prevImage) isLoadingPrev = false;
TvApp.getApplication().getLogger().Debug("Loaded item "+photo.getName());
if (play){
currentImageView().resume();
handler.postDelayed(new Runnable() {
@Override
public void run() {
play();
}
}, 5000);
}
}
@Override
public void onError() {
if (target == nextImage) isLoadingNext = false;
if (target == prevImage) isLoadingPrev = false;
TvApp.getApplication().getLogger().Debug("Error loading item "+photo.getName());
}
});
}
}
private OnItemViewClickedListener itemViewClickedListener = new OnItemViewClickedListener() {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {
handleSelectKey();
}
};
private OnItemViewSelectedListener itemViewSelectedListener = new OnItemViewSelectedListener() {
@Override
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {
if (!(item instanceof BaseRowItem) || MediaManager.getCurrentMediaAdapter() == null) return;
MediaManager.getCurrentMediaAdapter().loadMoreItemsIfNeeded(((BaseRowItem)item).getIndex());
}
};
private void setupPopupAnimations() {
showPopup = AnimationUtils.loadAnimation(this, R.anim.abc_slide_in_bottom);
showPopup.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mPopupArea.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animation animation) {
mPopupArea.requestFocus();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
hidePopup = AnimationUtils.loadAnimation(this, R.anim.abc_fade_out);
hidePopup.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mPopupArea.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private void showThumbPanel() {
mPopupArea.bringToFront();
mPopupRowPresenter.setPosition(MediaManager.getCurrentMediaPosition());
mPopupArea.startAnimation(showPopup);
mPopupPanelVisible = true;
}
private void hideThumbPanel(){
mPopupArea.startAnimation(hidePopup);
mPopupPanelVisible = false;
}
}