/*
* Copyright (C) 2014 Fastboot Mobile, LLC.
*
* This program 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.
*
* This program 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 this program;
* if not, see <http://www.gnu.org/licenses>.
*/
package com.fastbootmobile.encore.app.adapters;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Handler;
import android.support.v7.graphics.Palette;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.fastbootmobile.encore.app.R;
import com.fastbootmobile.encore.utils.Utils;
import com.fastbootmobile.encore.app.ui.AlbumArtImageView;
import com.fastbootmobile.encore.app.ui.MaterialTransitionDrawable;
import com.fastbootmobile.encore.model.Album;
import com.fastbootmobile.encore.providers.ProviderAggregator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Adapter for ListView to show a list of albums
*/
public class AlbumsAdapter extends BaseAdapter {
private final List<Album> mAlbums;
private final Handler mHandler;
private final int mDefaultArtColor;
private AlbumArtImageView.OnArtLoadedListener mArtListener = new AlbumArtImageView.OnArtLoadedListener() {
@Override
public void onArtLoaded(final AlbumArtImageView view, final BitmapDrawable drawable) {
Palette.from(drawable.getBitmap()).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(final Palette palette) {
final Palette.Swatch darkVibrantColor = palette.getDarkVibrantSwatch();
final Palette.Swatch darkMutedColor = palette.getDarkMutedSwatch();
mHandler.post(new Runnable() {
public void run() {
int targetColor = mDefaultArtColor;
ViewHolder tag = (ViewHolder) view.getTag();
if (darkVibrantColor != null) {
targetColor = darkVibrantColor.getRgb();
} else if (darkMutedColor != null) {
targetColor = darkMutedColor.getRgb();
}
if (targetColor != mDefaultArtColor) {
Drawable bg = tag.vRoot.getBackground();
TransitionDrawable background;
if (bg instanceof TransitionDrawable) {
background = (TransitionDrawable) tag.vRoot.getBackground();
ColorDrawable drawable1 = (ColorDrawable) background.getDrawable(0);
ColorDrawable drawable2 = (ColorDrawable) background.getDrawable(1);
drawable1.setColor(mDefaultArtColor);
drawable2.setColor(targetColor);
} else {
ColorDrawable drawable1 = new ColorDrawable(mDefaultArtColor);
ColorDrawable drawable2 = new ColorDrawable(targetColor);
background = new TransitionDrawable(new Drawable[]{drawable1, drawable2});
}
Utils.setViewBackground(tag.vRoot, background);
background.startTransition((int) MaterialTransitionDrawable.DEFAULT_DURATION);
tag.itemColor = targetColor;
} else {
tag.vRoot.setBackgroundColor(targetColor);
}
}
});
}
});
}
};
private Comparator<Album> mComparator = new Comparator<Album>() {
@Override
public int compare(Album album, Album album2) {
if (album.getName() != null && album2.getName() != null) {
return album.getName().compareTo(album2.getName());
} else if (album.getName() == null) {
return -1;
} else {
return 1;
}
}
};
/**
* ViewHolder class for Albums
*/
public static class ViewHolder {
public View vRoot;
public AlbumArtImageView ivCover;
public TextView tvTitle;
public Album album;
public int position;
public int itemColor;
public boolean offlineMode;
public ViewHolder(View root) {
vRoot = root;
ivCover = (AlbumArtImageView) root.findViewById(R.id.ivCover);
tvTitle = (TextView) root.findViewById(R.id.tvTitle);
vRoot.setTag(this);
ivCover.setTag(this);
}
}
/**
* Default constructor
*/
public AlbumsAdapter(Resources res) {
mAlbums = new ArrayList<>();
mHandler = new Handler();
mDefaultArtColor = res.getColor(R.color.default_album_art_background);
}
/**
* Sorts the list of albums alphabetically
*/
private void sortListLocked() {
Collections.sort(mAlbums, mComparator);
}
/**
* Adds an album to the adapter
* @param a The album to add
*/
public void addItem(Album a) {
synchronized (mAlbums) {
mAlbums.add(a);
sortListLocked();
}
}
/**
* Adds an album to the adapter if it isn't already existing
* @param a The album to add
* @return True if the item has been added, false otherwise
*/
public boolean addItemUnique(Album a) {
synchronized (mAlbums) {
if (!mAlbums.contains(a)) {
mAlbums.add(a);
sortListLocked();
return true;
} else {
return false;
}
}
}
/**
* Add all the elements of the input collection into the adapter
* @param ps The elements to add
*/
public void addAll(Collection<Album> ps) {
synchronized (mAlbums) {
mAlbums.addAll(ps);
sortListLocked();
}
}
/**
* Add all the elements of the input collection assuming they're not already in the adapter
* @param ps The elements to add
* @return True if at least one iteam has been aded
*/
public boolean addAllUnique(List<Album> ps) {
boolean didChange = false;
synchronized (mAlbums) {
for (Album p : ps) {
if (!mAlbums.contains(p) && p.isLoaded()) {
mAlbums.add(p);
didChange = true;
}
}
if (didChange) {
sortListLocked();
}
}
return didChange;
}
/**
* Returns whether or not the adapter contains the provided album
* @param p The album
* @return true if the adapter contains the provided album
*/
public boolean contains(Album p) {
synchronized (mAlbums) {
return mAlbums.contains(p);
}
}
/**
* {@inheritDoc}
*/
@Override
public int getCount() {
synchronized (mAlbums) {
return mAlbums.size();
}
}
/**
* {@inheritDoc}
*/
@Override
public Album getItem(int position) {
synchronized (mAlbums) {
return mAlbums.get(position);
}
}
/**
* {@inheritDoc}
*/
@Override
public long getItemId(int position) {
synchronized (mAlbums) {
return mAlbums.get(position).getRef().hashCode();
}
}
/**
* {@inheritDoc}
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Context ctx = parent.getContext();
assert ctx != null;
final Resources res = ctx.getResources();
assert res != null;
View root = convertView;
if (convertView == null) {
// Recycle the existing view
LayoutInflater inflater = LayoutInflater.from(ctx);
root = inflater.inflate(R.layout.medium_card_one_line, parent, false);
assert root != null;
root.setTag(new ViewHolder(root));
}
// Fill in the fields
final Album album = getItem(position);
final ViewHolder tag = (ViewHolder) root.getTag();
final boolean offlineMode = ProviderAggregator.getDefault().isOfflineMode();
if (tag.album == null || !tag.album.equals(album) || offlineMode != tag.offlineMode) {
tag.offlineMode = offlineMode;
tag.position = position;
tag.vRoot = root;
tag.album = album;
tag.vRoot.setBackgroundColor(mDefaultArtColor);
tag.itemColor = mDefaultArtColor;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tag.ivCover.setTransitionName("list:albums:cover:" + album.getRef());
tag.tvTitle.setTransitionName("list:albums:title:" + album.getRef());
}
if (album.getName() != null && !album.getName().isEmpty()) {
tag.tvTitle.setText(album.getName());
tag.ivCover.setOnArtLoadedListener(mArtListener);
tag.ivCover.loadArtForAlbum(album);
} else {
tag.tvTitle.setText(res.getString(R.string.loading));
}
}
return root;
}
}