/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Enno Gottschalk <mrmaffen@googlemail.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
package org.tomahawk.tomahawk_android.adapters;
import org.tomahawk.libtomahawk.collection.Image;
import org.tomahawk.libtomahawk.collection.Playlist;
import org.tomahawk.libtomahawk.collection.PlaylistEntry;
import org.tomahawk.libtomahawk.collection.StationPlaylist;
import org.tomahawk.libtomahawk.utils.ImageUtils;
import org.tomahawk.tomahawk_android.R;
import org.tomahawk.tomahawk_android.services.PlaybackService;
import org.tomahawk.tomahawk_android.utils.PlaybackManager;
import android.content.res.Configuration;
import android.os.Parcelable;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
/**
* {@link PagerAdapter} which provides functionality to swipe an AlbumArt image. Used in {@link
* org.tomahawk.tomahawk_android.fragments.PlaybackFragment}
*/
public class AlbumArtSwipeAdapter extends PagerAdapter {
private static final String TAG = AlbumArtSwipeAdapter.class.getSimpleName();
//Used to provide fake infinite swiping behaviour, if current Playlist is repeating
private static final int FAKE_INFINITY_COUNT = 20000;
private int mFakeInfinityOffset;
private final ViewPager mViewPager;
private int mLastItem;
private MediaControllerCompat mMediaController;
private PlaybackManager mPlaybackManager;
private int mSize = 0;
private int mRepeatMode = PlaybackManager.NOT_REPEATING;
private int mPageScrollState = ViewPager.SCROLL_STATE_IDLE;
private boolean mUpdateWhenIdle = false;
private final ViewPager.OnPageChangeListener mOnPageChangeListener
= new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (mMediaController != null) {
if (position == mLastItem - 1) {
Log.d(TAG, "Selected page is now " + position + ", was " + mLastItem
+ ". Skipping to previous track.");
mMediaController.getTransportControls().skipToPrevious();
} else if (position == mLastItem + 1) {
Log.d(TAG, "Selected page is now " + position + ", was " + mLastItem
+ ". Skipping to next track.");
mMediaController.getTransportControls().skipToNext();
}
} else {
Log.e(TAG, "Couldn't skip to next/previous track. mMediaController is null");
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
int lastState = mPageScrollState;
mPageScrollState = state;
if (mUpdateWhenIdle && lastState != ViewPager.SCROLL_STATE_IDLE
&& state == ViewPager.SCROLL_STATE_IDLE) {
mUpdateWhenIdle = false;
updatePlaylist();
}
}
};
/**
* Constructs a new AlbumArtSwipeAdapter.
*
* @param viewPager ViewPager which this adapter has been connected with
*/
public AlbumArtSwipeAdapter(ViewPager viewPager) {
mViewPager = viewPager;
mViewPager.addOnPageChangeListener(mOnPageChangeListener);
}
public void setMediaController(MediaControllerCompat mediaController) {
mMediaController = mediaController;
}
public void setPlaybackManager(PlaybackManager playbackManager) {
mPlaybackManager = playbackManager;
}
/**
* Instantiate an item in the {@link PagerAdapter}. Fill it async with the correct AlbumArt
* image.
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(mViewPager.getContext());
View view = inflater.inflate(R.layout.album_art_view_pager_item, container, false);
if (mPlaybackManager != null) {
Image image = null;
boolean isArtistImage = false;
if (mSize > 0) {
if (mRepeatMode != PlaybackManager.NOT_REPEATING) {
position = position % mSize;
}
PlaylistEntry entry = mPlaybackManager.getPlaybackListEntry(position);
if (entry != null) {
image = entry.getQuery().getImage();
isArtistImage = entry.getQuery().hasArtistImage();
}
} else if (mPlaybackManager.getPlaylist() instanceof StationPlaylist) {
StationPlaylist station = (StationPlaylist) mPlaybackManager.getPlaylist();
if (station.getArtists() != null && station.getArtists().size() > 0) {
image = station.getArtists().get(0).first.getImage();
isArtistImage = true;
}
if (image == null && station.getTracks() != null
&& station.getTracks().size() > 0) {
image = station.getTracks().get(0).first.getImage();
}
}
ImageView imageView = (ImageView) view.findViewById(R.id.album_art_image);
boolean landscapeMode = mViewPager.getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
ImageUtils.loadImageIntoImageView(mViewPager.getContext(), imageView,
image, Image.getLargeImageSize(), landscapeMode, isArtistImage);
}
if (view != null) {
container.addView(view);
}
return view;
}
/**
* @return If current {@link Playlist} is empty or null, return 1. If current {@link Playlist}
* is repeating, return FAKE_INFINITY_COUNT. Else return the current {@link Playlist}'s length.
*/
@Override
public int getCount() {
if (mPlaybackManager == null || mSize == 0) {
return 1;
}
if (mRepeatMode != PlaybackManager.NOT_REPEATING) {
return FAKE_INFINITY_COUNT;
}
return mSize;
}
/**
* Remove the given {@link View} from the {@link ViewPager}
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
/**
* @return true if view is equal to object
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* Dummy method
*
* @return always null
*/
@Override
public Parcelable saveState() {
return null;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
/**
* @param entry to set the current item to
* @param smoothScroll boolean to determine whether or not to show a scrolling animation
*/
private void setCurrentItem(PlaylistEntry entry, boolean smoothScroll) {
int position = mPlaybackManager.getPlaybackListIndex(entry);
if (mRepeatMode != PlaybackManager.NOT_REPEATING) {
position += mFakeInfinityOffset;
}
if (position != mViewPager.getCurrentItem()) {
if (mRepeatMode != PlaybackManager.NOT_REPEATING) {
int currentItem = mViewPager.getCurrentItem();
if (position == (currentItem % mSize) + 1
|| ((currentItem % mSize) == mSize - 1 && position == 0)) {
setCurrentViewPagerItem(mViewPager.getCurrentItem() + 1, smoothScroll);
} else if (position == (currentItem % mSize) - 1
|| ((currentItem % mSize) == 0 && position == mSize - 1)) {
setCurrentViewPagerItem(mViewPager.getCurrentItem() - 1, smoothScroll);
} else {
setCurrentViewPagerItem(position, false);
}
} else {
setCurrentViewPagerItem(position, smoothScroll);
}
}
mLastItem = position;
}
private void setCurrentViewPagerItem(int position, boolean smoothScroll) {
mViewPager.clearOnPageChangeListeners();
mViewPager.setCurrentItem(position, smoothScroll);
mViewPager.addOnPageChangeListener(mOnPageChangeListener);
}
/**
* Update the {@link Playlist} of the {@link AlbumArtSwipeAdapter} with the current one in
* {@link org.tomahawk.tomahawk_android.services.PlaybackService}
*/
public void updatePlaylist() {
if (mPageScrollState != ViewPager.SCROLL_STATE_IDLE) {
mUpdateWhenIdle = true;
return;
}
if (mMediaController != null && mPlaybackManager != null) {
if (mMediaController.getPlaybackState().getExtras() != null) {
mRepeatMode = mMediaController.getPlaybackState().getExtras()
.getInt(PlaybackService.EXTRAS_KEY_REPEAT_MODE);
} else {
mRepeatMode = PlaybackManager.NOT_REPEATING;
}
mSize = mPlaybackManager.getPlaybackListSize();
notifyDataSetChanged();
if (mSize > 0) {
mFakeInfinityOffset = mSize * ((FAKE_INFINITY_COUNT / 2) / mSize);
setCurrentItem(mPlaybackManager.getCurrentEntry(), false);
}
}
}
}